337 lines
6.0 KiB
C
337 lines
6.0 KiB
C
/* Contributed by Jeff Hostetler. */
|
|
/* Changes by Brian Marick */
|
|
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
|
|
#ifdef USG
|
|
#include <limits.h>
|
|
#else
|
|
#define PATH_MAX 1025
|
|
#endif
|
|
|
|
char filename[PATH_MAX];
|
|
int line_nr;
|
|
|
|
#define BUFSIZE 1024
|
|
char tmp_linebuf[BUFSIZE];
|
|
char tmp_filename[PATH_MAX];
|
|
int tmp_line_nr;
|
|
int tmp_taken1;
|
|
int tmp_taken2;
|
|
|
|
char *get_filename();
|
|
char *get_line_nr();
|
|
void do_this_line();
|
|
void start_file();
|
|
void finish_file();
|
|
void parse_line();
|
|
void emit();
|
|
|
|
FILE *f;
|
|
|
|
|
|
main(argc,argv)
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
if (1 != argc)
|
|
{
|
|
fprintf(stderr, "%s: usage: breport | %s\n", argv[0], argv[0]);
|
|
exit(1);
|
|
}
|
|
|
|
f = (FILE *)NULL;
|
|
filename[0] = NULL;
|
|
line_nr = 0;
|
|
while (fgets(tmp_linebuf,BUFSIZE,stdin) != NULL)
|
|
{
|
|
char *p;
|
|
|
|
/* "<path>", line <nr>: <type-dependent-message> */
|
|
|
|
p = get_filename(tmp_linebuf,tmp_filename);
|
|
p = get_line_nr(p, &tmp_line_nr);
|
|
|
|
if (strcmp(tmp_filename,filename) == 0)
|
|
{
|
|
/* same file */
|
|
do_this_line(p);
|
|
}
|
|
else
|
|
{
|
|
/* changed (or first) file */
|
|
|
|
if (f)
|
|
{
|
|
/* already have a file open */
|
|
finish_file();
|
|
}
|
|
strcpy(filename,tmp_filename);
|
|
start_file();
|
|
do_this_line(p);
|
|
}
|
|
}
|
|
if (f)
|
|
finish_file();
|
|
exit(0);
|
|
}
|
|
|
|
/* do_this_line -- process this line in the file. */
|
|
void do_this_line(p)
|
|
char *p;
|
|
{
|
|
int a,b;
|
|
char *c;
|
|
|
|
char buf[BUFSIZE];
|
|
|
|
parse_line(p, &a, &b, &c);
|
|
|
|
if (line_nr == tmp_line_nr) /* multiple msgs for same src line */
|
|
{
|
|
emit(0,c,a,b,"\n");
|
|
return;
|
|
|
|
}
|
|
while (line_nr < tmp_line_nr-1) /* handle gaps */
|
|
{
|
|
if (fgets(buf,BUFSIZE,f) == NULL)
|
|
{
|
|
fprintf(stderr,"read error on (%s)\n",filename);
|
|
perror("");
|
|
exit(errno);
|
|
}
|
|
line_nr++;
|
|
emit(line_nr," ",0,0,buf);
|
|
}
|
|
|
|
if (fgets(buf,BUFSIZE,f) == NULL)
|
|
{
|
|
fprintf(stderr,"read error on (%s)\n",filename);
|
|
perror("");
|
|
exit(errno);
|
|
}
|
|
line_nr++;
|
|
emit(line_nr,c,a,b,buf);
|
|
|
|
}
|
|
|
|
/* finish_file -- spit out rest of file and close it. */
|
|
void finish_file()
|
|
{
|
|
char buf[BUFSIZE];
|
|
while (fgets(buf,BUFSIZE,f) != NULL)
|
|
{
|
|
line_nr ++;
|
|
emit(line_nr," ",0,0,buf);
|
|
}
|
|
|
|
fclose(f);
|
|
}
|
|
|
|
/* start_file -- open file and emit upto (but not including) current line. */
|
|
void start_file()
|
|
{
|
|
f = fopen(filename,"r");
|
|
if (f == NULL)
|
|
{
|
|
fprintf(stderr,"could not open (%s)\n",filename);
|
|
perror("");
|
|
exit(errno);
|
|
}
|
|
|
|
printf("\f%s\n",filename);
|
|
|
|
line_nr=0;
|
|
while (line_nr < tmp_line_nr-1)
|
|
{
|
|
char buf[BUFSIZE];
|
|
if (fgets(buf,BUFSIZE,f) == NULL)
|
|
{
|
|
fprintf(stderr,"read error on (%s)\n",filename);
|
|
perror("");
|
|
exit(errno);
|
|
}
|
|
line_nr++;
|
|
emit(line_nr," ",0,0,buf);
|
|
}
|
|
}
|
|
|
|
/* emit() -- output line with stuff on it
|
|
* we assume that <line> has a <NL> on the end of it.
|
|
*/
|
|
void emit(line_nr,key,a,b,line)
|
|
int line_nr;
|
|
char *key;
|
|
int a,b;
|
|
char *line;
|
|
{
|
|
if (line_nr)
|
|
printf("%6d:%2s:",line_nr,key);
|
|
else
|
|
printf("%6s:%2s:"," ",key);
|
|
if (*key == ' ')
|
|
printf("%10s:%10s:%s"," "," ",line);
|
|
else if ( (strcmp(key,"DF") == 0)
|
|
|| (strcmp(key,"CA") == 0))
|
|
printf("%10d:%10s:%s",a," ",line);
|
|
else
|
|
printf("%10d:%10d:%s",a,b,line);
|
|
}
|
|
|
|
|
|
/* get_filename() -- extract filename from line (given by p),
|
|
* copy into buffer (given by q),
|
|
* return position past end of name (within p).
|
|
*
|
|
* fmt: ``"<name>"...''
|
|
*/
|
|
|
|
/*
|
|
* BEM: Do some minimal error checking here. All we're trying to do is
|
|
* catch the case where the user feeds in a log file instead of breport
|
|
* output.
|
|
*
|
|
*/
|
|
char * get_filename(p, q)
|
|
char *p, *q;
|
|
{
|
|
if ('"' == *p)
|
|
{
|
|
p++;
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "Input was not generated by breport.\n");
|
|
exit(1);
|
|
}
|
|
|
|
while (*p != '"')
|
|
*q++ = *p++;
|
|
*q = NULL;
|
|
|
|
return(p+1);
|
|
}
|
|
|
|
/* get_line_nr() -- extract line number from line (given by p),
|
|
* store in *l, return position past number.
|
|
*/
|
|
char * get_line_nr(p,l)
|
|
char *p;
|
|
int *l;
|
|
{
|
|
int numchar;
|
|
|
|
if (strncmp(p,", line ",7) == 0)
|
|
p+=7;
|
|
else
|
|
{
|
|
fprintf(stderr,"format problem (line)\n");
|
|
exit(1);
|
|
}
|
|
|
|
if (sscanf(p,"%d %n",l,&numchar) != 1)
|
|
{
|
|
fprintf(stderr,"format problem (sscanf line nr)\n");
|
|
exit(1);
|
|
}
|
|
return(p+numchar);
|
|
}
|
|
|
|
/* parse_line(p,a,b,c) -- extract fields from message portion of line. */
|
|
|
|
void parse_line(p,a,b,c)
|
|
char *p;
|
|
int *a;
|
|
int *b;
|
|
char **c;
|
|
{
|
|
int count_on_line; /* Multiple branches on same line. */
|
|
|
|
if (sscanf(p,": if was taken TRUE %d, FALSE %d times.",a,b) == 2)
|
|
{
|
|
*c = "IF";
|
|
return;
|
|
}
|
|
if (sscanf(p,": if(%d) was taken TRUE %d, FALSE %d times.",&count_on_line,a,b) == 3)
|
|
{
|
|
*c = "IF";
|
|
return;
|
|
}
|
|
if (sscanf(p,": while was taken TRUE %d, FALSE %d times.",a,b) == 2)
|
|
{
|
|
*c = "WH";
|
|
return;
|
|
}
|
|
if (sscanf(p,": while(%d) was taken TRUE %d, FALSE %d times.",&count_on_line,a,b) == 3)
|
|
{
|
|
*c = "WH";
|
|
return;
|
|
}
|
|
if (sscanf(p,": ? was taken TRUE %d, FALSE %d times.",a,b) == 2)
|
|
{
|
|
*c = "QU";
|
|
return;
|
|
}
|
|
if (sscanf(p,": ?(%d) was taken TRUE %d, FALSE %d times.",&count_on_line,a,b) == 3)
|
|
{
|
|
*c = "QU";
|
|
return;
|
|
}
|
|
if (sscanf(p,": for was taken TRUE %d, FALSE %d times.",a,b) == 2)
|
|
{
|
|
*c = "FO";
|
|
return;
|
|
}
|
|
if (sscanf(p,": for(%d) was taken TRUE %d, FALSE %d times.",&count_on_line,a,b) == 3)
|
|
{
|
|
*c = "FO";
|
|
return;
|
|
}
|
|
if (sscanf(p,": do-while was taken TRUE %d, FALSE %d times.",a,b) == 2)
|
|
{
|
|
*c = "DO";
|
|
return;
|
|
}
|
|
if (sscanf(p,": do-while(%d) was taken TRUE %d, FALSE %d times.",&count_on_line,a,b) == 3)
|
|
{
|
|
*c = "DO";
|
|
return;
|
|
}
|
|
if (sscanf(p,": case was taken %d times.",a) == 1)
|
|
{
|
|
*b=0;
|
|
*c = "CA";
|
|
return;
|
|
}
|
|
if (sscanf(p,": case(%d) was taken %d times.",&count_on_line, a) == 2)
|
|
{
|
|
*b=0;
|
|
*c = "CA";
|
|
return;
|
|
}
|
|
if (sscanf(p,": default was taken %d times.",a) == 1)
|
|
{
|
|
*b=0;
|
|
*c = "DF";
|
|
return;
|
|
}
|
|
if (sscanf(p,": default(%d) was taken %d times.",&count_on_line, a) == 2)
|
|
{
|
|
*b=0;
|
|
*c = "DF";
|
|
return;
|
|
}
|
|
if (sscanf(p,": %*s was called %d times.",a) == 1)
|
|
{
|
|
*b=0;
|
|
*c = "FU";
|
|
return;
|
|
}
|
|
fprintf(stderr,"unknown type (%s)",p);
|
|
exit(1);
|
|
}
|
|
|
|
|