/* LOGSCANU.C Scans log of a STATA ado-file run, searches for any errors that STATA found, and displays the surrounding program lines if error was encountered. To be called from FINDBUG.ADO using STATA. Timothy J. Schmidt November 7, 1994 STB23: ip7 */ #include #define LNLENGTH 81 #define SEEK_END 2 typedef char BUFFER[LNLENGTH] ; int main() { int flag = 0, counter = 0, strindex, cmdindex ; long marker, endofile ; char *cmd = " ", *blankstr = "", *WHILE = "while", *FOR = "for", *IF = "if", *LOCAL = "local", *noiadv = "noi", *quiadv = "qui", *byprefix = "by" ; char ch, line[LNLENGTH], *noerror = "* qQ\n", *errormsg = "No error" ; BUFFER buff1, buff2, buff3, buff4, buff5, buff6, buff7, buff8, buff9, buff10, buff11 ; FILE *infile, *outfile ; infile = fopen("_findbug.log", "r") ; if (infile == NULL) { fputs("Could not open file: _findbug.log\n", stdout) ; exit(1) ; } if (fseek(infile, 0L, SEEK_END) != 0) { fputs("fseek error -- could not find end of file\n", stdout) ; exit(2) ; } endofile = ftell(infile) ; for (marker = 5L ; marker <= endofile ; marker++) { if (fseek(infile, -marker, SEEK_END) != 0) { fputs("fseek error\n", stdout) ; exit(2) ; } if ((ch = fgetc(infile)) == EOF) { fputs("End of file has been reached\n", stdout) ; exit(3) ; } if (ch == '\n') { if (fgets(line, LNLENGTH, infile) == NULL) { fputs("Error reading string from file\n", stdout) ; exit(4) ; } if (!(strcmp(line, noerror))) { fputs("\n\n\n\nNo errors were found\n\n", stdout) ; break ; } if (line[0] != '-' && line[0] != ' ' && line[0] != '*' && line[0] != '>' && !(line[0] == 'r' && line[1] == '(') && flag == 0) { strncpy(errormsg, line, LNLENGTH) ; flag = 1 ; } else if (flag != 1) { strncpy(buff1, buff2, LNLENGTH) ; strncpy(buff2, buff3, LNLENGTH) ; strncpy(buff3, buff4, LNLENGTH) ; strncpy(buff4, buff5, LNLENGTH) ; strncpy(buff5, buff6, LNLENGTH) ; strncpy(buff6, buff7, LNLENGTH) ; strncpy(buff7, buff8, LNLENGTH) ; strncpy(buff8, buff9, LNLENGTH) ; strncpy(buff9, buff10, LNLENGTH) ; strncpy(buff10, buff11, LNLENGTH) ; strncpy(buff11, line, LNLENGTH) ; } if (flag == 1) flag++ ; if (flag == 2) counter++ ; if (counter > 8) break ; } } if (flag != 0) { outfile = fopen("junk.do", "w") ; for (; marker <= endofile ; marker++) { fseek(infile, -marker, SEEK_END) ; ch = getc(infile) ; if (ch == '\n') { fgets(line, LNLENGTH, infile) ; if (line[0] == '-' && line[2] != '}') { strindex = 2 ; cmdindex = 0 ; while (line[strindex] != ' ' && line[strindex] != '\n' && line[strindex] != '\t') { cmd[cmdindex] = line[strindex] ; if (strindex == 3) { if (!(strcmp(cmd, byprefix)) && line[4] == ' ') { while (line[++strindex] != ':') { } strncpy(cmd, blankstr, 9) ; cmdindex = -1 ; strindex++ ; } } if (strindex == 4) { if (!(strcmp(cmd, noiadv)) || !(strcmp(cmd, quiadv))) { while (line[++strindex] != ' ') { } strncpy(cmd, blankstr, 9) ; cmdindex = -1 ; } } cmdindex++ ; strindex++ ; } if (strcmp(cmd, WHILE) && strcmp(cmd, FOR) && strcmp(cmd, IF) && strcmp(cmd, LOCAL)) { fprintf(outfile, "cap which %s\n", cmd) ; fprintf(outfile, "if (!_rc) { mac def S_adoseq = \"$S_adoseq %s\" }\n",cmd); } strncpy(cmd, blankstr, 9) ; } } } if (fclose(outfile) == EOF) { fputs("Cannot close file: junk.do\n", stdout) ; exit(5) ; } fputs(buff11, stdout) ; fputs(buff10, stdout) ; fputs(buff9, stdout) ; fputs(buff8, stdout) ; fputs(buff7, stdout) ; fputs(buff6, stdout) ; fputs(buff5, stdout) ; fputs(buff4, stdout) ; fputs(errormsg, stdout) ; fputs(buff3, stdout) ; fputs(buff2, stdout) ; fputs(buff1, stdout) ; fputs("\n", stdout) ; } if (fclose(infile) == EOF) { fputs("Cannot close file: _findbug.log\n", stdout) ; exit(5) ; } return 0 ; }