joseph@cadvaxoz.eecs.unsw.oz (Joseph Kam) (08/07/86)
This is a very versatile little program which allows the rapid positioning to the error lines specified in the error file one after the other, and if possible, prints the corresponding error message on the terminal's status line. The error file may contain errors output from cc(1), ld(1), lint(1), cyntax(1) and make(1). It should be able to run on both System V and BSD4.2 systems. The program uses terminfo(4) to print out error messages to the status line of a terminal. If you do not have terminfo, then just do not define TERMINFO in the Makefile. In this case, the error message will not be displayed on the status line of your terminal. As the program only do a heuristic parsing of the form of error messages given out from cc, ld, lint, cyntax, and make from our UNSW Unix System (which is a mixture or a mess of Version 7, System 5, and BSD4.2 with significant local hacks), it may not able to recognise error messages in a different format. But you can look into the individual parser and do necessary changes or rewrite to make it work on your system. You are free to change the program, but if you have extended its capabilities like able to recognise error messages from yacc, lex, awk, grep, etc., please send a copy back to me. For sending flame, please direct to /dev/null and hopefully I may get it (you never know) or just do a '/bin/rm *' if that will make you feel happier. Anyway, enjoy it. Ming Chi Kam ISD: +61 2 697-4056 University of NSW, STD: (02) 697-4056 P.O. Box 1, Kensington, ARPA: joseph%cadvax.oz@seismo.arpa Sydney, NSW, 2033, UUCP: seismo!munnari!cadvax.oz!joseph AUSTRALIA. ACSnet: joseph@cadvax.oz ------- CUT HERE ----------- CUT HERE ----------- CUT HERE ---- # Shell Archive created by cadvax! at Thu Aug 7 12:00:29 1986 # To unpack the enclosed files, please use this file as input to the # Bourne (sh) shell. This can be most easily done by the command; # sh < thisfilename # This archive contains; # ve.1 Makefile cctag.c cyntag.c etag.c ldtag.c lintag.c # ---------- file ve.1 ---------- filename="ve.1" if [ -f $filename ] then echo File \"$filename\" already exists\! Skipping... filename=/dev/null # throw it away else echo extracting file ve.1... fi cat << 'END-OF-FILE' > $filename .TH VE 1 .SH NAME ve \- an interactive viewer of programming errors .SH SYNOPSIS .B ve file .SH DESCRIPTION .I Ve accepts only one argument which is the name of the file containing errors output from cc, ld, lint, cyntax and make. With the automatic invocation of the screen editor - vi, .I ve allows the rapid positioning to the error lines specified in the error file one after the other, and if possible, prints the corresponding error message on the terminal's status line. Three commands may be typed when in the vi editor to browse through the error lines. .P .in +10 ^A \(em go to next error line, .br ^Z \(em go back to the last error line, and .br ^C \(em go to the current error line. .in -10 .SH ARTHOR Ming Chi, Kam (joseph@cadvax.unsw.oz) .SH BUGS As users may change the contents of the file, so .I ve does not rely on the line number specified in the error file to position the cursor to the line which may cause the error. Instead, .I ve uses a pattern matching method to try to match the original line pattern before invoking vi, with the same file, after being possibly changed. As a result, there may be a chance, possibly very slight, that the file contains more than one line with the same pattern and incidently, .I ve positions to the wrong one. So users are advised to compare the line number in the error message with the line number of error line positioned by .I ve in cases where the users have some doubts as a result of their big difference or no error can be spotted. In both cases, the command n or N may be typed to see if any other match can be found. END-OF-FILE if [ "$filename" != "/dev/null" ] then size=`wc -c < $filename` if [ $size != 1600 ] then echo $filename changed - should be 1600 bytes, not $size bytes fi chmod 600 $filename fi # ---------- file Makefile ---------- filename="Makefile" if [ -f $filename ] then echo File \"$filename\" already exists\! Skipping... filename=/dev/null # throw it away else echo extracting file Makefile... fi cat << 'END-OF-FILE' > $filename # Define GETLOGIN if you do not have getlogin(3C) call # Define TMPFILE if you do not have tmpfile(3C) call # Define BSD if you use index(3C) call instead of strchr(3C) # Define TERMINFO only if your system supports terminfo(4). CFLAGS= -O LINKFLAGS= -n CC= cc CFILES= cctag.c cyntag.c etag.c ldtag.c lintag.c OBJECTS= cctag.o cyntag.o etag.o ldtag.o lintag.o # Use -lterminfo if you do not have -lcurses LIBS= -lcurses ve: $(OBJECTS) $(CC) $(LINKFLAGS) -o ve $(OBJECTS) $(LIBS) .c.o: $(CC) $(CFLAGS) -c $*.c END-OF-FILE if [ "$filename" != "/dev/null" ] then size=`wc -c < $filename` if [ $size != 462 ] then echo $filename changed - should be 462 bytes, not $size bytes fi chmod 600 $filename fi # ---------- file cctag.c ---------- filename="cctag.c" if [ -f $filename ] then echo File \"$filename\" already exists\! Skipping... filename=/dev/null # throw it away else echo extracting file cctag.c... fi cat << 'END-OF-FILE' > $filename #include <stdio.h> int makecctag(infp, outfp) FILE *infp ; FILE *outfp ; { int find = 0 ; char lbuf[512] ; while (fgets(lbuf, 512, infp) != NULL) { if (*lbuf == '"' ) { fputs(lbuf, outfp) ; find = 1 ; } } return(find) ; } END-OF-FILE if [ "$filename" != "/dev/null" ] then size=`wc -c < $filename` if [ $size != 253 ] then echo $filename changed - should be 253 bytes, not $size bytes fi chmod 600 $filename fi # ---------- file cyntag.c ---------- filename="cyntag.c" if [ -f $filename ] then echo File \"$filename\" already exists\! Skipping... filename=/dev/null # throw it away else echo extracting file cyntag.c... fi cat << 'END-OF-FILE' > $filename #include <stdio.h> static int line ; static FILE *outfp ; static FILE *infp ; static char mesg[254] ; static char filename[100] ; int makecyntag(infilep, outfilep) FILE *infilep ; FILE *outfilep ; { int find = 0 ; char lbuf[512] ; infp = infilep ; outfp = outfilep ; while (fgets(lbuf, 512, infp) != NULL) { switch ( CynMatch1(lbuf) ) { case 1 : find = 1 ; break ; case -1 : return(0) ; case 0 : switch (CynMatch2(lbuf) ) { case 1 : find = 1 ; break ; case -1 : return(0) ; case 0 : switch (CynMatch3(lbuf) ) { case 1 : find = 1 ; break ; case -1 : return(0) ; case 0 : switch (CynMatch4(lbuf) ) { case 1 : find = 1 ; break ; case -1 : return(0) ; } } } } } return(find) ; } int CynMatch1(lbuf) /* * Match ordinary error line with the format * file: line: error */ char *lbuf ; { if ( sscanf(lbuf, "%[^: \t]: %d: %[^\n]", filename, &line, mesg) > 2) { fprintf(outfp, "\"%s\", line %d: %s\n", filename, line, mesg ) ; return(1) ; } return(0) ; } int CynMatch2(lbuf) /* * match line with the format * variable "multiply declared": */ char *lbuf ; { char c ; char varname[100] ; char linebuf[512] ; if ( sscanf(lbuf, "%s multiply declared%c", varname, &c) > 1 && c == ':' ) { if ( (getc(infp) == '\t') && fgets(linebuf, 512, infp) != NULL ) { if ( sscanf(linebuf, "%[^:]: %d %[^\n]", filename, &line, mesg) > 2 && strncmp(mesg, "implicitly as", 13) == 0 ) { if ( getc(infp) != '\t' || fgets(linebuf, 512, infp) == NULL) return(-1) ; } else { if (fscanf(infp, " %[^:]: %d %[^\n]\n", filename, &line, mesg) < 3) return(-1) ; } fprintf( outfp, "\"%s\", line %d: %s %s : %s", filename, line, varname, mesg, linebuf ) ; return(1) ; } else return(-1) ; } else return(0) ; } int CynMatch3(lbuf) /* * match line with the format * variable "multiply defined": */ char *lbuf ; { char word[512] ; char linebuf[512] ; char c ; if ( sscanf(lbuf, "%*s multiply defined%c", &c) > 0 && c == ':' ) { while ((c = getc(infp)) == '\t') { if ( fgets(linebuf, 512, infp) != NULL && sscanf(linebuf, "%[^:]: %d", filename, &line) > 1 ) { fprintf( outfp, "\"%s\", line %d: %s", filename, line, lbuf ) ; } else return(-1) ; } ungetc(c, infp) ; return(1) ; } else return(0) ; } int CynMatch4(lbuf) /* * match line with the format * "function" function: library * or * "function" function: file: line */ char *lbuf ; { char word[512] ; char linebuf[512] ; char c ; if ( sscanf(lbuf, "function %*[^:]: %[^\n]", word) > 0 ) { lbuf[strlen(lbuf) - 1] = '\0' ; while ((c = getc(infp)) == '\t') { if ( fgets(linebuf, 512, infp) != NULL && sscanf(linebuf, "%[^:]: %d, %[^\n]", filename, &line, mesg) > 2 ) { fprintf( outfp, "\"%s\", line %d: %s %s\n", filename, line, lbuf, mesg ) ; } else return(-1) ; } ungetc(c, infp) ; return(1) ; } else return(0) ; } END-OF-FILE if [ "$filename" != "/dev/null" ] then size=`wc -c < $filename` if [ $size != 3424 ] then echo $filename changed - should be 3424 bytes, not $size bytes fi chmod 600 $filename fi # ---------- file etag.c ---------- filename="etag.c" if [ -f $filename ] then echo File \"$filename\" already exists\! Skipping... filename=/dev/null # throw it away else echo extracting file etag.c... fi cat << 'END-OF-FILE' > $filename /* * This is a program to make the debugging of C programs much * easier and faster. It makes use of the capability of vi * and terminfo. * Currently it can work with errors output from cc, lint, * ld, yacc, cyntax and make. * * Written by M.C. KAM */ #define SINGLE #define MAXEXSIZE 62 #define BELL "\007\007\007\007\007\007\007\007\007" #include <stdio.h> #ifdef BSD #define strchr index #define strrchr rindex #endif extern char *strrchr() ; extern int strcmp() ; extern char *getcmdpath() ; extern char *getenv() ; extern FILE *tmpfile() ; extern int makelintag() ; extern int makeldtag() ; extern int makecctag() ; extern int makecyntag() ; static void creattag() ; typedef struct { int (*translator)() ; int checktype ; } ERRDRIVER ; ERRDRIVER driverlist[] = { makecyntag, 1, makecctag, 0, makeldtag, 0, makelintag, 0, NULL } ; static FILE *srcefp ; static FILE *errfp; static FILE *tmpfp ; static FILE *terrfp ; static char tempfile[64] ; static char cursrcefile[128] ; static char curlinebuf[512] ; static char lbuf[512]; static int curlineno ; static int patmatch ; static FILE *fp; static int tabsize = 0 ; static int line = 0 ; static char tagfile[50] ; main(argc, argv, envp) int argc; char **argv; char **envp; { int i ; char **newenvp ; int eline; int initflag = 0 ; char filename[100]; char errmsg[132] ; char tagmsg[512] ; char envstr[300] ; char srhpat[50] ; char *homep ; extern char *getlogin() ; extern char *ttyname() ; extern char *strrchr() ; long addr ; if (isatty(0) == 0) { fputs(BELL, stderr) ; sleep(1) ; fputs(BELL, stderr) ; sleep(1) ; fputs(BELL, stderr) ; exit(1) ; } else homep = strrchr(ttyname(0), '/') + 1 ; line = 0 ; strcpy(tagfile, "/tmp/tags.") ; strcat(tagfile, homep) ; strcat(tagfile, getlogin()); switch (*argv[1]) { case '+' : (void) getheader(&line, &patmatch, &tabsize) ; if ((++line ) > tabsize) { fputs(BELL, stdout) ; fseek(fp, 3 * sizeof(int) + tabsize * sizeof(long), 0) ; fread((char *) &addr, sizeof (long), 1, fp) ; fseek(fp, addr + 55 * sizeof(char), 0) ; fprintf(fp, "/$/%62.s\n", "") ; fclose(fp) ; tprintf("ve : no more error line found"); exit(0) ; } break; case '=' : (void) getheader(&line, &patmatch, &tabsize) ; break; case '-' : initflag = -1 ; (void) getheader(&line, &patmatch, &tabsize) ; if (line > 1) line-- ; else { fputs(BELL, stdout) ; tprintf("ve : no more previous error line"); exit(0) ; } break; default: if (argc < 2) { fprintf(stderr, "usage : %s file\n", argv[0]) ; exit(1) ; } else { if ((errfp = fopen(argv[1], "r")) == NULL) { fprintf(stderr, "%s : can not open error file : %s\n", argv[0], argv[1]) ; exit(2) ; } } if (getc(errfp) != EOF) rewind(errfp) ; else { fputs(BELL, stdout) ; tprintf("ve : no recognisable syntax error "); exit(1) ; } patmatch = (argc <= 2) ; openfile() ; CallTranslator() ; initflag = 1 ; line++ ; fputs(BELL, stderr) ; break; } fseek(fp, (line - 1) * sizeof( long), 1) ; fread((char *) &addr, sizeof (long), 1, fp) ; fseek(fp, addr, 0) ; fgets(lbuf, 512, fp) ; rewind(fp) ; fwrite((char *) &line, sizeof (int), 1, fp) ; fseek(fp, 3 * sizeof(int) + tabsize * sizeof(long), 0) ; fread((char *) &addr, sizeof (long), 1, fp) ; fseek(fp, addr, 0) ; if (*lbuf == '"') { if (sscanf(lbuf, "\"%[^\"]\", line %d: %[^\^\n]%[^\n]", filename, &eline, errmsg, tagmsg) > 3 && ( patmatch == 1 && initflag != 1 ) ) { char *ch ; tprintf("%s, %d: %s", filename, eline, errmsg) ; ch = (initflag == -1 ? "?" : "/") ; fprintf(fp, "err\t%50.50s\t%s%s%-*.1s\n", filename, ch, tagmsg, MAXEXSIZE + 2 - strlen(tagmsg), ch); } else { tprintf("%s, %d: %s", filename, eline, errmsg) ; fprintf(fp, "err\t%50.50s\t%5d%60.s\n", filename, eline, ""); } } else if (*lbuf == '\'') { char *ch ; ch = (initflag == -1 ? "?" : "/") ; sscanf(lbuf, "'%[^']', %s : %[^\n]", filename, srhpat, tagmsg) ; tprintf("%s, %s", filename, tagmsg ) ; fprintf(fp, "err\t%50.50s\t%s%.*s%-*.1s\n", filename, ch, MAXEXSIZE + 1, srhpat, MAXEXSIZE + 2 - strlen(srhpat), ch); } fclose(fp) ; if (initflag == 1 ) { for (i = 0 ; envp[i] != NULL && strncmp(envp[i], "EXINIT", 6) ; i++) ; if (envp[i] != NULL) { sprintf( envstr, "EXINIT=%s | set tags=%s\\ tags | set nu | map ? :!%s +\r:ta err\r | map ? :!%s +\r | map ? :ta err\r | map ? :!%s =\r:ta err\r | map ? :!%s -\r:ta err\r | set nomagic", envp[i]+7, tagfile, argv[0], argv[0], argv[0], argv[0] ); envp[i] = envstr ; fflush(stdout) ; execle(getcmdpath("vi"), "vi", "-t", "err", 0, envp) ; perror("ve") ; exit(2) ; } else { int j ; newenvp = (char **) malloc ((i + 2) * sizeof (char **)) ; for (j = 0 ; j < i ; j++) newenvp[j] = envp[j] ; sprintf( envstr, "EXINIT=set tags=%s\\ tags | set nomagic | map ? :!%s +\r:ta err\r | map ? :!%s =\r:ta err\r | map ? :!%s -\r:ta err\r | set nu", tagfile, argv[0], argv[0], argv[0] ); newenvp[i+1] = NULL ; newenvp[i] = envstr ; fflush(stdout) ; execle(getcmdpath("vi"), "vi", "-t", "err", 0, newenvp) ; perror("ve") ; exit(2) ; } } } CallTranslator() { register ERRDRIVER *errdp ; for ( errdp = driverlist ; errdp->translator != NULL ; errdp++ ) { if ((* errdp->translator)( errfp, terrfp) == 1 && errdp->checktype == 0) break ; else rewind(errfp) ; } fclose(errfp) ; rewind(terrfp) ; preprocess() ; } preprocess() { *cursrcefile = '\0' ; tabsize = 0 ; while (fgets(lbuf, 512, terrfp) != NULL) { switch (*lbuf ) { case '\'' : fputs(lbuf, tmpfp) ; tabsize++ ; break ; case '"' : lbuf[strlen(lbuf) - 1] = '\0' ; extract(lbuf) ; tabsize++ ; break ; } } if (tabsize != 0) creattag(tmpfp) ; else { fputs(BELL, stdout) ; tprintf("ve : no recognisable syntax error "); exit(1) ; } } extract(linebuf) char *linebuf ; { char filename[64] ; int eline ; if (sscanf(linebuf, "\"%[^\"]\", line %d:", filename, &eline) <= 1) return ; if (! strcmp(cursrcefile, filename)) { if (curlineno > eline) { rewind(srcefp) ; curlineno = 0 ; } processsrce(linebuf, eline) ; } else { if (srcefp != NULL) fclose(srcefp) ; if ((srcefp = fopen(filename, "r")) == NULL) fprintf(tmpfp, "%s\n", linebuf) ; else { curlineno = 0 ; strcpy(cursrcefile, filename) ; processsrce(linebuf, eline) ; } } } processsrce(linebuf, eline) int eline ; char linebuf[]; { if (curlineno < eline) { do { if (fgets(curlinebuf, 512, srcefp) == NULL) break ; else curlineno ++ ; } while (curlineno < eline) ; if (curlineno < eline) { fprintf(tmpfp, "%s\n", linebuf) ; return ; } else { int LineLen ; register char *cp ; cp = curlinebuf ; /* * put extra '\' to quote the magic char */ while (*cp != '\0') { if (*cp == '\\' || *cp == '/') { mvstr(cp) ; *cp++ = '\\' ; } cp++ ; } if ((LineLen = strlen(curlinebuf)) <= MAXEXSIZE) curlinebuf[LineLen - 1] = '$' ; else curlinebuf[MAXEXSIZE] = '\0' ; } } fprintf(tmpfp, "%s^%s\n", linebuf, curlinebuf) ; } mvstr(tcp) char tcp[] ; { register int slen ; for (slen = strlen(tcp) + 1 ; slen > 0 ; slen--) { tcp[slen ] = tcp[slen - 1] ; } } #ifdef TERMINFO #include <curses.h> #include <term.h> #endif tprintf(format, p1, p2, p3, p4) char *format ; { char buf[512] ; #ifdef TERMINFO setupterm(0, 1, 0) ; if (has_status_line == 0) { /* * put it out to the status line */ putp(to_status_line) ; fprintf(stdout, format, p1, p2, p3, p4) ; putp(from_status_line) ; } else #endif { fprintf(stdout, format, p1, p2, p3, p4) ; fputc('\n', stdout) ; } #ifdef TERMINFO resetterm() ; #endif } openfile() { if ((tmpfp = tmpfile()) == NULL || (terrfp = tmpfile()) == NULL) { fprintf(stderr, "ve : can not open temporary file for writing\n") ; exit(2) ; } } static void creattag(tempfp) FILE *tempfp ; { long address ; long startadd ; register int c ; extern long ftell() ; rewind(tempfp) ; if ((fp = fopen(tagfile, "w+")) == NULL) { perror("ve") ; exit(1) ; } /* setbuf(fp, NULL) ; /**/ startadd = 3 * sizeof (int) + (tabsize + 1) * sizeof( long) ; fwrite((char *) &line, sizeof(int), 1, fp) ; fwrite((char *) &patmatch, sizeof(int), 1, fp) ; fwrite((char *) &tabsize, sizeof(int), 1, fp) ; fwrite((char *) &startadd, sizeof(long), 1, fp) ; while ((c = getc(tempfp)) != EOF) { if (c == '\n') { address = ftell(tempfp) + startadd ; fwrite((char *) &address, sizeof(long), 1, fp) ; } } rewind(tempfp) ; while (( c = getc(tempfp)) != EOF) putc(c, fp) ; fseek(fp, 3 * sizeof(int), 0) ; } getheader(errno, type, size) int *errno ; int *type ; int *size ; { if ((fp = fopen(tagfile, "r+")) == NULL) { perror("ve") ; exit(1) ; } else { /* setbuf(fp, NULL) ; /**/ fread((char *)errno, sizeof(int), 1, fp) ; fread((char *)type, sizeof(int), 1, fp) ; fread((char *)size, sizeof(int), 1, fp) ; } } #ifdef GETLOGIN #include <pwd.h> char * getlogin() { extern struct passwd *getpwuid(); struct passwd *pwd; if ((pwd = getpwuid(getuid())) == (struct passwd *) NULL) return NULL; else return(pwd->pw_name); } #endif GETLOGIN #ifdef TMPFILE FILE * tmpfile() { char filename[15] ; FILE *fp; strcpy(filename, "/tmp/tagXXXXXX") ; if ((fp = fopen(mktemp(filename), "w+")) != NULL) { unlink(filename); return(fp); } return(NULL); } #endif TMPFILE /* * * getcmdpath.c returns the full path name of the argument cmd * by looking through the environment variable PATH. * * */ char * getcmdpath(cmd) char *cmd; { extern char *getenv(); extern char *strchr(); char *path, *cp; static char buf[200]; char patbuf[512]; if (cmd == NULL || *cmd == '/') return(cmd) ; strcpy(patbuf, getenv("PATH")); path = patbuf; cp = path; while(1) { if (path == NULL || *path == '\0') return(NULL) ; if (*path == ':') strcpy(buf, cmd); else { cp = strchr(path, ':'); if (cp != NULL) *cp = '\0'; sprintf(buf, "%s/%s", path, cmd); } path = ++cp; if (access(buf, 1) == 0) { return(buf) ; } } } END-OF-FILE if [ "$filename" != "/dev/null" ] then size=`wc -c < $filename` if [ $size != 10732 ] then echo $filename changed - should be 10732 bytes, not $size bytes fi chmod 600 $filename fi # ---------- file ldtag.c ---------- filename="ldtag.c" if [ -f $filename ] then echo File \"$filename\" already exists\! Skipping... filename=/dev/null # throw it away else echo extracting file ldtag.c... fi cat << 'END-OF-FILE' > $filename #include <stdio.h> int makeldtag(infp, outfp) FILE *infp ; FILE *outfp ; { int find = 0 ; char lbuf[512] ; char varname[100] ; char filename[100] ; char filename2[100] ; while (fgets(lbuf, 512, infp) != NULL) { if ( *lbuf == '_' && sscanf(lbuf+1, "%s %s", varname, filename) > 1 ) { filename[strlen(filename) - 1 ] = 'c' ; fprintf(outfp, "'%s', %s : undefined symbol %s\n", filename, varname, varname ) ; find = 1 ; } else if ( sscanf( lbuf, "ld : Symbol _%s in %s is multiply defined. First defined in %s", varname, filename, filename2 ) > 2 ) { filename[strlen(filename) - 1 ] = 'c' ; filename2[strlen(filename2) - 1 ] = 'c' ; fprintf( outfp, "'%s', %s : multiply defined symbol %s. First defined in %s\n", filename, varname, varname, filename2 ) ; find = 1 ; } } return(find) ; } END-OF-FILE if [ "$filename" != "/dev/null" ] then size=`wc -c < $filename` if [ $size != 944 ] then echo $filename changed - should be 944 bytes, not $size bytes fi chmod 600 $filename fi # ---------- file lintag.c ---------- filename="lintag.c" if [ -f $filename ] then echo File \"$filename\" already exists\! Skipping... filename=/dev/null # throw it away else echo extracting file lintag.c... fi cat << 'END-OF-FILE' > $filename #include <stdio.h> char lbuf[512] ; char rbuf[512] ; char mbuf[512] ; char *varname[100] ; char filename[100] ; int linenum1 ; int linenum2 ; int linenum3 ; int lineref = 0 ; int j ; FILE *infp ; extern char *strchr() ; extern char *strrchr() ; char *getline(linebuf) char *linebuf ; { if (fgets(linebuf, 512, infp) != NULL) { lineref++ ; /* fprintf(stderr, "line %d : %s\n", lineref, linebuf) ; */ linebuf[strlen(linebuf) - 1] = '\0' ; return(linebuf) ; } else return(NULL) ; } int makelintag(infilep, outfp) FILE *infilep ; FILE *outfp ; { int lintfilepresent = 0 ; while (fgets(lbuf, 512, infilep) != NULL) { if (*lbuf == '=' ) { if ( ! strncmp(lbuf + 1, "=============", 13)) { lintfilepresent = 1 ; rewind(infilep) ; break ; } } } if (lintfilepresent == 0) { /* fprintf(stderr, "Lint file not present\n") ; /**/ return(0) ; } else infp = infilep ; /* fprintf(stderr, "Lint file present\n") ; /**/ while (getline(lbuf) != NULL) { if (*lbuf == '\0') continue ; if (*lbuf == '=') { if (getline(lbuf) == NULL) goto end ; while (*lbuf != ' ') { strcpy(rbuf, lbuf) ; if (getline(lbuf) == NULL) goto end ; if (match3(lbuf, mbuf, varname, filename, &linenum1)) { do { strcat(mbuf, " - "); strcat(mbuf, varname) ; fprintf(outfp, "\"%s\", line %d: %s: %s\n", filename, linenum1, rbuf, mbuf) ; if (getline(lbuf) == NULL) goto end ; } while (match3(lbuf, mbuf, varname, filename, &linenum1) ) ; } else if (match4( lbuf, mbuf, filename, &linenum1)) { do { fprintf(outfp, "\"%s\", line %d: %s: %s\n", filename, linenum1, rbuf, mbuf) ; if (getline(lbuf) == NULL) goto end ; } while (match4( lbuf, mbuf, filename, &linenum1)) ; } } goto end ; } loop1: strcpy(rbuf, lbuf) ; if (getline(lbuf) == NULL) goto end ; switch (*lbuf) { case '=' : sscanf(rbuf, "%s", filename) ; /* fprintf(stderr, "File %s found\n", filename) ; /**/ break ; case '\0' : continue ; default : goto loop1 ; } if (getline(lbuf) == NULL) goto end ; if (! match1(lbuf,& linenum1, mbuf)) { loop2 : strcpy(rbuf, lbuf) ; if (getline(lbuf) == NULL) goto end ; if (*lbuf == '\0') continue ; if ((j = match5(lbuf, &linenum1, &linenum2, &linenum3)) > 1) { do { fprintf(outfp, "\"%s\", line %d: %s %s\n", filename, linenum1, rbuf, mbuf) ; fprintf(outfp, "\"%s\", line %d: %s %s\n", filename, linenum2, rbuf, mbuf) ; if (j > 2) fprintf(outfp, "\"%s\", line %d: %s %s\n", filename, linenum3, rbuf, mbuf) ; if (getline(lbuf) == NULL) goto end ; } while ((j = match5(lbuf, &linenum1, &linenum2, &linenum3)) > 1 ) ; } else if (match2(lbuf, &linenum1, mbuf) ) { do { fprintf(outfp, "\"%s\", line %d: %s %s\n", filename, linenum1, rbuf, mbuf) ; if (getline(lbuf) == NULL) goto end ; } while (match2(lbuf, &linenum1, mbuf) ) ; } goto loop2 ; } else do { fprintf(outfp, "\"%s\", line %d: %s\n", filename, linenum1, mbuf) ; if (getline(lbuf) == NULL) goto end ; } while (match1( lbuf, &linenum1, mbuf) ) ; goto loop2 ; } end : return(1) ; } int match1(linebuf, linenum, msg) /* * match line with the format * (line) message */ char *linebuf ; int *linenum ; char *msg ; { return(sscanf(linebuf, "(%d) %[^$]", linenum, msg) > 1) ; } int match2(linebuf, linenum, msg) /* * match line with the format * 4 spaces (line) message */ char *linebuf ; int *linenum ; char *msg ; { int i ; for (i = 0 ; linebuf[i] != '\0' && linebuf[i] == ' ' ; i++); if (i != 4) return(0) ; else { *msg = '\0' ; return(sscanf(linebuf, " (%d) %[^$]", linenum, msg) > 0) ; } } int match3(linebuf, msg, vname, fname, linenum) /* * match line with the format * message file1(line1) :: file2(line2) */ char *linebuf ; char *msg ; char *fname ; char *vname ; int *linenum ; { int i ; for (i = 0 ; linebuf[i] != '\0' && linebuf[i] == ' ' ; i++); if (i != 4) return(0) ; if (sscanf(linebuf, " %[^\t]\t%s :: %[^\(](%d)", msg, vname, fname, linenum) > 3) { if (fname[strlen(fname) - 2] != '.') { char filenamebuf[100] ; int line ; sscanf(vname, "%[^\(](%d)", filenamebuf, &line) ; sprintf(vname, "%s(%d)", fname, *linenum) ; strcpy(fname, filenamebuf) ; *linenum = line ; } return(1) ; } else return(0) ; } int match4(linebuf, msg, fname, linenum) /* * match line with the format: * message file(line) */ char *linebuf ; char *msg ; char *fname ; int *linenum ; { int i ; for (i = 0 ; linebuf[i] != '\0' && linebuf[i] == ' ' ; i++); if (i != 4) return(0) ; if (sscanf(linebuf, " %s %[^\(](%d)", msg, fname, linenum) > 2) { i = strlen(fname) - 1 ; if (fname[i] == '?') fname[i] = '\0' ; return(1) ; } else return(0) ; } int match5(linebuf, lnum1, lnum2, lnum3) /* * match line which contains only numbers */ char *linebuf ; int *lnum1 ; int *lnum2 ; int *lnum3 ; { int i ; for (i = 0 ; linebuf[i] != '\0' && linebuf[i] == ' ' ; i++); if (i != 4) return(0) ; return( sscanf(linebuf, " (%d)\t(%d)\t(%d)", lnum1, lnum2, lnum3)) ; } END-OF-FILE if [ "$filename" != "/dev/null" ] then size=`wc -c < $filename` if [ $size != 5575 ] then echo $filename changed - should be 5575 bytes, not $size bytes fi chmod 600 $filename fi echo done exit 0