lenny@icus.ICUS.COM (Lenny Tropiano) (03/02/90)
This shar file was sent to me, the author doesn't have a reliable way of posting this himself, so I'm posting it for him as per his request. I looked at this program briefly and it reminds me of a BSD utility "error" but much more simplistic, making it easy to use. The manual page explains the program and how to use it. Essentially the program ("fake") [I would have called it emake for error/make, but that's *my* opinion] searches out errors from a spawned of /bin/make (changable with environment variables) and using a Regular Expression searching pattern it inserts the compile time errors in a temporary file intermixed at the line of error. You fix the error, and re-run fake. [A suggestion from me is to set this in your .profile ... If you use "vi"] FAKEMASK='^"\(.*\)", line \([0-9]*\):' EDITOPTS='+/,,/' |From: attmail!auxnj!icepit!mark | | "fake" provides C "error-editing" capabilities similar to those found |in other environments, such as MS-DOS Quick C or Turbo C. "fake" works |exactly like make, except that if any errors occur you are immediately |thrown into your favorite editor, with the error message intermixed at |the appropriate place, just below the offending line. You can easily |move from one error to another, always seeing the error message and the |associated source line. Mark Schulman Cincinnati Bell Information Systems attmail!auxnj!icepit!mark #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by typing sh file. To overwrite existing files, type "sh file -c". # If this archive is complete, you will see the following message at the end: # "End of shell archive." # Contents: Makefile README fake.1 fake.c # Wrapped by icepit!mark on Fri Feb 16 15:30:46 EST 1990 echo "extracting files ..." if test -f 'Makefile' -a "${1}" != -c ; then echo "shar: Will not clobber existing file \"Makefile\"" else echo "x - Makefile (38 characters)" sed 's/^X//' >'Makefile' <<'EOF' Xfake: fake.o X $(CC) fake.o -s -o fake EOF if test 38 -ne `wc -c <'Makefile'`; then echo shar: Makefile unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'README' -a "${1}" != -c ; then echo "shar: Will not clobber existing file \"README\"" else echo "x - README (754 characters)" sed 's/^X//' >'README' <<'EOF' X If you've done any development work in MS-DOS, you may be aware of Xthe nifty development environments available in Quick C or Turbo C. XWhen running a compile, if any errors occur you are immediately thrown Xinto the editor, with the error message displayed and the cursor on Xthe offending line. Very nice. You can easily move from one error Xto another, always seeing the error message and the associated source Xline. X "fake" provides similar capabilities. X Now when you run make and get a ton of errors, you don't have to print Xthem out or write them down in order to get into vi and fix them. "fake" Xwill throw you into vi (or EMACS) with source code and error messages Xintermixed. Simply locate each error, fix it, and get out of the editor. EOF if test 754 -ne `wc -c <'README'`; then echo shar: README unpacked with wrong size! fi # end of 'README' fi if test -f 'fake.1' -a "${1}" != -c ; then echo "shar: Will not clobber existing file \"fake.1\"" else echo "x - fake.1 (3287 characters)" sed 's/^X//' >'fake.1' <<'EOF' X.TH FAKE 2.0 1 X.SH "NAME" Xfake - "fix make" - execute a make and edit errors X.SH "SYNOPSIS" X.B fake X[make options] X.SH "RIGHTS & LIMITATIONS" X.B fake Xis distributed "as is". You assume the risk of any and Xall damage or loss from use, or inability to use the software. XThe author does not warrant that the functions of the software will Xmeet your needs or that the software will be error-free or uninterrupted. X.B fake Xhas never been observed to destroy a source file, but I take no Xresponsibility if it does. X.SH "DESCRIPTION" XHow many times does this happen: You run X.BR make , Xget a ton of errors, and either have to print them out or write them down Xso that you can get into vi and fix them. If you've had this problem, X.B fake is your salvation. X.PP X.B fake Xruns X.B make Xand accepts all make options. If errors occur, X.B fake Xcaptures the errors and creates a temporary file which contains Xthe errors interspersed amongst the source code. The user is thrown into Xan editor (default is vi). Each error message Xwill appear just after the line that caused the error. The message is Xprefixed with a comma-comma (",,"), a phrase which is easy to search for Xand yet does not normally occur within a C program. X.PP XA snippet of what you might see in the editor if compilation errors are Xfound: X.PP X.in +.25i X.nf X execvp (argv[0],argv); X perror (p); X,, -> "test.c", line 82: p undefined X exit (1); X.fi X.in -.25i X.PP XBy repeatedly searching for Xcomma-comma, you can visit each error message one by one, and repair Xeach error. (Don't forget to delete the error messages themselves.) XWhen you leave the editor, the temporary file is copied onto the original Xsource file. X.PP XIf no changes are made to the temporary file, it is not copied back Xonto the source file. X.PP XAn easy way (in vi) to get rid of all the error messages once the problems Xhave been corrected is: X.sp X.ti +.5i X:g/,,/d X.PP XFive environment variables (1 mandatory, 4 optional) are used by X.BR fake : X.PP X.IP FAKEMASK 1i X(required). This variable contains a regular expression that tells X.B fake Xhow to identify an error message and how to extract the file name and line Xnumber. The regular expression must contain two pairs of parentheses -- X\e( and \e) -- the first surrounding the file name, the second the error Xline number. For example, if a typical error message looks like this: X.br X.in +.5i X"test.c", line 60: syntax error X.in -.5i X.br Xthen FAKEMASK might be set like this: X.br X.in +.5i X.nf XFAKEMASK='^"\(.*\)", line \([0-9]*\):' Xexport FAKEMASK X.fi X.in -.5i X.IP FAKEMARKER 1i X(optional). Specifies the characters to prepend to the beginning of error Xmessages, to facilitate searching through the source for the errors. XIf undefined, comma-comma is used. X.IP MAKE 1i XThis is the program run underneath X.B fake X-- default is /bin/make. X.IP EDITOR 1i X(optional) is the editor to load if errors are detected. Default is vi. X.IP EDITOPTS 1i X(optional) specifies an option to be fed to the editor when loaded. XIf vi is used, specifying EDITOPTS=+/,, will cause the cursor to be Xpositioned automatically on the first error. X.SH "AUTHOR" X.nf XE-mail: {auxnj,cbis2}!icepit!mark XSnail Mail: Mark Schulman X Cincinnati Bell Information Systems X 851 Trafalgar Ct. Suite 300W X Maitland, FL 32751 X.fi EOF if test 3287 -ne `wc -c <'fake.1'`; then echo shar: fake.1 unpacked with wrong size! fi # end of 'fake.1' fi if test -f 'fake.c' -a "${1}" != -c ; then echo "shar: Will not clobber existing file \"fake.c\"" else echo "x - fake.c (4216 characters)" sed 's/^X//' >'fake.c' <<'EOF' X/* X * FAKE -- a C source development tool by Mark Schulman, Cincinnati X * Bell Information Systems, Maitland, Florida. X */ X X#include <stdio.h> X#include <ctype.h> X#include <signal.h> X#include <sys/types.h> X#include <sys/stat.h> X X#define MAXLINE 32767 X XFILE *mf; /* pipe from make */ XFILE *sf; /* source file (NULL if not yet open) */ XFILE *tf; /* temp file (NULL if not yet open) */ Xint lineno; /* line number of source file */ Xint err_line; /* line number of last error message */ Xchar err_file[51]; /* file name for last error message */ Xchar last_file[51]; /* name of file already open */ Xchar err_text[129]; /* text of last error message */ Xchar temp_file[51]; /* temporary file */ Xchar *marker; /* marker for error messages */ Xchar *errmask; /* regular expression for error */ X Xextern char *getenv (); X X#define INIT register char *sp = errmask; X#define GETC() (*sp++) X#define PEEKC() (*sp) X#define UNGETC(c) (--sp) X#define RETURN(c) return; X#define ERROR(c) regerr () X#include <regexp.h> X Xregerr (n) Xint n; X{ X fprintf (stderr,"regular expression error %d\n",n); X exit (1); X} X Xmain (argc,argv) Xint argc; Xchar *argv[]; X{ X /* get the error mask */ X if ((errmask = getenv ("FAKEMASK")) == NULL) { X fputs ("fake: FAKEMASK must be defined.\n",stderr); X exit (1); X } X X /* set things up */ X init_pipe (argv); X if ((marker = getenv ("FAKEMARKER"))==NULL) marker = ",,"; X X /* read the error messages */ X while (get_error ()) X if (err_line != -1) do_error (); X X /* finish up */ X fclose (mf); X finish (); X wait ((int*) 0); X} X Xinit_pipe (argv) Xchar *argv[]; X{ Xint fd[2]; X X if (pipe (fd)) { X perror ("fake: can't open pipe"); X exit (1); X } X if (!fork ()) { X /* child process (make) */ X close (fd[0]); X close (1); X dup (fd[1]); X close (fd[1]); X close (2); X dup (1); X if ((argv[0] = getenv ("MAKE"))==NULL) X argv[0] = "/bin/make"; X execvp (argv[0],argv); X perror (argv[0]); X exit (1); X } X signal (SIGINT,SIG_IGN); X close (fd[1]); X if ((mf = fdopen (fd[0],"r"))==NULL) { X perror ("fake: fdopen failed"); X exit (1); X } X} X Xget_error () X{ Xchar *p,expr[512]; X X if (!fgets (err_text,sizeof (err_text),mf)) return (0); X fputs (err_text,stdout); X X p = compile (errmask, expr, expr+sizeof (expr), 0); X if (step (err_text, expr) == 0) { X err_line = -1; X return (1); X } X if (nbra != 2) { X fputs ("fake: mask must have 2 pairs of \\( \\) in it.\n", X stderr); X exit (1); X } X X memcpy (err_file, braslist[0], braelist[0] - braslist[0]); X err_file[braelist[0] - braslist[0]] = 0; X err_line = atoi (braslist[1]); X return (1); X} X Xdo_error () X{ X if (strcmp (err_file,last_file)) { X finish (); X sprintf (temp_file,"/tmp/fake.%d",getpid ()); X if ((tf = fopen (temp_file,"w"))==NULL) { X fputs ("can't open tempfile ",stderr); X perror (temp_file); X exit (1); X } X strcpy (last_file,err_file); X if ((sf = fopen (err_file,"r"))==NULL) { X fputs ("can't open source file ",stderr); X perror (err_file); X exit (1); X } X } X while (lineno < err_line) copy_line (); X fprintf (tf,"%s -> %s",marker,err_text); X} X Xcopy_line () X{ Xint c; X X lineno++; X do { X c = fgetc (sf); X if (c == EOF) { X lineno = MAXLINE; X return (0); X } X fputc (c,tf); X } while (c != '\n'); X return (1); X} X Xfinish () X{ Xchar *editor,*opts; Xint pid; Xstruct stat st; Xlong time_stamp; X X if (!*last_file) return; X while (copy_line ()) X ; X fclose (sf); X fclose (tf); X if (stat (temp_file,&st)) { X fputs ("can't stat temp file ",stderr); X perror (temp_file); X exit (1); X } X time_stamp = st.st_mtime; X if (!(pid = fork ())) { X /* child process (vi) */ X signal (SIGINT,SIG_DFL); X if ((editor = getenv ("EDITOR"))==NULL) X editor = "/usr/bin/vi"; X if ((opts = getenv ("EDITOPTS"))==NULL) X execlp (editor,editor,temp_file,NULL); X else execlp (editor,editor,opts,temp_file,NULL); X perror (editor); X exit (1); X } X while (wait (NULL) != pid); X if (stat (temp_file,&st)) return; X if (time_stamp == st.st_mtime) { X if (unlink (temp_file)) { X fputs ("can't unlink ",stderr); X perror (temp_file); X } X return; X } X X if (!fork ()) { X /* child process (mv) */ X execlp ("/bin/mv","/bin/mv",temp_file,err_file,NULL); X perror ("can't move temp file"); X exit (1); X } X} EOF if test 4216 -ne `wc -c <'fake.c'`; then echo shar: fake.c unpacked with wrong size! fi # end of 'fake.c' fi echo End of shell archive. exit 0 [Special side-note ... I am phasing out the US Domain syntax in favor of my new domain ICUS.COM, please update your mail aliases and use the lenny@icus.ICUS.COM or lenny@icus.com from now on, sometime in the not so distant future the icus.islp.ny.us MX record on the Internet will be removed -- if you have trouble getting mail to me using this new syntax, please let me know ASAP] -- | Lenny Tropiano ICUS Software Systems lenny@icus.ICUS.COM | | {ames,pacbell,decuac,sbcs,hombre,rayssd}!icus!lenny attmail!icus!lenny | +------ ICUS Software Systems -- PO Box 1; Islip Terrace, NY 11752 ------+