xref: /titanic_41/usr/src/lib/libpp/common/pptrace.c (revision 4a7ceb24cfcc0a97f96d86cfe5852ae445b50e57)
1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *           Copyright (c) 1986-2007 AT&T Knowledge Ventures            *
5 *                      and is licensed under the                       *
6 *                  Common Public License, Version 1.0                  *
7 *                      by AT&T Knowledge Ventures                      *
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*
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*
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*
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*
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*
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*
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*
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
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