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
37char*
38pptokstr(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
82char*
83ppinstr(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
115char*
116pplexstr(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
144static char*
145ppflagstr(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
173char*
174ppmodestr(register long mode)
175{
176	return(ppflagstr(ppmodemap, elementsof(ppmodemap), mode));
177}
178
179/*
180 * return string given pp.option
181 */
182
183char*
184ppoptionstr(register long option)
185{
186	return(ppflagstr(ppoptionmap, elementsof(ppoptionmap), option));
187}
188
189/*
190 * return string given pp.state
191 */
192
193char*
194ppstatestr(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
206void
207pptrace(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