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