1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin *                                                                      *
3da2e3ebdSchin *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1986-2011 AT&T Intellectual Property          *
5da2e3ebdSchin *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
77c2fbfb3SApril Chin *                    by AT&T Intellectual Property                     *
8da2e3ebdSchin *                                                                      *
9da2e3ebdSchin *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
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