/*********************************************************************** * * * This software is part of the ast package * * Copyright (c) 1986-2007 AT&T Knowledge Ventures * * and is licensed under the * * Common Public License, Version 1.0 * * by AT&T Knowledge Ventures * * * * A copy of the License is available at * * http://www.opensource.org/licenses/cpl1.0.txt * * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * * * * Information and Software Systems Research * * AT&T Research * * Florham Park NJ * * * * Glenn Fowler * * * ***********************************************************************/ #pragma prototyped /* * Glenn Fowler * AT&T Research * * preprocessor library trace and debug support */ #include "pplib.h" #include "ppfsm.h" #include /* * convert token string to printable form */ char* pptokstr(register char* s, register int c) { register char* t; static char buf[8]; if (t = s) { while (*t == ' ' || *t == '\t') t++; c = *t ? *t : *s; } switch (c) { case 0: case 0400: return("`EOF'"); case ' ': return("`space'"); case '\f': return("`formfeed'"); case '\n': return("`newline'"); case '\t': return("`tab'"); case '\v': return("`vertical-tab'"); case T_TOKCAT: return("##"); default: if (iscntrl(c) || !isprint(c)) sfsprintf(buf, sizeof(buf), "`%03o'", c); else if (s) return(s); else sfsprintf(buf, sizeof(buf), "%c", c); return(buf); } } #if DEBUG & TRACE_debug #include "ppdebug.h" /* * return input stream name given index */ char* ppinstr(register struct ppinstk* p) { register int i; static char buf[128]; for (i = 0; i < elementsof(ppinmap); i++) if (p->type == ppinmap[i].val) { switch (p->type) { case IN_MACRO: #if MACDEF case IN_MULTILINE: #endif if (p->symbol) { sfsprintf(buf, sizeof(buf), "%s=%s", ppinmap[i].nam, p->symbol->name); return(buf); } break; } return(ppinmap[i].nam); } sfsprintf(buf, sizeof(buf), "UNKNOWN[%d]", p->type); return(buf); } /* * return string given fsm lex state */ char* pplexstr(register int lex) { register int i; int splice; static char buf[64]; if (lex < 0) lex &= ~lex; splice = (lex & SPLICE); lex &= 0x7f; for (i = 0; i < (elementsof(pplexmap) - 1) && (lex > pplexmap[i].val || lex == pplexmap[i+1].val); i++); if (lex != pplexmap[i].val) { if (pplexmap[i].val < 0) sfsprintf(buf, sizeof(buf), "%s|0x%04x%s", pplexmap[i].nam, lex, splice ? "|SPLICE" : ""); else sfsprintf(buf, sizeof(buf), "%s+%d", pplexmap[i-1].nam, lex - pplexmap[i-1].val, splice ? "|SPLICE" : ""); return(buf); } if (splice) { sfsprintf(buf, sizeof(buf), "%s|SPLICE", pplexmap[i].nam); return(buf); } return(pplexmap[i].nam); } /* * return string given map p of size n and flags */ static char* ppflagstr(register struct map* p, int n, register long flags) { register int i; register int k; register char* s; static char buf[128]; s = buf; for (i = 0; i < n; i++) if (flags & p[i].val) { k = strlen(p[i].nam); if ((elementsof(buf) - 2 - (s - buf)) > k) { if (s > buf) *s++ = '|'; strcpy(s, p[i].nam); s += k; } } *s = 0; return(buf); } /* * return string given pp.mode */ char* ppmodestr(register long mode) { return(ppflagstr(ppmodemap, elementsof(ppmodemap), mode)); } /* * return string given pp.option */ char* ppoptionstr(register long option) { return(ppflagstr(ppoptionmap, elementsof(ppoptionmap), option)); } /* * return string given pp.state */ char* ppstatestr(register long state) { return(ppflagstr(ppstatemap, elementsof(ppstatemap), state)); } #include /* * io stream stack trace * sig==0 registers the handler */ void pptrace(int sig) { register char* s; register char* x; register struct ppinstk* p; static int handling; if (!sig) { #ifdef SIGBUS signal(SIGBUS, pptrace); #endif #ifdef SIGSEGV signal(SIGSEGV, pptrace); #endif #ifdef SIGILL signal(SIGILL, pptrace); #endif signal(SIGQUIT, pptrace); return; } s = fmtsignal(sig); if (handling) { sfprintf(sfstderr, "\n%s during io stack trace\n", s); signal(handling, SIG_DFL); sigunblock(handling); kill(getpid(), handling); pause(); error(PANIC, "signal not redelivered"); } handling = sig; sfprintf(sfstderr, "\n%s - io stack trace\n", s); for (p = pp.in; p->prev; p = p->prev) { sfprintf(sfstderr, "\n[%s]\n", ppinstr(p)); if ((s = pp.in->nextchr) && *s) { if (*s != '\n') sfputc(sfstderr, '\t'); x = s + 256; while (*s && s < x) { sfputc(sfstderr, *s); if (*s++ == '\n' && *s && *s != '\n') sfputc(sfstderr, '\t'); } if (*s) sfprintf(sfstderr, " ..."); } } sfprintf(sfstderr, "\n"); handling = 0; signal(sig, SIG_DFL); sigunblock(sig); kill(getpid(), sig); pause(); error(PANIC, "signal not redelivered"); } #endif