home *** CD-ROM | disk | FTP | other *** search
/ Total Destruction / Total_Destruction.iso / addons / Lccwin32.exe / Lccwin32 / lccpub / src / profio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-11  |  7.6 KB  |  310 lines

  1. /* C compiler: prof.out input
  2.  
  3.  
  4. prof.out format:
  5. #files
  6.     name
  7.     ... (#files-1 times)
  8. #functions
  9.     name file# x y count caller file x y 
  10.     ... (#functions-1 times)
  11. #points
  12.     file# x y count
  13.     ... (#points-1 times)
  14. */
  15. struct count {            /* count data: */
  16.     int x, y;            /* source coordinate */
  17.     int count;            /* associated execution count */
  18. };
  19.  
  20. #define MAXTOKEN 64
  21. #ifdef BPRINT
  22. #define ARGS(list) list
  23. #define ngetc() getc(fp)
  24. static FILE *fp;
  25. #else
  26. #include "c.h"
  27. #ifndef EOF
  28. #define EOF -1
  29. #endif
  30. #define ngetc() (*cp == 0 ? EOF : *cp == '\n' ? (cp++, nextline(), '\n') : *cp++)
  31. extern void qsort ARGS((struct count *, int, int, int (*)(const void *, const void *)));
  32. #endif
  33.  
  34. struct file {            /* per-file prof.out data: */
  35.     struct file *link;        /* link to next file */
  36.     char *name;            /* file name */
  37.     int size;            /* size of counts[] */
  38.     int count;            /* counts[0..count-1] hold valid data */
  39.     struct count *counts;        /* count data */
  40.     struct func {            /* function data: */
  41.         struct func *link;        /* link to next function */
  42.         char *name;            /* function name */
  43.         struct count count;        /* total number of calls */
  44.         struct caller {        /* caller data: */
  45.             struct caller *link;    /* link to next caller */
  46.             char *name;        /* caller's name */
  47.             char *file;        /* call site: file, x, y */
  48.             int x, y;
  49.             int count;        /* number of calls from this site */
  50.         } *callers;
  51.     } *funcs;            /* list of functions */
  52. } *filelist;
  53.  
  54. static void acaller ARGS((char *, char *, int, int, int, struct func *));
  55. static int compare ARGS((struct count *, struct count *));
  56. static struct func *afunction ARGS((char *, char *, int, int, int));
  57. static void apoint ARGS((int, char *, int, int, int));
  58. static struct file *findfile ARGS((char *));
  59. static int gather ARGS((void));
  60. static int getd ARGS((void));
  61. static char *getstr ARGS((void));
  62.  
  63. /* acaller - add caller and site (file,x,y) to callee's callers list */
  64. static void acaller(caller, file, x, y, count, callee)
  65. char *caller, *file; int x, y, count; struct func *callee; {
  66.     struct caller *q;
  67.  
  68.     assert(callee);
  69.     for (q = callee->callers; q && (caller != q->name
  70.         || file != q->file || x != q->x || y != q->y); q = q->link)
  71.         ;
  72.     if (!q) {
  73.         struct caller **r;
  74.         NEW(q, PERM);
  75.         q->name = caller;
  76.         q->file = file;
  77.         q->x = x;
  78.         q->y = y;
  79.         q->count = 0;
  80.         for (r = &callee->callers; *r && (strcmp(q->name, (*r)->name) > 0
  81.             || strcmp(q->file, (*r)->file) > 0 || q->y > (*r)->y || q->y > (*r)->y); r = &(*r)->link)
  82.             ;
  83.         q->link = *r;
  84.         *r = q;
  85.     }
  86.     q->count += count;
  87. }
  88.  
  89. /* afunction - add function name and its data to file's function list */
  90. static struct func *afunction(name, file, x, y, count)
  91. char *name, *file; int x, y, count; {
  92.     struct file *p = findfile(file);
  93.     struct func *q;
  94.  
  95.     assert(p);
  96.     for (q = p->funcs; q && name != q->name; q = q->link)
  97.         ;
  98.     if (!q) {
  99.         struct func **r;
  100.         NEW(q, PERM);
  101.         q->name = name;
  102.         q->count.x = x;
  103.         q->count.y = y;
  104.         q->count.count = 0;
  105.         q->callers = 0;
  106.         for (r = &p->funcs; *r && compare(&q->count, &(*r)->count) > 0; r = &(*r)->link)
  107.             ;
  108.         q->link = *r;
  109.         *r = q;
  110.     }
  111.     q->count.count += count;
  112.     return q;
  113. }
  114.  
  115. /* apoint - append execution point i to file's data */ 
  116. static void apoint(i, file, x, y, count)
  117. char *file; int i, x, y, count; {
  118.     struct file *p = findfile(file);
  119.  
  120.     assert(p);
  121.     if (i >= p->size) {
  122.         int j;
  123.         if (p->size == 0) {
  124.             p->size = i >= 200 ? 2*i : 200;
  125.             p->counts = newarray(p->size, sizeof *p->counts, PERM);
  126.         } else {
  127.             struct count *new;
  128.             p->size = 2*i;
  129.             new = newarray(p->size, sizeof *new, PERM);
  130.             for (j = 0; j < p->count; j++)
  131.                 new[j] = p->counts[j];
  132.             p->counts = new;
  133.         }
  134.         for (j = p->count; j < p->size; j++) {
  135.             static struct count z;
  136.             p->counts[j] = z;
  137.         }
  138.     }
  139.     p->counts[i].x = x;
  140.     p->counts[i].y = y;
  141.     p->counts[i].count += count;
  142.     if (i >= p->count)
  143.         p->count = i + 1;
  144. }
  145.  
  146. /* compare - return <0, 0, >0 if a<b, a==b, a>b, resp. */
  147. static int compare(a, b) struct count *a, *b; {
  148.     if (a->y == b->y)
  149.         return a->x - b->x;
  150.     return a->y - b->y;
  151. }
  152.  
  153. /* findcount - return count associated with (file,x,y) or -1 */
  154. int findcount(file, x, y) char *file; int x, y;{
  155.     static struct file *cursor;
  156.  
  157.     if (cursor == 0 || cursor->name != file)
  158.         cursor = findfile(file);
  159.     if (cursor) {
  160.         int l, u;
  161.         struct count *c = cursor->counts;
  162.         for (l = 0, u = cursor->count - 1; l <= u; ) {
  163.             int k = (l + u)/2;
  164.             if (c[k].y > y || c[k].y == y && c[k].x > x)
  165.                 u = k - 1;
  166.             else if (c[k].y < y || c[k].y == y && c[k].x < x)
  167.                 l = k + 1;
  168.             else
  169.                 return c[k].count;
  170.         }
  171.     }
  172.     return -1;
  173. }
  174.  
  175. /* findfile - return file name's file list entry, or 0 */
  176. static struct file *findfile(name) char *name; {
  177.     struct file *p;
  178.  
  179.     for (p = filelist; p; p = p->link)
  180.         if (p->name == name)
  181.             return p;
  182.     return 0;
  183. }
  184.  
  185. /* findfunc - return count associated with function name in file or -1 */
  186. int findfunc(name, file) char *name, *file; {
  187.     static struct file *cursor;
  188.  
  189.     if (cursor == 0 || cursor->name != file)
  190.         cursor = findfile(file);
  191.     if (cursor) {
  192.         struct func *p;
  193.         for (p = cursor->funcs; p; p = p->link)
  194.             if (p->name == name)
  195.                 return p->count.count;
  196.     }
  197.     return -1;
  198. }
  199.  
  200. /* gather - read prof.out data from fd */
  201. static int gather() {
  202.     int i, nfiles, nfuncs, npoints;
  203.     char *files[64];
  204.  
  205.     if ((nfiles = getd()) < 0)
  206.         return 0;
  207.     assert(nfiles < NELEMS(files));
  208.     for (i = 0; i < nfiles; i++) {
  209.         if ((files[i] = getstr()) == 0)
  210.             return -1;
  211.         if (!findfile(files[i])) {
  212.             struct file *new;
  213.             NEW(new, PERM);
  214.             new->name = files[i];
  215.             new->size = new->count = 0;
  216.             new->counts = 0;
  217.             new->funcs = 0;
  218.             new->link = filelist;
  219.             filelist = new;
  220.         }
  221.     }
  222.     if ((nfuncs = getd()) < 0)
  223.         return -1;
  224.     for (i = 0; i < nfuncs; i++) {
  225.         struct func *q;
  226.         char *name, *file;
  227.         int f, x, y, count;
  228.         if ((name = getstr()) == 0 || (f = getd()) <= 0
  229.         || (x = getd()) < 0 || (y = getd()) < 0 || (count = getd()) < 0)
  230.             return -1;
  231.         q = afunction(name, files[f-1], x, y, count);
  232.         if ((name = getstr()) == 0 || (file = getstr()) == 0
  233.         || (x = getd()) < 0 || (y = getd()) < 0)
  234.             return -1;
  235.         if (*name != '?')
  236.             acaller(name, file, x, y, count, q);
  237.     }
  238.     if ((npoints = getd()) < 0)
  239.         return -1;
  240.     for (i = 0; i < npoints; i++) {
  241.         int f, x, y, count;
  242.         if ((f = getd()) < 0 || (x = getd()) < 0 || (y = getd()) < 0
  243.         || (count = getd()) < 0)
  244.             return -1;
  245.         if (f)
  246.             apoint(i, files[f-1], x, y, count);
  247.     }
  248.     return 1;
  249. }
  250.  
  251. /* getd - read a nonnegative number */
  252. static int getd() {
  253.     int c, n = 0;
  254.  
  255.     while ((c = ngetc()) != EOF && (c == ' ' || c == '\n' || c == '\t'))
  256.         ;
  257.     if (c >= '0' && c <= '9') {
  258.         do
  259.             n = 10*n + (c - '0');
  260.         while ((c = ngetc()) >= '0' && c <= '9');
  261.         return n;
  262.     }
  263.     return -1;
  264. }
  265.  
  266. /* getstr - read a string */
  267. static char *getstr() {
  268.     int c;
  269.     char buf[MAXTOKEN], *s = buf;
  270.  
  271.     while ((c = ngetc()) != EOF && c != ' ' && c != '\n' && c != '\t')
  272.         if (s - buf < (int)sizeof buf - 2)
  273.             *s++ = c;
  274.     *s = 0;
  275.     return s == buf ? (char *)0 : string(buf);
  276. }
  277.  
  278. /* process - read prof.out data from file */
  279. int process(file) char *file; {
  280.     int more;
  281.  
  282. #ifdef BPRINT
  283.     if ((fp = fopen(file, "r")) != NULL) {
  284.         while ((more = gather()) > 0)
  285.             ;
  286.         fclose(fp);
  287.         return more < 0 ? more : 1;
  288.     }
  289. #else
  290.     struct file *p;
  291.  
  292.     if ((infd = open(file, 0)) >= 0) {
  293.         inputInit();
  294.         while ((more = gather()) > 0)
  295.             ;
  296.         close(infd);
  297.         if (more < 0)
  298.             return more;
  299.         for (p = filelist; p; p = p->link)
  300.             qsort(p->counts, p->count, sizeof *p->counts,
  301.                 (int (*) ARGS((const void *, const void *)))
  302.                 compare);
  303.         
  304.         return 1;
  305.     }
  306. #endif
  307.     return 0;
  308. }
  309.  
  310.