summaryrefslogtreecommitdiff
path: root/usr/src/lib/libpp/common/ppmisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libpp/common/ppmisc.c')
-rw-r--r--usr/src/lib/libpp/common/ppmisc.c242
1 files changed, 242 insertions, 0 deletions
diff --git a/usr/src/lib/libpp/common/ppmisc.c b/usr/src/lib/libpp/common/ppmisc.c
new file mode 100644
index 0000000000..d7b5d3730e
--- /dev/null
+++ b/usr/src/lib/libpp/common/ppmisc.c
@@ -0,0 +1,242 @@
+/***********************************************************************
+* *
+* 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
+ *
+ * miscellaneous preprocessor support
+ */
+
+#include "pplib.h"
+
+/*
+ * macro symbol def|ref
+ */
+
+struct ppsymbol*
+pprefmac(char* name, int ref)
+{
+ register struct ppsymbol* sym;
+
+ if (!(sym = ppsymget(pp.symtab, name)) && (ref <= REF_NORMAL && pp.macref || ref == REF_CREATE || ref == REF_DELETE && (pp.mode & (INIT|READONLY))))
+ {
+ if ((pp.state & COMPILE) && pp.truncate && strlen(name) > pp.truncate)
+ name[pp.truncate] = 0;
+ sym = ppsymset(pp.symtab, NiL);
+ }
+ if (sym && ref <= REF_NORMAL)
+ {
+ if (pp.macref) (*pp.macref)(sym, error_info.file, error_info.line, ref == REF_NORMAL && (pp.state & CONDITIONAL) ? REF_IF : ref, 0L);
+ if (!sym->macro) sym = 0;
+ }
+#if COMPATIBLE
+ if (!(pp.state & COMPATIBILITY))
+#endif
+ if (ref == REF_IF && sym && (sym->flags & SYM_PREDEFINED) && *name != '_' && !(pp.mode & (HOSTED|INACTIVE)))
+ {
+ if (pp.state & STRICT)
+ {
+ error(1, "%s: obsolete predefined symbol reference disabled", name);
+ return(0);
+ }
+ error(1, "%s: obsolete predefined symbol referenced", name);
+ }
+ return(sym);
+}
+
+/*
+ * common predicate assertion operations
+ * op is DEFINE or UNDEF
+ */
+
+void
+ppassert(int op, char* pred, char* args)
+{
+ register struct pplist* a;
+ register struct ppsymbol* sym;
+ register struct pplist* p;
+ register struct pplist* q;
+
+ if (!args) switch (op)
+ {
+ case DEFINE:
+ goto mark;
+ case UNDEF:
+ a = 0;
+ goto unmark;
+ }
+ if (a = (struct pplist*)hashget(pp.prdtab, pred))
+ {
+ p = 0;
+ q = a;
+ while (q)
+ {
+ if (streq(q->value, args))
+ {
+ if (op == DEFINE) return;
+ q = q->next;
+ if (p) p->next = q;
+ else a = q;
+ }
+ else
+ {
+ p = q;
+ q = q->next;
+ }
+ }
+ if (op == UNDEF)
+ {
+ unmark:
+ hashput(pp.prdtab, pred, a);
+ if (sym = ppsymref(pp.symtab, pred))
+ sym->flags &= ~SYM_PREDICATE;
+ return;
+ }
+ }
+ if (op == DEFINE)
+ {
+ p = newof(0, struct pplist, 1, 0);
+ p->next = a;
+ p->value = strdup(args);
+ hashput(pp.prdtab, NiL, p);
+ mark:
+ if ((pp.state & COMPILE) && pp.truncate) return;
+ if (sym = ppsymset(pp.symtab, pred))
+ sym->flags |= SYM_PREDICATE;
+ }
+}
+
+/*
+ * parse a predicate argument list
+ * the args are placed in pp.args
+ * the first non-space/paren argument token type is returned
+ * forms:
+ *
+ * predicate <identifier> type=T_ID
+ * predicate ( <identifier> ) type=T_ID
+ * predicate ( ) type=0
+ * predicate ( <balanced-paren-list> ) type=T_STRING
+ * otherwise type=<other>
+ */
+
+int
+pppredargs(void)
+{
+ register int c;
+ register int n;
+ register int type;
+ char* pptoken;
+
+ pptoken = pp.token;
+ pp.token = pp.args;
+ switch (type = pplex())
+ {
+ case '(':
+ type = 0;
+ n = 1;
+ pp.state |= HEADER;
+ pp.state &= ~STRIP;
+ c = pplex();
+ pp.state &= ~NOSPACE;
+ for (;;)
+ {
+ switch (c)
+ {
+ case '(':
+ n++;
+ break;
+ case '\n':
+ ungetchr(c);
+ error(2, "missing %d )%s in predicate argument list", n, n == 1 ? "" : "'s");
+ type = 0;
+ goto done;
+ case ')':
+ if (!--n) goto done;
+ break;
+ }
+ pp.token = pp.toknxt;
+ if (c != ' ')
+ {
+ if (type) type = T_STRING;
+ else type = (c == T_ID) ? T_ID : T_STRING;
+ }
+ c = pplex();
+ }
+ done:
+ pp.state &= ~HEADER;
+ pp.state |= NOSPACE|STRIP;
+ if (pp.token > pp.args && *(pp.token - 1) == ' ') pp.token--;
+ *pp.token = 0;
+ break;
+ case '\n':
+ ungetchr('\n');
+ type = 0;
+ break;
+ }
+ pp.token = pptoken;
+ return(type);
+}
+
+/*
+ * sync output line number
+ */
+
+int
+ppsync(void)
+{
+ long m;
+
+ if ((pp.state & (ADD|HIDDEN)))
+ {
+ if (pp.state & ADD)
+ {
+ pp.state &= ~ADD;
+ m = pp.addp - pp.addbuf;
+ pp.addp = pp.addbuf;
+ ppprintf("%-.*s", m, pp.addbuf);
+ }
+ if (pp.linesync)
+ {
+ if ((pp.state & SYNCLINE) || pp.hidden >= MAXHIDDEN)
+ {
+ pp.hidden = 0;
+ pp.state &= ~(HIDDEN|SYNCLINE);
+ if (error_info.line)
+ (*pp.linesync)(error_info.line, error_info.file);
+ }
+ else
+ {
+ m = pp.hidden;
+ pp.hidden = 0;
+ pp.state &= ~HIDDEN;
+ while (m-- > 0)
+ ppputchar('\n');
+ }
+ }
+ else
+ {
+ pp.hidden = 0;
+ pp.state &= ~HIDDEN;
+ ppputchar('\n');
+ }
+ }
+ return 0;
+}