summaryrefslogtreecommitdiff
path: root/usr/src/lib/libpp/common/pptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libpp/common/pptrace.c')
-rw-r--r--usr/src/lib/libpp/common/pptrace.c264
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