Pristine Ack-5.5
[Ack-5.5.git] / util / int / tally.c
1 /*
2         Gathering run-time statistics
3 */
4
5 /* $Id: tally.c,v 2.2 1994/06/24 10:49:19 ceriel Exp $ */
6
7 #include        <stdio.h>
8
9 #include        "global.h"
10 #include        "linfil.h"
11 #include        "alloc.h"
12
13 struct line_tally {                     /* one for each line */
14         long lt_cnt;                    /* counts entrances */
15         long lt_instr;                  /* counts instructions */
16 };
17
18 struct file_tally {                     /* one for each file */
19         struct file_tally *next;
20         ptr ft_fil;                     /* file name */
21         long ft_limit;                  /* size of line array */
22         struct line_tally *ft_line;     /* pointer to line array */
23 };
24
25 PRIVATE struct file_tally *first_tally; /* start of chain */
26 PRIVATE struct file_tally *file;        /* present file */
27
28 PRIVATE long lastLIN;
29
30 PRIVATE tally_newFIL();
31 PRIVATE enlarge();
32
33 tally()
34 {
35         if (!FIL)
36                 return;
37         
38         if (!file || FIL != file->ft_fil) {
39                 tally_newFIL(FIL);
40                 file->ft_fil = FIL;
41                 lastLIN = -1;
42         }
43         if (LIN != lastLIN) {
44                 if (LIN >= file->ft_limit) {
45                         enlarge(file, LIN);
46                 }
47                 file->ft_line[LIN].lt_cnt++;
48                 lastLIN = LIN;
49         }
50         file->ft_line[LIN].lt_instr++;
51 }
52
53 PRIVATE tally_newFIL(f)
54         ptr f;
55 {
56         struct file_tally **hook = &first_tally;
57         
58         while (*hook) {
59                 if ((*hook)->ft_fil == f)
60                         break;
61                 hook = &(*hook)->next;
62         }
63         if (!*hook) {
64                 /* first time we see this file */
65                 /* construct a new entry */
66                 struct file_tally *nt = (struct file_tally *)
67                         Malloc((size) sizeof (struct file_tally), "file_tally");
68                 
69                 nt->next = (struct file_tally *)0;
70                 nt->ft_fil = f;
71                 nt->ft_limit = 1;       /* provisional length */
72                 nt->ft_line = (struct line_tally *)
73                         Malloc((size) sizeof (struct line_tally),
74                                                         "struct line_tally");
75                 nt->ft_line[0].lt_cnt = 0;
76                 nt->ft_line[0].lt_instr = 0;
77                 
78                 /* and hook it in */
79                 *hook = nt;
80         }
81         file = *hook;
82 }
83
84 PRIVATE enlarge(ft, l)
85         struct file_tally *ft;
86         long l;
87 {
88         long limit = allocfrac(l < 100 ? 100 : l);
89         
90         if (limit <= ft->ft_limit)
91                 return;
92         ft->ft_line = (struct line_tally *)
93                 Realloc((char *)ft->ft_line,
94                         (size)(limit*sizeof (struct line_tally)),
95                         "array line_tally");
96         while (ft->ft_limit < limit) {
97                 ft->ft_line[ft->ft_limit].lt_cnt = 0;
98                 ft->ft_line[ft->ft_limit].lt_instr = 0;
99                 ft->ft_limit++;
100         }
101 }
102
103 PRIVATE FILE *tally_fp;
104
105 out_tally()
106 {
107         struct file_tally **hook = &first_tally;
108         
109         if (!*hook)
110                 return;
111
112         tally_fp = fopen("int.tally", "w");
113         if (!tally_fp)
114                 return;
115
116         while (*hook) {
117                 struct file_tally *ft = *hook;
118                 register long i;
119                 
120                 fprintf(tally_fp, "%s:\n", dt_fname(ft->ft_fil));
121                 for (i = 0; i < ft->ft_limit; i++) {
122                         struct line_tally *lt = &ft->ft_line[i];
123                         
124                         if (lt->lt_cnt) {
125                                 /* we visited this line */
126                                 fprintf(tally_fp, "\t%ld\t%ld\t%ld\n",
127                                         i, lt->lt_cnt, lt->lt_instr);
128                         }
129                 }
130                 fprintf(tally_fp, "\n");
131                 hook = &(*hook)->next;
132         }
133
134         fclose(tally_fp);
135         tally_fp = 0;
136 }
137