diff options
Diffstat (limited to 'usr/src/lib/libpp/common/pptrace.c')
-rw-r--r-- | usr/src/lib/libpp/common/pptrace.c | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/usr/src/lib/libpp/common/pptrace.c b/usr/src/lib/libpp/common/pptrace.c new file mode 100644 index 0000000000..d1b1204817 --- /dev/null +++ b/usr/src/lib/libpp/common/pptrace.c @@ -0,0 +1,264 @@ +/*********************************************************************** +* * +* 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 <gsf@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * Glenn Fowler + * AT&T Research + * + * preprocessor library trace and debug support + */ + +#include "pplib.h" +#include "ppfsm.h" + +#include <ctype.h> + +/* + * 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 <sig.h> + +/* + * 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 |