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