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 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