1*da2e3ebdSchin /*********************************************************************** 2*da2e3ebdSchin * * 3*da2e3ebdSchin * This software is part of the ast package * 4*da2e3ebdSchin * Copyright (c) 1986-2007 AT&T Knowledge Ventures * 5*da2e3ebdSchin * and is licensed under the * 6*da2e3ebdSchin * Common Public License, Version 1.0 * 7*da2e3ebdSchin * by AT&T Knowledge Ventures * 8*da2e3ebdSchin * * 9*da2e3ebdSchin * A copy of the License is available at * 10*da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt * 11*da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12*da2e3ebdSchin * * 13*da2e3ebdSchin * Information and Software Systems Research * 14*da2e3ebdSchin * AT&T Research * 15*da2e3ebdSchin * Florham Park NJ * 16*da2e3ebdSchin * * 17*da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> * 18*da2e3ebdSchin * * 19*da2e3ebdSchin ***********************************************************************/ 20*da2e3ebdSchin #pragma prototyped 21*da2e3ebdSchin /* 22*da2e3ebdSchin * Glenn Fowler 23*da2e3ebdSchin * AT&T Research 24*da2e3ebdSchin * 25*da2e3ebdSchin * preprocessor library trace and debug support 26*da2e3ebdSchin */ 27*da2e3ebdSchin 28*da2e3ebdSchin #include "pplib.h" 29*da2e3ebdSchin #include "ppfsm.h" 30*da2e3ebdSchin 31*da2e3ebdSchin #include <ctype.h> 32*da2e3ebdSchin 33*da2e3ebdSchin /* 34*da2e3ebdSchin * convert token string to printable form 35*da2e3ebdSchin */ 36*da2e3ebdSchin 37*da2e3ebdSchin char* 38*da2e3ebdSchin pptokstr(register char* s, register int c) 39*da2e3ebdSchin { 40*da2e3ebdSchin register char* t; 41*da2e3ebdSchin 42*da2e3ebdSchin static char buf[8]; 43*da2e3ebdSchin 44*da2e3ebdSchin if (t = s) 45*da2e3ebdSchin { 46*da2e3ebdSchin while (*t == ' ' || *t == '\t') t++; 47*da2e3ebdSchin c = *t ? *t : *s; 48*da2e3ebdSchin } 49*da2e3ebdSchin switch (c) 50*da2e3ebdSchin { 51*da2e3ebdSchin case 0: 52*da2e3ebdSchin case 0400: 53*da2e3ebdSchin return("`EOF'"); 54*da2e3ebdSchin case ' ': 55*da2e3ebdSchin return("`space'"); 56*da2e3ebdSchin case '\f': 57*da2e3ebdSchin return("`formfeed'"); 58*da2e3ebdSchin case '\n': 59*da2e3ebdSchin return("`newline'"); 60*da2e3ebdSchin case '\t': 61*da2e3ebdSchin return("`tab'"); 62*da2e3ebdSchin case '\v': 63*da2e3ebdSchin return("`vertical-tab'"); 64*da2e3ebdSchin case T_TOKCAT: 65*da2e3ebdSchin return("##"); 66*da2e3ebdSchin default: 67*da2e3ebdSchin if (iscntrl(c) || !isprint(c)) sfsprintf(buf, sizeof(buf), "`%03o'", c); 68*da2e3ebdSchin else if (s) return(s); 69*da2e3ebdSchin else sfsprintf(buf, sizeof(buf), "%c", c); 70*da2e3ebdSchin return(buf); 71*da2e3ebdSchin } 72*da2e3ebdSchin } 73*da2e3ebdSchin 74*da2e3ebdSchin #if DEBUG & TRACE_debug 75*da2e3ebdSchin 76*da2e3ebdSchin #include "ppdebug.h" 77*da2e3ebdSchin 78*da2e3ebdSchin /* 79*da2e3ebdSchin * return input stream name given index 80*da2e3ebdSchin */ 81*da2e3ebdSchin 82*da2e3ebdSchin char* 83*da2e3ebdSchin ppinstr(register struct ppinstk* p) 84*da2e3ebdSchin { 85*da2e3ebdSchin register int i; 86*da2e3ebdSchin 87*da2e3ebdSchin static char buf[128]; 88*da2e3ebdSchin 89*da2e3ebdSchin for (i = 0; i < elementsof(ppinmap); i++) 90*da2e3ebdSchin if (p->type == ppinmap[i].val) 91*da2e3ebdSchin { 92*da2e3ebdSchin switch (p->type) 93*da2e3ebdSchin { 94*da2e3ebdSchin case IN_MACRO: 95*da2e3ebdSchin #if MACDEF 96*da2e3ebdSchin case IN_MULTILINE: 97*da2e3ebdSchin #endif 98*da2e3ebdSchin if (p->symbol) 99*da2e3ebdSchin { 100*da2e3ebdSchin sfsprintf(buf, sizeof(buf), "%s=%s", ppinmap[i].nam, p->symbol->name); 101*da2e3ebdSchin return(buf); 102*da2e3ebdSchin } 103*da2e3ebdSchin break; 104*da2e3ebdSchin } 105*da2e3ebdSchin return(ppinmap[i].nam); 106*da2e3ebdSchin } 107*da2e3ebdSchin sfsprintf(buf, sizeof(buf), "UNKNOWN[%d]", p->type); 108*da2e3ebdSchin return(buf); 109*da2e3ebdSchin } 110*da2e3ebdSchin 111*da2e3ebdSchin /* 112*da2e3ebdSchin * return string given fsm lex state 113*da2e3ebdSchin */ 114*da2e3ebdSchin 115*da2e3ebdSchin char* 116*da2e3ebdSchin pplexstr(register int lex) 117*da2e3ebdSchin { 118*da2e3ebdSchin register int i; 119*da2e3ebdSchin int splice; 120*da2e3ebdSchin static char buf[64]; 121*da2e3ebdSchin 122*da2e3ebdSchin if (lex < 0) lex &= ~lex; 123*da2e3ebdSchin splice = (lex & SPLICE); 124*da2e3ebdSchin lex &= 0x7f; 125*da2e3ebdSchin for (i = 0; i < (elementsof(pplexmap) - 1) && (lex > pplexmap[i].val || lex == pplexmap[i+1].val); i++); 126*da2e3ebdSchin if (lex != pplexmap[i].val) 127*da2e3ebdSchin { 128*da2e3ebdSchin if (pplexmap[i].val < 0) sfsprintf(buf, sizeof(buf), "%s|0x%04x%s", pplexmap[i].nam, lex, splice ? "|SPLICE" : ""); 129*da2e3ebdSchin else sfsprintf(buf, sizeof(buf), "%s+%d", pplexmap[i-1].nam, lex - pplexmap[i-1].val, splice ? "|SPLICE" : ""); 130*da2e3ebdSchin return(buf); 131*da2e3ebdSchin } 132*da2e3ebdSchin if (splice) 133*da2e3ebdSchin { 134*da2e3ebdSchin sfsprintf(buf, sizeof(buf), "%s|SPLICE", pplexmap[i].nam); 135*da2e3ebdSchin return(buf); 136*da2e3ebdSchin } 137*da2e3ebdSchin return(pplexmap[i].nam); 138*da2e3ebdSchin } 139*da2e3ebdSchin 140*da2e3ebdSchin /* 141*da2e3ebdSchin * return string given map p of size n and flags 142*da2e3ebdSchin */ 143*da2e3ebdSchin 144*da2e3ebdSchin static char* 145*da2e3ebdSchin ppflagstr(register struct map* p, int n, register long flags) 146*da2e3ebdSchin { 147*da2e3ebdSchin register int i; 148*da2e3ebdSchin register int k; 149*da2e3ebdSchin register char* s; 150*da2e3ebdSchin 151*da2e3ebdSchin static char buf[128]; 152*da2e3ebdSchin 153*da2e3ebdSchin s = buf; 154*da2e3ebdSchin for (i = 0; i < n; i++) 155*da2e3ebdSchin if (flags & p[i].val) 156*da2e3ebdSchin { 157*da2e3ebdSchin k = strlen(p[i].nam); 158*da2e3ebdSchin if ((elementsof(buf) - 2 - (s - buf)) > k) 159*da2e3ebdSchin { 160*da2e3ebdSchin if (s > buf) *s++ = '|'; 161*da2e3ebdSchin strcpy(s, p[i].nam); 162*da2e3ebdSchin s += k; 163*da2e3ebdSchin } 164*da2e3ebdSchin } 165*da2e3ebdSchin *s = 0; 166*da2e3ebdSchin return(buf); 167*da2e3ebdSchin } 168*da2e3ebdSchin 169*da2e3ebdSchin /* 170*da2e3ebdSchin * return string given pp.mode 171*da2e3ebdSchin */ 172*da2e3ebdSchin 173*da2e3ebdSchin char* 174*da2e3ebdSchin ppmodestr(register long mode) 175*da2e3ebdSchin { 176*da2e3ebdSchin return(ppflagstr(ppmodemap, elementsof(ppmodemap), mode)); 177*da2e3ebdSchin } 178*da2e3ebdSchin 179*da2e3ebdSchin /* 180*da2e3ebdSchin * return string given pp.option 181*da2e3ebdSchin */ 182*da2e3ebdSchin 183*da2e3ebdSchin char* 184*da2e3ebdSchin ppoptionstr(register long option) 185*da2e3ebdSchin { 186*da2e3ebdSchin return(ppflagstr(ppoptionmap, elementsof(ppoptionmap), option)); 187*da2e3ebdSchin } 188*da2e3ebdSchin 189*da2e3ebdSchin /* 190*da2e3ebdSchin * return string given pp.state 191*da2e3ebdSchin */ 192*da2e3ebdSchin 193*da2e3ebdSchin char* 194*da2e3ebdSchin ppstatestr(register long state) 195*da2e3ebdSchin { 196*da2e3ebdSchin return(ppflagstr(ppstatemap, elementsof(ppstatemap), state)); 197*da2e3ebdSchin } 198*da2e3ebdSchin 199*da2e3ebdSchin #include <sig.h> 200*da2e3ebdSchin 201*da2e3ebdSchin /* 202*da2e3ebdSchin * io stream stack trace 203*da2e3ebdSchin * sig==0 registers the handler 204*da2e3ebdSchin */ 205*da2e3ebdSchin 206*da2e3ebdSchin void 207*da2e3ebdSchin pptrace(int sig) 208*da2e3ebdSchin { 209*da2e3ebdSchin register char* s; 210*da2e3ebdSchin register char* x; 211*da2e3ebdSchin register struct ppinstk* p; 212*da2e3ebdSchin static int handling; 213*da2e3ebdSchin 214*da2e3ebdSchin if (!sig) 215*da2e3ebdSchin { 216*da2e3ebdSchin #ifdef SIGBUS 217*da2e3ebdSchin signal(SIGBUS, pptrace); 218*da2e3ebdSchin #endif 219*da2e3ebdSchin #ifdef SIGSEGV 220*da2e3ebdSchin signal(SIGSEGV, pptrace); 221*da2e3ebdSchin #endif 222*da2e3ebdSchin #ifdef SIGILL 223*da2e3ebdSchin signal(SIGILL, pptrace); 224*da2e3ebdSchin #endif 225*da2e3ebdSchin signal(SIGQUIT, pptrace); 226*da2e3ebdSchin return; 227*da2e3ebdSchin } 228*da2e3ebdSchin s = fmtsignal(sig); 229*da2e3ebdSchin if (handling) 230*da2e3ebdSchin { 231*da2e3ebdSchin sfprintf(sfstderr, "\n%s during io stack trace\n", s); 232*da2e3ebdSchin signal(handling, SIG_DFL); 233*da2e3ebdSchin sigunblock(handling); 234*da2e3ebdSchin kill(getpid(), handling); 235*da2e3ebdSchin pause(); 236*da2e3ebdSchin error(PANIC, "signal not redelivered"); 237*da2e3ebdSchin } 238*da2e3ebdSchin handling = sig; 239*da2e3ebdSchin sfprintf(sfstderr, "\n%s - io stack trace\n", s); 240*da2e3ebdSchin for (p = pp.in; p->prev; p = p->prev) 241*da2e3ebdSchin { 242*da2e3ebdSchin sfprintf(sfstderr, "\n[%s]\n", ppinstr(p)); 243*da2e3ebdSchin if ((s = pp.in->nextchr) && *s) 244*da2e3ebdSchin { 245*da2e3ebdSchin if (*s != '\n') sfputc(sfstderr, '\t'); 246*da2e3ebdSchin x = s + 256; 247*da2e3ebdSchin while (*s && s < x) 248*da2e3ebdSchin { 249*da2e3ebdSchin sfputc(sfstderr, *s); 250*da2e3ebdSchin if (*s++ == '\n' && *s && *s != '\n') sfputc(sfstderr, '\t'); 251*da2e3ebdSchin } 252*da2e3ebdSchin if (*s) sfprintf(sfstderr, " ..."); 253*da2e3ebdSchin } 254*da2e3ebdSchin } 255*da2e3ebdSchin sfprintf(sfstderr, "\n"); 256*da2e3ebdSchin handling = 0; 257*da2e3ebdSchin signal(sig, SIG_DFL); 258*da2e3ebdSchin sigunblock(sig); 259*da2e3ebdSchin kill(getpid(), sig); 260*da2e3ebdSchin pause(); 261*da2e3ebdSchin error(PANIC, "signal not redelivered"); 262*da2e3ebdSchin } 263*da2e3ebdSchin 264*da2e3ebdSchin #endif 265