Pristine Ack-5.5
[Ack-5.5.git] / util / int / warn.c
1 /*
2         Warnings.
3 */
4
5 /* $Id: warn.c,v 2.3 1994/06/24 10:49:39 ceriel Exp $ */
6
7 #include        <stdio.h>
8
9 #include        "logging.h"
10 #include        "global.h"
11 #include        "log.h"
12 #include        "alloc.h"
13 #include        "warn.h"
14 #include        "linfil.h"
15
16 extern FILE *mess_fp;                   /* from io.c */
17 extern char *trap2text();               /* from trap.c */
18
19 /********  The warnings  ********/
20
21 struct warn_msg {
22         char *wm_text;
23         int wm_nr;
24 };
25
26 #define WMASK           0x5555          /* powers of 4 */
27
28 PRIVATE struct warn_msg warn_msg[] = {
29 #include        "warn_msg"              /* generated from $(EM)/doc/int */
30         {0,             0}              /* sentinel */
31 };
32
33 PRIVATE char *warn_text[WMSG+1];
34
35 init_wmsg()
36 {
37         register int i;
38         register struct warn_msg *wmsg;
39
40         for (i = 0; i <= WMSG; i++) {
41                 warn_text[i] = "*** Unknown warning (internal error) ***";
42         }
43         
44         for (wmsg = &warn_msg[0]; wmsg->wm_nr; wmsg++) {
45                 warn_text[wmsg->wm_nr] = wmsg->wm_text;
46         }
47 }
48
49 /********  The warning counters  ********/
50
51 struct warn_cnt {
52         struct warn_cnt *next;
53         ptr wc_fil;                     /* file name pointer */
54         long wc_lin;                    /* line number */
55         long wc_cnt;                    /* the counter */
56 };
57
58 PRIVATE struct warn_cnt *warn_cnt[WMSG];
59 PRIVATE char warnmask[WMSG];
60
61 PRIVATE long count_wrn(nr)
62         int nr;
63 {       /*      returns the occurrence counter for the warning with number
64                 nr; keeps track of the warnings, sorted by warning number,
65                 file name and line number.
66         */
67         register struct warn_cnt **warn_hook = &warn_cnt[nr];
68         register struct warn_cnt *wrn;
69
70         while (wrn = *warn_hook) {
71                 if (wrn->wc_fil == FIL && wrn->wc_lin == LIN) {
72                         return ++wrn->wc_cnt;
73                 }
74                 warn_hook = &wrn->next;
75         }
76
77         wrn = (struct warn_cnt *)
78                 Malloc((size) sizeof (struct warn_cnt), (char *)0);
79         if (!wrn) {
80                 /* no problem */
81                 return 1;
82         }
83         *warn_hook = wrn;
84         wrn->next = 0;
85         wrn->wc_fil = FIL;
86         wrn->wc_lin = LIN;
87         wrn->wc_cnt = 1;
88         return 1;
89 }
90
91 /******** The handling ********/
92
93 #define wmask_on(i)     (warnmask[i])
94
95 PRIVATE int latest_warning_printed;     /* set if ... */
96
97 /*ARGSUSED*/
98 do_warn(nr, L, F)
99         int nr;
100         int L;
101         char *F;
102 {
103         latest_warning_printed = 0;
104         if (nr < WMSG) {
105                 if (!wmask_on(nr)) {
106                         register long wrn_cnt = count_wrn(nr);
107                         register char *wmsgtxt = warn_text[nr];
108                         
109                         LOG(("@w1 warning: %s [%s: %d]", wmsgtxt, F, L));
110                         if (    /* wrn_cnt is a power of two */
111                                 !((wrn_cnt-1) & wrn_cnt)
112                         &&      /* and it is the right power of two */
113                                 (WMASK & wrn_cnt)
114                         ) {
115                                 fprintf(mess_fp,
116                                         "(Warning %d, #%ld): %s at %s\n",
117                                         nr, wrn_cnt, wmsgtxt, position());
118                                 latest_warning_printed = 1;
119                         }
120                 }
121         }
122         else {
123                 /* actually a trap number */
124                 nr -= WMSG;
125                 
126                 fprintf(mess_fp, "(Warning): Trap occurred - %s at %s\n",
127                                         trap2text(nr), position());
128         }
129 }
130
131 #ifdef  LOGGING
132
133 warningcont(nr)
134         int nr;
135 {
136         /* continued warning */
137         if (latest_warning_printed) {
138                 if (!wmask_on(nr)) {
139                         register char *wmsgtxt = warn_text[nr];
140                         
141                         LOG(("@w1 warning cont.: %s", wmsgtxt));
142                         fprintf(mess_fp,
143                                 "(Warning %d, cont.): %s at %s\n",
144                                         nr, wmsgtxt, position());
145                 }
146         }
147 }
148
149 #endif  /* LOGGING */
150
151 set_wmask(i)
152         int i;
153 {
154         if (i < WMSG) {
155                 warnmask[i] = 1;
156         }
157 }
158