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