|
|
1.1 ! root 1: #include <assert.h> ! 2: #include <ctype.h> ! 3: #include <stdio.h> ! 4: #include <stdlib.h> ! 5: #include <string.h> ! 6: ! 7: /* ! 8: * bprint [ -c | -Idir... | -f | -b | -n ] [ file... ] ! 9: * annotate listings of files with prof.out data ! 10: * ! 11: */ ! 12: ! 13: char *progname; ! 14: int number; ! 15: char *dirs[20]; ! 16: #define NDIRS (sizeof dirs/sizeof dirs[0] - 1) ! 17: ! 18: char *alloc(int); ! 19: char *string(char *); ! 20: ! 21: int process(char *); ! 22: ! 23: #define BPRINT ! 24: #include "../c/profio.c" ! 25: ! 26: void emitdata(char *); ! 27: void printfile(struct file *, int); ! 28: void printfuncs(struct file *, int); ! 29: ! 30: int fcount; ! 31: ! 32: int main(int argc, char *argv[]) { ! 33: int i; ! 34: struct file *p; ! 35: void (*f)(struct file *, int) = printfile; ! 36: ! 37: progname = argv[0]; ! 38: if ((i = process("prof.out")) <= 0) { ! 39: fprintf(stderr, "%s: can't %s `%s'\n", progname, ! 40: i == 0 ? "open" : "interpret", "prof.out"); ! 41: exit(1); ! 42: } ! 43: for (i = 1; i < argc && *argv[i] == '-'; i++) ! 44: if (strcmp(argv[i], "-c") == 0) { ! 45: emitdata("prof.out"); ! 46: exit(0); ! 47: } else if (strcmp(argv[i], "-b") == 0) ! 48: f = printfile; ! 49: else if (strcmp(argv[i], "-f") == 0) { ! 50: fcount++; ! 51: f = printfuncs; ! 52: } else if (strcmp(argv[i], "-n") == 0) ! 53: number++; ! 54: else if (strncmp(argv[i], "-I", 2) == 0) { ! 55: int j; ! 56: for (j = 0; j < NDIRS && dirs[j]; j++) ! 57: ; ! 58: if (j < NDIRS) ! 59: dirs[j] = &argv[i][2]; ! 60: else ! 61: fprintf(stderr, "%s: too many -I options\n", progname); ! 62: } else { ! 63: fprintf(stderr, "usage: %s [ -c | -b | -n | -f | -Idir... ] [ file... ]\n", progname); ! 64: exit(1); ! 65: } ! 66: for (p = filelist; p; p = p->link) ! 67: qsort(p->counts, p->count, sizeof *p->counts, ! 68: (int (*)(const void *, const void *))compare); ! 69: if (i < argc) { ! 70: int nf = i < argc - 1 ? 1 : 0; ! 71: for ( ; i < argc; i++, nf ? nf++ : 0) ! 72: if (p = findfile(string(argv[i]))) ! 73: (*f)(p, nf); ! 74: else ! 75: fprintf(stderr, "%s: no data for `%s'\n", progname, argv[i]); ! 76: } else { ! 77: int nf = filelist && filelist->link ? 1 : 0; ! 78: for (p = filelist; p; p = p->link, nf ? nf++ : 0) ! 79: (*f)(p, nf); ! 80: } ! 81: return 0; ! 82: } ! 83: ! 84: /* alloc - allocate n bytes or die */ ! 85: char *alloc(int n) { ! 86: char *new = (char *)malloc(n); ! 87: ! 88: assert(new); ! 89: return new; ! 90: } ! 91: ! 92: /* emitdata - write prof.out data to file */ ! 93: void emitdata(char *file) { ! 94: FILE *fp; ! 95: ! 96: if (fp = fopen(file, "w")) { ! 97: struct file *p; ! 98: for (p = filelist; p; p = p->link) { ! 99: int i; ! 100: struct func *q; ! 101: struct caller *r; ! 102: fprintf(fp, "1\n%s\n", p->name); ! 103: for (i = 0, q = p->funcs; q; i++, q = q->link) ! 104: if (r = q->callers) ! 105: for (i--; r; r = r->link) ! 106: i++; ! 107: fprintf(fp, "%d\n", i); ! 108: for (q = p->funcs; q; q = q->link) ! 109: if (q->count.count == 0 || !q->callers) ! 110: fprintf(fp, "%s 1 %d %d %d ? ? 0 0\n", q->name, q->count.x, ! 111: q->count.y, q->count.count); ! 112: else ! 113: for (r = q->callers; r; r = r->link) ! 114: fprintf(fp, "%s 1 %d %d %d %s %s %d %d\n", q->name, q->count.x, ! 115: q->count.y, r->count, r->name, r->file, r->x, r->y); ! 116: fprintf(fp, "%d\n", p->count); ! 117: for (i = 0; i < p->count; i++) ! 118: fprintf(fp, "1 %d %d %d\n", p->counts[i].x, ! 119: p->counts[i].y, p->counts[i].count); ! 120: } ! 121: fclose(fp); ! 122: } else ! 123: fprintf(stderr, "%s: can't create `%s'\n", progname, file); ! 124: } ! 125: ! 126: /* openfile - open name for reading, searching -I directories */ ! 127: FILE *openfile(char *name) { ! 128: int i; ! 129: FILE *fp; ! 130: ! 131: if (*name != '/') ! 132: for (i = 0; dirs[i]; i++) { ! 133: char buf[200]; ! 134: sprintf(buf, "%s/%s", dirs[i], name); ! 135: if (fp = fopen(buf, "r")) ! 136: return fp; ! 137: } ! 138: return fopen(name, "r"); ! 139: } ! 140: ! 141: /* printfile - print annotated listing for p */ ! 142: void printfile(struct file *p, int nf) { ! 143: int lineno; ! 144: FILE *fp; ! 145: char *s, buf[512]; ! 146: struct count *u = p->counts, *r, *uend; ! 147: ! 148: if (u == 0 || p->count <= 0) ! 149: return; ! 150: uend = &p->counts[p->count]; ! 151: if ((fp = openfile(p->name)) == NULL) { ! 152: fprintf(stderr, "%s: can't open `%s'\n", progname, p->name); ! 153: return; ! 154: } ! 155: if (nf) ! 156: printf("%s%s:\n\n", nf == 1 ? "" : "\f", p->name); ! 157: for (lineno = 1; fgets(buf, sizeof buf, fp); lineno++) { ! 158: if (number) ! 159: printf("%d\t", lineno); ! 160: while (u < uend && u->y < lineno) ! 161: u++; ! 162: for (s = buf; *s; ) { ! 163: char *t = s + 1; ! 164: while (u < uend && u->y == lineno && u->x < s - buf) ! 165: u++; ! 166: if (isalnum(*s) || *s == '_') ! 167: while (isalnum(*t) || *t == '_') ! 168: t++; ! 169: while (u < uend && u->y == lineno && u->x < t - buf) { ! 170: printf("<%d>", u->count); ! 171: for (r = u++; u < uend && u->x == r->x && u->y == r->y && u->count == r->count; u++) ! 172: ; ! 173: } ! 174: while (s < t) ! 175: putchar(*s++); ! 176: } ! 177: if (*s) ! 178: printf("%s", s); ! 179: } ! 180: fclose(fp); ! 181: } ! 182: ! 183: /* printfuncs - summarize data for functions in p */ ! 184: void printfuncs(struct file *p, int nf) { ! 185: struct func *q; ! 186: ! 187: if (nf) ! 188: printf("%s:\n", p->name); ! 189: for (q = p->funcs; q; q = q->link) ! 190: if (fcount <= 1 || q->count.count == 0 || !q->callers) ! 191: printf("%d\t%s\n", q->count.count, q->name); ! 192: else { ! 193: struct caller *r; ! 194: for (r = q->callers; r; r = r->link) ! 195: printf("%d\t%s\tfrom %s\tin %s:%d.%d\n", r->count, q->name, r->name, ! 196: r->file, r->y, r->x + 1); ! 197: } ! 198: ! 199: } ! 200: ! 201: /* string - save a copy of str, if necessary */ ! 202: char *string(char *str) { ! 203: static struct string { struct string *link; char str[1]; } *list; ! 204: struct string *p; ! 205: ! 206: for (p = list; p; p = p->link) ! 207: if (strcmp(p->str, str) == 0) ! 208: return p->str; ! 209: p = (struct string *)alloc(strlen(str) + sizeof *p); ! 210: strcpy(p->str, str); ! 211: p->link = list; ! 212: list = p; ! 213: return p->str; ! 214: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.