1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1986-2009 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * *
19 ***********************************************************************/
20 #pragma prototyped
21 /*
22 * Glenn Fowler
23 * AT&T Research
24 *
25 * preprocessor library trace and debug support
26 */
27
28 #include "pplib.h"
29 #include "ppfsm.h"
30
31 #include <ctype.h>
32
33 /*
34 * convert token string to printable form
35 */
36
37 char*
pptokstr(register char * s,register int c)38 pptokstr(register char* s, register int c)
39 {
40 register char* t;
41
42 static char buf[8];
43
44 if (t = s)
45 {
46 while (*t == ' ' || *t == '\t') t++;
47 c = *t ? *t : *s;
48 }
49 switch (c)
50 {
51 case 0:
52 case 0400:
53 return("`EOF'");
54 case ' ':
55 return("`space'");
56 case '\f':
57 return("`formfeed'");
58 case '\n':
59 return("`newline'");
60 case '\t':
61 return("`tab'");
62 case '\v':
63 return("`vertical-tab'");
64 case T_TOKCAT:
65 return("##");
66 default:
67 if (iscntrl(c) || !isprint(c)) sfsprintf(buf, sizeof(buf), "`%03o'", c);
68 else if (s) return(s);
69 else sfsprintf(buf, sizeof(buf), "%c", c);
70 return(buf);
71 }
72 }
73
74 #if DEBUG & TRACE_debug
75
76 #include "ppdebug.h"
77
78 /*
79 * return input stream name given index
80 */
81
82 char*
ppinstr(register struct ppinstk * p)83 ppinstr(register struct ppinstk* p)
84 {
85 register int i;
86
87 static char buf[128];
88
89 for (i = 0; i < elementsof(ppinmap); i++)
90 if (p->type == ppinmap[i].val)
91 {
92 switch (p->type)
93 {
94 case IN_MACRO:
95 #if MACDEF
96 case IN_MULTILINE:
97 #endif
98 if (p->symbol)
99 {
100 sfsprintf(buf, sizeof(buf), "%s=%s", ppinmap[i].nam, p->symbol->name);
101 return(buf);
102 }
103 break;
104 }
105 return(ppinmap[i].nam);
106 }
107 sfsprintf(buf, sizeof(buf), "UNKNOWN[%d]", p->type);
108 return(buf);
109 }
110
111 /*
112 * return string given fsm lex state
113 */
114
115 char*
pplexstr(register int lex)116 pplexstr(register int lex)
117 {
118 register int i;
119 int splice;
120 static char buf[64];
121
122 if (lex < 0) lex &= ~lex;
123 splice = (lex & SPLICE);
124 lex &= 0x7f;
125 for (i = 0; i < (elementsof(pplexmap) - 1) && (lex > pplexmap[i].val || lex == pplexmap[i+1].val); i++);
126 if (lex != pplexmap[i].val)
127 {
128 if (pplexmap[i].val < 0) sfsprintf(buf, sizeof(buf), "%s|0x%04x%s", pplexmap[i].nam, lex, splice ? "|SPLICE" : "");
129 else sfsprintf(buf, sizeof(buf), "%s+%d", pplexmap[i-1].nam, lex - pplexmap[i-1].val, splice ? "|SPLICE" : "");
130 return(buf);
131 }
132 if (splice)
133 {
134 sfsprintf(buf, sizeof(buf), "%s|SPLICE", pplexmap[i].nam);
135 return(buf);
136 }
137 return(pplexmap[i].nam);
138 }
139
140 /*
141 * return string given map p of size n and flags
142 */
143
144 static char*
ppflagstr(register struct map * p,int n,register long flags)145 ppflagstr(register struct map* p, int n, register long flags)
146 {
147 register int i;
148 register int k;
149 register char* s;
150
151 static char buf[128];
152
153 s = buf;
154 for (i = 0; i < n; i++)
155 if (flags & p[i].val)
156 {
157 k = strlen(p[i].nam);
158 if ((elementsof(buf) - 2 - (s - buf)) > k)
159 {
160 if (s > buf) *s++ = '|';
161 strcpy(s, p[i].nam);
162 s += k;
163 }
164 }
165 *s = 0;
166 return(buf);
167 }
168
169 /*
170 * return string given pp.mode
171 */
172
173 char*
ppmodestr(register long mode)174 ppmodestr(register long mode)
175 {
176 return(ppflagstr(ppmodemap, elementsof(ppmodemap), mode));
177 }
178
179 /*
180 * return string given pp.option
181 */
182
183 char*
ppoptionstr(register long option)184 ppoptionstr(register long option)
185 {
186 return(ppflagstr(ppoptionmap, elementsof(ppoptionmap), option));
187 }
188
189 /*
190 * return string given pp.state
191 */
192
193 char*
ppstatestr(register long state)194 ppstatestr(register long state)
195 {
196 return(ppflagstr(ppstatemap, elementsof(ppstatemap), state));
197 }
198
199 #include <sig.h>
200
201 /*
202 * io stream stack trace
203 * sig==0 registers the handler
204 */
205
206 void
pptrace(int sig)207 pptrace(int sig)
208 {
209 register char* s;
210 register char* x;
211 register struct ppinstk* p;
212 static int handling;
213
214 if (!sig)
215 {
216 #ifdef SIGBUS
217 signal(SIGBUS, pptrace);
218 #endif
219 #ifdef SIGSEGV
220 signal(SIGSEGV, pptrace);
221 #endif
222 #ifdef SIGILL
223 signal(SIGILL, pptrace);
224 #endif
225 signal(SIGQUIT, pptrace);
226 return;
227 }
228 s = fmtsignal(sig);
229 if (handling)
230 {
231 sfprintf(sfstderr, "\n%s during io stack trace\n", s);
232 signal(handling, SIG_DFL);
233 sigunblock(handling);
234 kill(getpid(), handling);
235 pause();
236 error(PANIC, "signal not redelivered");
237 }
238 handling = sig;
239 sfprintf(sfstderr, "\n%s - io stack trace\n", s);
240 for (p = pp.in; p->prev; p = p->prev)
241 {
242 sfprintf(sfstderr, "\n[%s]\n", ppinstr(p));
243 if ((s = pp.in->nextchr) && *s)
244 {
245 if (*s != '\n') sfputc(sfstderr, '\t');
246 x = s + 256;
247 while (*s && s < x)
248 {
249 sfputc(sfstderr, *s);
250 if (*s++ == '\n' && *s && *s != '\n') sfputc(sfstderr, '\t');
251 }
252 if (*s) sfprintf(sfstderr, " ...");
253 }
254 }
255 sfprintf(sfstderr, "\n");
256 handling = 0;
257 signal(sig, SIG_DFL);
258 sigunblock(sig);
259 kill(getpid(), sig);
260 pause();
261 error(PANIC, "signal not redelivered");
262 }
263
264 #endif
265