da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* Copyright (c) 1986-2009 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * preprocessor control directive support
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "pplib.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <regex.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TOKOP_DUP (1<<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TOKOP_STRING (1<<1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TOKOP_UNSET (1<<2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct edit
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct edit* next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regex_t re;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct map
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct map* next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regex_t re;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct edit* edit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define RESTORE (COLLECTING|CONDITIONAL|DEFINITION|DIRECTIVE|DISABLE|EOF2NL|HEADER|NOSPACE|NOVERTICAL|PASSEOF|STRIP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * common predicate assertion operations
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * op is DEFINE or UNDEF
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinassert(int op, char* pred, char* args)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct pplist* a;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct ppsymbol* sym;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct pplist* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct pplist* q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!args) switch (op)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case DEFINE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto mark;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case UNDEF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto unmark;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (a = (struct pplist*)hashget(pp.prdtab, pred))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = a;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (streq(q->value, args))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (op == DEFINE) return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = q->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p) p->next = q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else a = q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = q->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (op == UNDEF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unmark:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hashput(pp.prdtab, pred, a);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sym = ppsymref(pp.symtab, pred))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->flags &= ~SYM_PREDICATE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (op == DEFINE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = newof(0, struct pplist, 1, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->next = a;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->value = strdup(args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hashput(pp.prdtab, NiL, p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mark:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.state & COMPILE) && pp.truncate) return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sym = ppsymset(pp.symtab, pred))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->flags |= SYM_PREDICATE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * tokenize string ppop()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * op PP_* op
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * name option name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * s string of option values
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * n option sense
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * flags TOKOP_* flags
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintokop(int op, char* name, register char* s, register int n, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags & TOKOP_UNSET) && !n) error(2, "%s: option cannot be unset", name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!s) ppop(op, s, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (flags & TOKOP_STRING)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSH_LINE(s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = pplex();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!c) break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c != ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(op, (flags & TOKOP_DUP) ? strdup(pp.token) : pp.token, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin POP_LINE();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*s == ' ') s++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (t = s; *t && *t != ' '; t++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*t) *t++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s) ppop(op, (flags & TOKOP_DUP) ? strdup(s) : s, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (s = t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return symbol pointer for next token macro (re)definition
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic struct ppsymbol*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinmacsym(int tok)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct ppsymbol* sym;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (tok != T_ID)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: invalid macro name", pptokstr(pp.token, 0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym = pprefmac(pp.token, REF_CREATE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((sym->flags & SYM_FINAL) && (pp.mode & HOSTED)) return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sym->flags & (SYM_ACTIVE|SYM_READONLY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pp.option & ALLPOSSIBLE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: macro is %s", sym->name, (sym->flags & SYM_READONLY) ? "readonly" : "active");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!sym->macro) sym->macro = newof(0, struct ppmacro, 1, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return sym;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * get one space canonical pplex() line, sans '\n', and place in p
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * x is max+1 pos in p
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 0 returned if line too large
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * otherwise end of p ('\0') returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chingetline(register char* p, char* x, int disable)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long restore;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin restore = pp.state & (NOSPACE|STRIP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~(NEWLINE|NOSPACE|STRIP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= EOF2NL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((c = pplex()) != '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (disable)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*ignore*/;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (disable == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin disable = (c == T_ID && streq(pp.token, pp.pass)) ? 2 : 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin disable = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == ':')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= DISABLE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = pp.token;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*p = *s++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (++p >= x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p > b && *(p - 1) == ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p >= x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin done:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~(NOSPACE|STRIP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= restore;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * regex error handler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinregfatal(regex_t* p, int level, int code)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char buf[128];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regerror(code, p, buf, sizeof(buf));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regfree(p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(level, "regular expression: %s", buf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * process a single directive line
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinppcontrol(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct ppmacro* mac;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct ppsymbol* sym;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct edit* edit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct map* map;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppfile* fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int o;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int directive;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long restore;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct pptuple* rp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct pptuple* tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* v;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int emitted;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin union
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct map* best;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppinstk* inp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct pplist* list;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* string;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ppsymbol* symbol;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PPLINESYNC linesync;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } var;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char __va_args__[] = "__VA_ARGS__";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int i0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int i1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int i2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int i3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int i4;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static long n1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static long n2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static long n3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char* p0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char* p1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char* p2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char* p3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char* p4;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char* p5;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char* p6;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static struct ppmacro old;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char* formargs[MAXFORMALS];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACKEYARGS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char* formvals[MAXFORMALS];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin emitted = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.state & SKIPCONTROL) pp.level--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin restore = (pp.state & RESTORE)|NEWLINE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.state & PASSTHROUGH) restore |= DISABLE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else restore &= ~DISABLE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~(NEWLINE|RESTORE|SKIPCONTROL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= DIRECTIVE|DISABLE|EOF2NL|NOSPACE|NOVERTICAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if COMPATIBLE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.state & (COMPATIBILITY|STRICT)) == COMPATIBILITY || (pp.mode & HOSTED)) pp.state &= ~NOVERTICAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.mode & HOSTED) pp.state &= ~NOVERTICAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c = pplex())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_DECIMAL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_OCTAL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.state & STRICT) && !(pp.mode & (HOSTED|RELAX)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "# <line> [ \"<file>\" [ <type> ] ]: non-standard directive");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin directive = INCLUDE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto linesync;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_ID:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (directive = (int)hashref(pp.dirtab, pp.token))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ELIF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else_if:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.option & ALLPOSSIBLE) && !pp.in->prev->prev)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.control <= pp.in->control)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "no matching #%s for #%s", dirname(IF), dirname(ELIF));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.control == (pp.in->control + 1)) pp.in->flags |= IN_noguard;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*pp.control & HADELSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "invalid #%s after #%s", dirname(ELIF), dirname(ELSE));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp.control |= SKIP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*pp.control & KEPT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp.control |= SKIP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (directive == IFDEF || directive == IFNDEF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp.control &= ~SKIP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto else_ifdef;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin conditional:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ppexpr(&i1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp.control &= ~SKIP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp.control |= KEPT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else *pp.control |= SKIP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = (pp.state & NEWLINE) ? '\n' : ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ELSE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.option & ALLPOSSIBLE) && !pp.in->prev->prev)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.option & ELSEIF) && (c = pplex()) == T_ID && ((n = (int)hashref(pp.dirtab, pp.token)) == IF || n == IFDEF || n == IFNDEF))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "#%s %s is non-standard -- use #%s", dirname(directive), dirname(n), dirname(ELIF));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin directive = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto else_if;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.control <= pp.in->control) error(2, "no matching #%s for #%s", dirname(IF), dirname(ELSE));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.control == (pp.in->control + 1)) pp.in->flags |= IN_noguard;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(*pp.control & KEPT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp.control &= ~SKIP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp.control |= HADELSE|KEPT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*pp.control & HADELSE) error(2, "more than one #%s for #%s", dirname(ELSE), dirname(IF));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp.control |= HADELSE|SKIP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto enddirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ENDIF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.option & ALLPOSSIBLE) && !pp.in->prev->prev)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.control <= pp.in->control) error(2, "no matching #%s for #%s", dirname(IF), dirname(ENDIF));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (--pp.control == pp.in->control && pp.in->symbol)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.in->flags & IN_endguard) pp.in->flags |= IN_noguard;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.in->flags &= ~IN_tokens;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.in->flags |= IN_endguard;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto enddirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case IF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case IFDEF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case IFNDEF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.option & ALLPOSSIBLE) && !pp.in->prev->prev)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pushcontrol();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SETIFBLOCK(pp.control);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*pp.control & SKIP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp.control |= KEPT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (directive == IF) goto conditional;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else_ifdef:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = pplex()) == T_ID)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym = pprefmac(pp.token, REF_IF);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (directive == IFNDEF && pp.control == pp.in->control + 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.in->flags & (IN_defguard|IN_endguard))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.in->flags |= IN_noguard;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.in->flags |= IN_defguard;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pp.in->flags & IN_tokens))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.in->symbol = sym ? sym : pprefmac(pp.token, REF_CREATE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pp.mode & HOSTED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "%s: invalid macro name", pptokstr(pp.token, 0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp.control |= ((sym != 0) == (directive == IFDEF)) ? KEPT : SKIP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto enddirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case INCLUDE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*pp.control & SKIP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= HEADER;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = pplex();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~HEADER;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~DISABLE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= HEADER|STRIP;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pp.in->flags |= IN_noguard;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c = pplex())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_STRING:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = pp.token;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do pp.token = pp.toknxt; while ((c = pplex()) == T_STRING);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp.token = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.token = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_HEADER:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin header:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*pp.token)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "#%s: null file name", dirname(INCLUDE));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*pp.token == '/' && !(pp.mode & (HOSTED|RELAX)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "#%s: reference to %s is not portable", dirname(INCLUDE), pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = ppsearch(pp.token, c, SEARCH_INCLUDE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '<':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * HEADEREXPAND|HEADEREXPANDALL gets us here
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p = pp.hdrbuf) && !(p = pp.hdrbuf = newof(0, char, MAXTOKEN, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(3, "out of space");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((c = pplex()) && c != '>')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = p + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin STRCOPY(p, pp.token, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p == v && *(p - 1) == ' ' && pp.in->type != IN_MACRO)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(pp.token, pp.hdrbuf, p - pp.hdrbuf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = T_HEADER;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto header;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "#%s: \"...\" or <...> argument expected", dirname(INCLUDE));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto enddirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regmatch_t match[10];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*UNDENT*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = pp.valbuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = '#';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin STRCOPY(p, pp.token, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p0 = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.mode |= EXPOSE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= HEADER;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p6 = getline(p, &pp.valbuf[MAXTOKEN], 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~HEADER;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.mode &= ~EXPOSE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!p6)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p0 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: directive too long", pp.valbuf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p1 = p2 = p3 = p4 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p5 = *p ? p + 1 : 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin checkmap:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i0 = *p0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = pp.valbuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.best = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (map = (struct map*)pp.maps; map; map = map->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(i1 = regexec(&map->re, p, elementsof(match), match, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = match[0].rm_eo - match[0].rm_so) > n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.best = map;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (i1 != REG_NOMATCH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regfatal(&map->re, 3, i1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (map = var.best)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.state & (STRICT|WARN)) && !(pp.mode & (HOSTED|RELAX)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p0 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pp.state & WARN) || strcmp(p + 1, dirname(PRAGMA)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "%s: non-standard directive", p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p0 = i0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(*pp.control & SKIP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (edit = map->edit; edit; edit = edit->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(i0 = regexec(&edit->re, p, elementsof(match), match, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i0 = regsubexec(&edit->re, p, elementsof(match), match))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regfatal(&edit->re, 3, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = edit->re.re_sub->re_buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (edit->re.re_sub->re_flags & REG_SUB_STOP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (i0 != REG_NOMATCH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regfatal(&edit->re, 3, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n && *p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p1 = s = oldof(0, char, 0, strlen(p) + 32);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*s = *p++) s++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin debug((-4, "map: %s", p1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s++ = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSH_RESCAN(p1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin directive = LINE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto donedirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (directive != PRAGMA && (!(*pp.control & SKIP) || !(pp.mode & (HOSTED|RELAX))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p0 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "%s: unknown directive", pptokstr(pp.valbuf, 0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p0 = i0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pass:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(*pp.control & SKIP) && pp.pragma && !(pp.state & NOTEXT) && (directive == PRAGMA || !(pp.mode & INIT)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p0 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p2) *p2 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p4)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p4 == p5)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p5 = strcpy(pp.tmpbuf, p5);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p = strchr(p5, MARK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*s++ = *p++) == MARK && *p == MARK) p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p4 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p = (char*)memchr(pp.valbuf + 1, MARK, p6 - pp.valbuf - 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (p < p6) switch (*s++ = *p++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case MARK:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*pp.pragma)(pp.valbuf + 1, p1, p3, p5, (pp.state & COMPILE) || (pp.mode & INIT) != 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin emitted = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto donedirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*INDENT*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*pp.control & SKIP) goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (directive)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACDEF
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ENDMAC:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = pplex();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "no matching #%s for #%s", dirname(MACDEF), dirname(ENDMAC));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto enddirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACDEF
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case MACDEF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.state & STRICT) && !(pp.mode & (HOSTED|RELAX)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "#%s: non-standard directive", pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case DEFINE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n2 = error_info.line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = pplex()) == '#' && directive == DEFINE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto assertion;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '<')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = pplex();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(sym = macsym(c)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.truncate)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppfsm(FSM_MACRO, pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac = sym->macro;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.option & ALLPOSSIBLE) && !pp.in->prev->prev && mac->value)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto tuple;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin old = *mac;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i0 = sym->flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->flags &= ~(SYM_BUILTIN|SYM_EMPTY|SYM_FINAL|SYM_FUNCTION|SYM_INIT|SYM_INITIAL|SYM_MULTILINE|SYM_NOEXPAND|SYM_PREDEFINED|SYM_REDEFINE|SYM_VARIADIC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACDEF
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (directive == MACDEF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->flags |= SYM_MULTILINE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->arity = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->formals = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->value = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= DEFINITION|NOEXPAND;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c = pplex())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '(':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->flags |= SYM_FUNCTION;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACKEYARGS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.option & KEYARGS)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 2 * MAXTOKEN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = mac->formals = oldof(0, char, 0, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = pplex()) == T_ID) for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mac->arity < MAXFORMALS)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mac->arity) p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin formargs[mac->arity] = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin STRAPP(p, pp.token, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin formvals[mac->arity++] = p1 = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mac->arity == 1) *p++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else error(2, "%s: formal argument %s ignored", sym->name, pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c = pplex())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '=':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = pplex();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ',':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto endformals;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p0 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto endformals;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '(':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p0++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ')':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!p0--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p > formvals[mac->arity - 1] && *(p - 1) == ' ') *--p = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto endformals;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ',':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!p0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p > formvals[mac->arity - 1] && *(p - 1) == ' ') *--p = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto nextformal;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ' ':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p > formvals[mac->arity - 1] && *(p - 1) == ' ') continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin STRCOPY(p, pp.token, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p > &mac->formals[n - MAXTOKEN] && (s = newof(mac->formals, char, n += MAXTOKEN, 0)) != mac->formals)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n1 = s - mac->formals;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (n = 0; n < mac->arity; n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin formargs[n] += n1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin formvals[n] += n1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = p - mac->formals;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->formals = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = mac->formals + c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = pplex();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nextformal:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = pplex()) != T_ID)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ',';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin endformals: /*NOP*/;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = mac->formals = oldof(0, char, 0, MAXFORMALS * (MAXID + 1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = pplex();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if COMPATIBLE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.state & COMPATIBILITY) && c == ',')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.state & WARN) && !(pp.mode & HOSTED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "%s: macro formal argument expected", sym->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((c = pplex()) == ',');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == T_VARIADIC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sym->flags & SYM_VARIADIC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: %s: duplicate macro formal argument", sym->name, pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->flags |= SYM_VARIADIC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = __va_args__;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c == T_ID)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = pp.token;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sym->flags & SYM_VARIADIC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: %s: macro formal argument cannot follow ...", sym->name, v);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (streq(v, __va_args__))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: %s: invalid macro formal argument", sym->name, v);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mac->arity < MAXFORMALS)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (n = 0; n < mac->arity; n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (streq(formargs[n], v))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: %s: duplicate macro formal argument", sym->name, v);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin formargs[mac->arity++] = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin STRAPP(p, v, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: %s: macro formal argument ignored", sym->name, v);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = pplex()) == ',')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = pplex();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if COMPATIBLE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.state & COMPATIBILITY) && c == ',')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.state & WARN) && !(pp.mode & HOSTED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "%s: macro formal argument expected", sym->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((c = pplex()) == ',');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (c != T_VARIADIC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sym->flags & SYM_VARIADIC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: %s: duplicate macro formal argument", sym->name, pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->flags |= SYM_VARIADIC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = pplex();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mac->arity && (s = newof(mac->formals, char, p - mac->formals, 0)) != mac->formals)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n1 = s - mac->formals;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (n = 0; n < mac->arity; n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin formargs[n] += n1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->formals = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!mac->arity)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(mac->formals);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->formals = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ')':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACKEYARGS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= NOEXPAND|NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= NOEXPAND;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = pplex();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: invalid macro formal argument list", sym->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mac->formals)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(mac->formals);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->formals = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->arity = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(mac);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->macro = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ' ':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\t':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = pplex();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 2 * MAXTOKEN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACKEYARGS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p1 = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = mac->value = oldof(0, char, 0, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.type = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n1 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACDEF
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i2 = i3 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n3 = pp.state;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.option & PLUSPLUS) && (pp.state & (COMPATIBILITY|TRANSITION)) != COMPATIBILITY)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '+':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '-':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '&':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '|':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '<':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '>':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '=':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin o = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_ID:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (c = 0; c < mac->arity; c++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (streq(formargs[c], pp.token))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if COMPATIBLE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pp.state & COMPATIBILITY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (var.type != TOK_TOKCAT && p > mac->value && *(p - 1) != ' ' && !(pp.option & PRESERVE)) *p++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = MARK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if COMPATIBLE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.state & (COMPATIBILITY|TRANSITION)) == COMPATIBILITY) *p++ = 'C';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = (n1 || var.type == TOK_TOKCAT) ? 'C' : 'A';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = c + ARGOFFSET;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((pp.state & WARN) && !(pp.mode & (HOSTED|RELAX)) && var.type != TOK_TOKCAT && !(var.type & TOK_ID))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s = pp.in->nextchr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while ((c = *s++) && (c == ' ' || c == '\t'));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (c == '\n')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if (c == '*' && *s == ')')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = ')';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if (c == '=' || ppisidig(c) || c == *s || *s == '=')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (o != '.' && o != T_PTRMEM)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((var.type & TOK_ID) || o == ' ' || ppisseparate(o))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin o = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (!((o == 0 || o == '(' || o == ')' || o == '[' || o == ']' || o == ',' || o == '|' || o == ';' || o == '{' || o == '}') && (c == '(' || c == ')' || c == '[' || c == ']' || c == ',' || c == '|' || c == ';' || c == '}' || c == 0)) && !(o == '*' && c == ')'))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error(1, "%s: %s: formal should be parenthesized in macro value (t=%x o=%#c c=%#c)", sym->name, pp.token, var.type, o, c);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.type = TOK_FORMAL|TOK_ID;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '>';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto checkvalue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (var.type == TOK_BUILTIN) switch ((int)hashget(pp.strtab, pp.token))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case V_DEFAULT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case V_EMPTY:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->flags |= SYM_EMPTY;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (pp.hiding && (var.symbol = ppsymref(pp.symtab, pp.token)) && var.symbol->hidden)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (var.inp = pp.in; var.inp->type != IN_FILE && var.inp->prev; var.inp = var.inp->prev);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p += sfsprintf(p, MAXTOKEN, "_%d_%s_hIDe", var.inp->hide, pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.type = TOK_ID;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto checkvalue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.type = TOK_ID;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '#':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.type = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACDEF
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(sym->flags & (SYM_FUNCTION|SYM_MULTILINE))) break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(sym->flags & SYM_FUNCTION)) break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = pplex();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '@')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = pplex();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i4 = 'S';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else i4 = 'Q';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c != T_ID) c = mac->arity;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else for (c = 0; c < mac->arity; c++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (streq(formargs[c], pp.token))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c >= mac->arity)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACDEF
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sym->flags & SYM_MULTILINE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n3 & NEWLINE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~NOEXPAND;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch ((int)hashref(pp.dirtab, pp.token))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ENDMAC:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!i2--) goto gotdefinition;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case INCLUDE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* PARSE HEADER constant */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case MACDEF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i2++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = '#';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if COMPATIBLE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.state & COMPATIBILITY) *p++ = '#';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "# must precede a formal parameter");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p > mac->value && ppisidig(*(p - 1)) && !(pp.option & PRESERVE)) *p++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = MARK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = i4;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = c + ARGOFFSET;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto checkvalue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_TOKCAT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p <= mac->value) error(2, "%s lhs operand omitted", pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*(p - 1) == ' ') p--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (var.type == (TOK_FORMAL|TOK_ID)) *(p - 2) = 'C';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = pplex();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '\n') error(2, "%s rhs operand omitted", pptokchr(T_TOKCAT));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.type = TOK_TOKCAT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '(':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*pp.token == '#')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.type = TOK_BUILTIN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n1++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.type = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n1) n1++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ')':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.type = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n1) n1--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_STRING:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_CHARCONST:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~NOEXPAND;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.type = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (strchr(pp.token, MARK)) pp.state &= ~NOEXPAND;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if COMPATIBLE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*UNDENT*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((sym->flags & SYM_FUNCTION) && (pp.state & (COMPATIBILITY|TRANSITION)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* v;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = pp.token;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*s) goto checkvalue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ppisid(*s))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (ppisid(*++s));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i1 = *s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (c = 0; c < mac->arity; c++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (streq(formargs[c], v))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = MARK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = 'C';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = c + ARGOFFSET;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pp.mode & HOSTED) && (!(pp.state & COMPATIBILITY) || (pp.state & WARN))) switch (*pp.token)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '"':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "use the # operator to \"...\" quote macro arguments");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\'':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "macro arguments should be '...' quoted before substitution");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto quotearg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin STRCOPY2(p, v);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin quotearg:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s = i1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else *p++ = *s++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*INDENT*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACDEF
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sym->flags & SYM_MULTILINE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.state & EOF2NL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= HIDDEN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.hidden++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.type = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!i3++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto checkvalue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= EOF2NL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: missing #%s", sym->name, dirname(ENDMAC));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto gotdefinition;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto gotdefinition;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if COMPATIBLE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ' ':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.state & COMPATIBILITY) var.type = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.option & PRESERVE) break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p > mac->value && *(p - 1) != ' ') *p++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto checkvalue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\t':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (var.type & TOK_ID)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((c = pplex()) == '\t');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == T_ID)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (var.type == (TOK_FORMAL|TOK_ID)) *(p - 2) = 'C';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.type = TOK_TOKCAT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.state & WARN) error(1, "use the ## operator to concatenate macro arguments");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else var.type = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.type = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.option & PRESERVE) break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p > mac->value && *(p - 1) != ' ') *p++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto checkvalue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case MARK:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~NOEXPAND;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.type = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin STRCOPY(p, pp.token, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin checkvalue:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin o = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p > &mac->value[n - MAXTOKEN] && (s = newof(mac->value, char, n += MAXTOKEN, 0)) != mac->value)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = p - mac->value;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->value = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = mac->value + c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACDEF
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n3 = pp.state;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = pplex();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin gotdefinition:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (p > mac->value && *(p - 1) == ' ') p--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p > mac->value && (pp.option & PLUSPLUS) && (pp.state & (COMPATIBILITY|TRANSITION)) != COMPATIBILITY)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (o)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '+':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '-':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '&':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '|':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '<':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '>':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '=':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACKEYARGS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!mac->arity) /* ok */;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (pp.option & KEYARGS)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p0 = mac->formals;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->formkeys = newof(0, struct ppkeyarg, n, p1 - p0 + 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = (char*)&mac->formkeys[mac->arity];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (void)memcpy(s, p0, p1 - p0 + 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(p0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (n = 0; n < mac->arity; n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->formkeys[n].name = s + (formargs[n] - p0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->formkeys[n].value = s + (formvals[n] - p0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (n = 1; n < mac->arity; n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *(formargs[n] - 1) = ',';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (old.value)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((i0 & SYM_FUNCTION) != (sym->flags & SYM_FUNCTION) || old.arity != mac->arity || !streq(old.value, mac->value)) goto redefined;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!old.formals)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mac->formals) goto redefined;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (mac->formals)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACKEYARGS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.option & KEYARGS)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (n = 0; n < mac->arity; n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!streq(mac->formkeys[n].name, old.formkeys[n].name) || !streq(mac->formkeys[n].value, old.formkeys[n].value))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto redefined;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!streq(mac->formals, old.formals)) goto redefined;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACKEYARGS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.option & KEYARGS)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mac->formkeys) free(mac->formkeys);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->formkeys = old.formkeys;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mac->formals) free(mac->formals);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->formals = old.formals;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(mac->value);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->value = old.value;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto benign;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin redefined:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pp.mode & HOSTED) || !(i0 & SYM_INITIAL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "%s redefined", sym->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACKEYARGS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.option & KEYARGS) && mac->formkeys)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(mac->formkeys);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACKEYARGS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pp.option & KEYARGS))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (old.formals) free(old.formals);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(old.value);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!pp.truncate) ppfsm(FSM_MACRO, sym->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->value = newof(mac->value, char, (mac->size = p - mac->value) + 1, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.option & (DEFINITIONS|PREDEFINITIONS|REGUARD)) && !sym->hidden && !(sym->flags & SYM_MULTILINE) && ((pp.option & PREDEFINITIONS) || !(pp.mode & INIT)) && ((pp.option & (DEFINITIONS|PREDEFINITIONS)) || !(pp.state & NOTEXT)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppsync();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppprintf("#%s %s", dirname(DEFINE), sym->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sym->flags & SYM_FUNCTION)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppputchar('(');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mac->formals)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppprintf("%s", mac->formals);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppputchar(')');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((p = mac->value) && *p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppputchar(' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i0 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (n = *p++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n != MARK || (n = *p++) == MARK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppputchar(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i0 = ppisid(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n == 'Q')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppputchar('#');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (i0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppputchar('#');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppputchar('#');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = formargs[*p++ - ARGOFFSET];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((n = *s++) && n != ',')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppputchar(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ppisid(*p) || *p == MARK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppputchar('#');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppputchar('#');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i0 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppcheckout();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin emitted = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin benign:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.mode & BUILTIN) sym->flags |= SYM_BUILTIN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.option & FINAL) sym->flags |= SYM_FINAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.mode & INIT) sym->flags |= SYM_INIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.option & INITIAL) sym->flags |= SYM_INITIAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.state & NOEXPAND) sym->flags |= SYM_NOEXPAND;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.option & PREDEFINED) sym->flags |= SYM_PREDEFINED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.mode & READONLY) sym->flags |= SYM_READONLY;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.macref) (*pp.macref)(sym, error_info.file, n2, mac ? error_info.line - n2 + 1 : REF_UNDEF, mac ? strsum(mac->value, (long)mac->arity) : 0L);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin assertion:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = pplex();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.state & STRICT) && !(pp.mode & (HOSTED|RELAX)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "#%s #%s: assertions are non-standard", dirname(directive), pptokstr(pp.token, 0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c != T_ID)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: invalid predicate name", pptokstr(pp.token, 0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch ((int)hashref(pp.strtab, pp.token))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_DEFINED:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_EXISTS:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_STRCMP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s is a builtin predicate", pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_SIZEOF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s cannot be a predicate", pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(pp.tmpbuf, pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (pppredargs())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_ID:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_STRING:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin assert(directive, pp.tmpbuf, pp.args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin assert(directive, pp.tmpbuf, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "invalid predicate argument list");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tuple:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= DEFINITION|NOEXPAND|NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp = mac->tuple;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!tp && !mac->value)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppfsm(FSM_MACRO, sym->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((c = pplex()) && c != '>' && c != '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; tp; tp = tp->nomatch)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (streq(tp->token, pp.token))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!tp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(tp = newof(0, struct pptuple, 1, strlen(pp.token))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(3, "out of space");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(tp->token, pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (rp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp->nomatch = rp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rp->nomatch = tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp->nomatch = mac->tuple;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->tuple = tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rp = tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp = tp->match;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!rp || c != '>')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: > omitted in tuple macro definition", sym->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 2 * MAXTOKEN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = v = oldof(0, char, 0, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((c = pplex()) && c != '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p > v || c != ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin STRCOPY(p, pp.token, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p > &v[n - MAXTOKEN] && (s = newof(v, char, n += MAXTOKEN, 0)) != v)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = p - v;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = v + c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (p > v && *(p - 1) == ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = p - v;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp = newof(0, struct pptuple, 1, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(tp->token, v);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp->match = rp->match;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rp->match = tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto benign;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case WARNING:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.state & STRICT) && !(pp.mode & (HOSTED|RELAX)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "#%s: non-standard directive", pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ERROR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~DISABLE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = pp.tmpbuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((c = pplex()) != '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p + strlen(pp.token) < &pp.tmpbuf[MAXTOKEN])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin STRCOPY(p, pp.token, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = *pp.tmpbuf ? pp.tmpbuf : ((directive == WARNING) ? "user warning" : "user error");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (directive == WARNING) ? 1 : 3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(n, "%s", p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case LET:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n2 = error_info.line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.state & STRICT) && !(pp.mode & (HOSTED|RELAX)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "#%s: non-standard directive", pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(sym = macsym(c = pplex()))) goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = pplex()) != '=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: = expected", sym->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->flags &= ~(SYM_BUILTIN|SYM_FUNCTION|SYM_MULTILINE|SYM_PREDEFINED|SYM_VARIADIC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac = sym->macro;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->arity = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mac->value)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(sym->flags & SYM_REDEFINE) && !sym->hidden)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "%s: redefined", sym->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MACKEYARGS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.option & KEYARGS) && mac->formkeys) free(mac->formkeys);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(mac->formals);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->formals = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = strlen(mac->value) + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppfsm(FSM_MACRO, sym->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n1 = ppexpr(&i1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i1) c = sfsprintf(pp.tmpbuf, MAXTOKEN, "%luU", n1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else c = sfsprintf(pp.tmpbuf, MAXTOKEN, "%ld", n1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n < ++c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mac->value) free(mac->value);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac->value = oldof(0, char, 0, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(mac->value, pp.tmpbuf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->flags |= SYM_REDEFINE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = (pp.state & NEWLINE) ? '\n' : ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto benign;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case LINE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~DISABLE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = pplex()) == '#')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = pplex();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin directive = INCLUDE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c != T_DECIMAL && c != T_OCTAL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "#%s: line number expected", dirname(LINE));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin linesync:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = error_info.line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line = strtol(pp.token, NiL, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (error_info.line == 0 && directive == LINE && (pp.state & STRICT) && !(pp.mode & HOSTED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "#%s: line number should be > 0", dirname(LINE));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~DISABLE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= STRIP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c = pplex())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_STRING:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = error_info.file;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (*(p = pp.token))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pathcanon(p, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp = ppsetfile(p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.file = fp->name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (error_info.line == 1)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ppmultiple(fp, INC_IGNORE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c = pplex())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_DECIMAL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_OCTAL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (directive == LINE && (pp.state & STRICT) && !(pp.mode & (HOSTED|RELAX)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "#%s: integer file type argument is non-standard", dirname(LINE));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "#%s: integer file type argument expected", dirname(LINE));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (directive == LINE) pp.in->flags &= ~IN_ignoreline;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (pp.incref)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (error_info.file != s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*pp.token)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case PP_sync_push:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.insert) (*pp.incref)(s, error_info.file, n, PP_SYNC_INSERT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else (*pp.incref)(s, error_info.file, n, PP_SYNC_PUSH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case PP_sync_pop:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.insert) (*pp.incref)(s, error_info.file, n, PP_SYNC_INSERT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else (*pp.incref)(s, error_info.file, n - 1, PP_SYNC_POP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case PP_sync_ignore:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.insert) (*pp.incref)(s, error_info.file, n, PP_SYNC_INSERT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*pp.incref)(s, error_info.file, n, PP_SYNC_IGNORE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.file = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp == pp.insert)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.insert = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (error_info.line == 1 && !pp.insert)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*pp.incref)(s, error_info.file, n, PP_SYNC_PUSH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!pp.insert) pp.insert = ppgetfile(s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*pp.incref)(s, error_info.file, n, PP_SYNC_INSERT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "#%s: \"file-name\" expected", dirname(LINE));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (directive == LINE && (pp.in->flags & IN_ignoreline))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line = n + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.hidden = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~HIDDEN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.linesync)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if CATSTRINGS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.state & JOINING) pp.state |= HIDDEN|SYNCLINE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = pp.lineid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = pp.flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (directive == LINE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.flags &= ~PP_linetype;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.macref) pp.lineid = dirname(LINE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*pp.linesync)(error_info.line, error_info.file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.flags = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.lineid = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin directive = LINE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case PRAGMA:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * #pragma [STDC] [pass:] [no]option [arg ...]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * pragma args are not expanded by default
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if STDC is present then it is silently passed on
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if pass is pp.pass then the option is used
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and verified but is not passed on
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if pass is omitted then the option is passed on
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * otherwise if pass is non-null and not pp.pass then
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the option is passed on but not used
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if the line does not match this form then
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * it is passed on unchanged
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * #directive pass: option [...]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * ^ ^ ^ ^ ^ ^ ^ ^
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * pp.valbuf p0 p1 p2 p3 p4 p5 p6
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * p? 0 if component omitted
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * i0 0 if ``no''option
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = pp.valbuf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = '#';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin STRCOPY(p, pp.token, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p0 = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.option & PRAGMAEXPAND)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~DISABLE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p6 = getline(p, &pp.valbuf[MAXTOKEN], !!(pp.option & PRAGMAEXPAND))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p0 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: directive too long", pp.valbuf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p1 = ++p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (ppisid(*p))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p == p1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p5 = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p4 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p3 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p2 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p1 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*p != ':')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p5 = *p ? p + (*p == ' ') : 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p4 = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p3 = p1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p2 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p1 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p2 = p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p3 = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (ppisid(*p))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p == p3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p4 = p1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p3 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p2 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p1 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p4 = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p5 = *p4 ? p4 + (*p4 == ' ') : 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!p1 && p3 && (p4 - p3) == 4 && strneq(p3, "STDC", 4))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto pass;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if ((pp.state & WARN) && (pp.mode & (HOSTED|RELAX|PEDANTIC)) == PEDANTIC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "#%s: non-standard directive", dirname(PRAGMA));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i0 = !p3 || *p3 != 'n' || *(p3 + 1) != 'o';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!p3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto checkmap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p2 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = streq(p1, pp.pass);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p2 = ':';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto checkmap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i2 = *p4;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p4 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (((i1 = (int)hashref(pp.strtab, p3 + (i0 ? 0 : 2))) < 1 || i1 > X_last_option) && (i0 || (i1 = (int)hashref(pp.strtab, p3)) > X_last_option))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i1 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.state & (COMPATIBILITY|STRICT)) == STRICT && !(pp.mode & (HOSTED|RELAX)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.optflags[i1] & OPT_GLOBAL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto donedirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n || (pp.mode & WARN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "#%s: non-standard directive ignored", dirname(PRAGMA));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i1 = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pp.optflags[i1] & OPT_GLOBAL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p4 = i2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto checkmap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pp.optflags[i1] & OPT_PASS))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!i1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: unknown option", p1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((pp.state & STRICT) && !(pp.mode & (HOSTED|RELAX)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "%s: non-standard option", p1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = p5;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (i1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_ALLMULTIPLE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_MULTIPLE, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_ALLPOSSIBLE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(ALLPOSSIBLE, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_BUILTIN:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setmode(BUILTIN, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_CATLITERAL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setmode(CATLITERAL, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.mode & CATLITERAL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(STRINGSPLIT, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_CDIR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tokop(PP_CDIR, p3, p, i0, TOKOP_UNSET|TOKOP_STRING|TOKOP_DUP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_CHECKPOINT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if CHECKPOINT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppload(p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(3, "%s: preprocessor not compiled with checkpoint enabled", p3);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_CHOP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tokop(PP_CHOP, p3, p, i0, TOKOP_UNSET|TOKOP_STRING);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_COMPATIBILITY:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_COMPATIBILITY, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_DEBUG:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.trace = i0 ? (p ? -strtol(p, NiL, 0) : -1) : 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_ELSEIF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(ELSEIF, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_EXTERNALIZE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setmode(EXTERNALIZE, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_FINAL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(FINAL, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_HEADEREXPAND:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(HEADEREXPAND, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_HEADEREXPANDALL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(HEADEREXPANDALL, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_HIDE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_NOTE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSH_LINE(p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* UNDENT...*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (c = pplex())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c != T_ID) error(1, "%s: %s: identifier expected", p3, pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (sym = ppsymset(pp.symtab, pp.token))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i1 == X_NOTE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->flags &= ~SYM_NOTICED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppfsm(FSM_MACRO, sym->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (i0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!sym->hidden && !(sym->hidden = newof(0, struct pphide, 1, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(3, "out of space");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!sym->macro)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppfsm(FSM_MACRO, sym->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!sym->hidden->level++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.hiding++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sym->macro && !(sym->flags & (SYM_ACTIVE|SYM_READONLY)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->hidden->macro = sym->macro;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->macro = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->hidden->flags = sym->flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->flags &= ~(SYM_BUILTIN|SYM_FUNCTION|SYM_INIT|SYM_MULTILINE|SYM_PREDEFINED|SYM_REDEFINE|SYM_VARIADIC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (sym->hidden)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((mac = sym->macro) && !(sym->flags & (SYM_ACTIVE|SYM_READONLY)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mac->formals) free(mac->formals);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(mac->value);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(mac);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->macro = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->flags &= ~(SYM_BUILTIN|SYM_FUNCTION|SYM_INIT|SYM_MULTILINE|SYM_PREDEFINED|SYM_REDEFINE|SYM_VARIADIC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!--sym->hidden->level)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.hiding--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sym->hidden->macro)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->macro = sym->hidden->macro;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->flags = sym->hidden->flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(sym->hidden);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->hidden = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*...INDENT*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin POP_LINE();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_HOSTDIR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tokop(PP_HOSTDIR, p3, p, i0, TOKOP_UNSET|TOKOP_STRING|TOKOP_DUP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_HOSTED:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setmode(HOSTED, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_HOSTEDTRANSITION:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setmode(HOSTEDTRANSITION, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_ID:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tokop(PP_ID, p3, p, i0, TOKOP_UNSET|TOKOP_STRING);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_IGNORE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tokop(PP_IGNORE, p3, p, i0, TOKOP_UNSET|TOKOP_STRING);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_INCLUDE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tokop(PP_INCLUDE, p3, p, i0, TOKOP_STRING|TOKOP_DUP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_INITIAL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(INITIAL, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_KEYARGS:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_KEYARGS, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_LINE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.linesync) pp.olinesync = pp.linesync;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.linesync = i0 ? pp.olinesync : (PPLINESYNC)0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_LINEBASE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_LINEBASE, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_LINEFILE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_LINEFILE, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_LINEID:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_LINEID, i0 ? p : (char*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_LINETYPE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_LINETYPE, i0 ? (p ? strtol(p, NiL, 0) : 1) : 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_MACREF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i0 && !pp.macref)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_LINETYPE, 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_MACREF, ppmacref);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else error(2, "%s: option cannot be unset", p3);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (s = strchr(p, ' '))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.macref && (s = strchr(p, ' ')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = strtol(s, NiL, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.type = pp.truncate;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.truncate = PPTOKSIZ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*pp.macref)(pprefmac(p, REF_CREATE), error_info.file, error_info.line - (c == REF_NORMAL ? 2 : 1), c, (s = strchr(s, ' ')) ? strtol(s, NiL, 0) : 0L);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.truncate = var.type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line -= 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_MAP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*UNDENT*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * #pragma pp:map [id ...] "/from/[,/to/]" [ "/old/new/[glnu]" ... ]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!i0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: option cannot be unset", p3);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto donedirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!p5)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: address argument expected", p3);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto donedirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSH_LINE(p5);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((c = pplex()) == T_ID)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(pp.tmpbuf, MAXTOKEN, "__%s__", s = pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c = (int)hashget(pp.dirtab, s))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hashput(pp.dirtab, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hashput(pp.dirtab, pp.tmpbuf, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c = (int)hashget(pp.strtab, s))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hashput(pp.strtab, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hashput(pp.strtab, pp.tmpbuf, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c != T_STRING || !*(s = pp.token))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: %s: address argument expected", p3, pptokstr(pp.token, 0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatmap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin map = newof(0, struct map, 1, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * /from/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i0 = regcomp(&map->re, s, REG_AUGMENTED|REG_DELIMITED|REG_LENIENT|REG_NULL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regfatal(&map->re, 3, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*(s += map->re.re_npat))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: invalid characters after pattern: %s ", p3, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatmap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * /old/new/[flags]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin edit = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((c = pplex()) == T_STRING)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*(s = pp.token))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: substitution argument expected", p3);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatmap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (edit)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin edit = edit->next = newof(0, struct edit, 1, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin edit = map->edit = newof(0, struct edit, 1, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(i0 = regcomp(&edit->re, s, REG_AUGMENTED|REG_DELIMITED|REG_LENIENT|REG_NULL)) && !(i0 = regsubcomp(&edit->re, s += edit->re.re_npat, NiL, 0, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s += edit->re.re_npat;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regfatal(&edit->re, 3, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: invalid characters after substitution: %s ", p3, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatmap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: %s: substitution argument expected", p3, pptokstr(pp.token, 0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatmap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin map->next = (struct map*)pp.maps;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.maps = (char*)map;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eatmap:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin POP_LINE();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*INDENT*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_MAPINCLUDE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppmapinclude(NiL, p5);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_MODERN:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(MODERN, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_MULTIPLE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (pp.in->type == IN_FILE || pp.in->type == IN_RESCAN)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ppmultiple(ppsetfile(error_info.file), i0 ? INC_CLEAR : INC_IGNORE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_NATIVE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(NATIVE, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_OPSPACE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppfsm(FSM_OPSPACE, i0 ? p4 : (char*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_PASSTHROUGH:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_PASSTHROUGH, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_PEDANTIC:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_PEDANTIC, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_PLUSCOMMENT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_PLUSCOMMENT, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_PLUSPLUS:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_PLUSPLUS, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_PLUSSPLICE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(PLUSSPLICE, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_PRAGMAEXPAND:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(PRAGMAEXPAND, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_PRAGMAFLAGS:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tokop(PP_PRAGMAFLAGS, p3, p, i0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_PREDEFINED:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(PREDEFINED, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_PREFIX:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(PREFIX, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_PRESERVE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(PRESERVE, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.option & PRESERVE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setmode(CATLITERAL, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_COMPATIBILITY, 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_TRANSITION, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_PLUSCOMMENT, 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_SPACEOUT, 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(STRINGSPAN, 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(STRINGSPLIT, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_HOSTDIR, "-", 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_PROTOTYPED:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * this option doesn't bump the token count
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin directive = ENDIF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if PROTOTYPE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(PROTOTYPED, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "preprocessor not compiled with prototype conversion enabled");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_PROTO:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(NOPROTO, !i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_QUOTE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tokop(PP_QUOTE, p3, p, i0, TOKOP_UNSET|TOKOP_STRING);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_READONLY:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setmode(READONLY, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_REGUARD:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(REGUARD, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_RESERVED:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tokop(PP_RESERVED, p3, p, i0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_SPACEOUT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pp.state & (COMPATIBILITY|COMPILE)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_SPACEOUT, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_SPLICECAT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(SPLICECAT, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_SPLICESPACE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(SPLICESPACE, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_STANDARD:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tokop(PP_STANDARD, p3, p, i0, TOKOP_UNSET|TOKOP_STRING|TOKOP_DUP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_STRICT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_STRICT, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_STRINGSPAN:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(STRINGSPAN, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_STRINGSPLIT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(STRINGSPLIT, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.option & STRINGSPLIT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setmode(CATLITERAL, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_SYSTEM_HEADER:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (i0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.mode |= HOSTED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.flags |= PP_hosted;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.in->flags |= IN_hosted;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.mode &= ~HOSTED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.flags &= ~PP_hosted;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.in->flags &= ~PP_hosted;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_TEST:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_TEST, p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_TEXT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pp.option & KEEPNOTEXT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setstate(NOTEXT, !i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_TRANSITION:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_TRANSITION, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.state & TRANSITION) ppop(PP_COMPATIBILITY, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_TRUNCATE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_TRUNCATE, i0 ? (p ? strtol(p, NiL, 0) : TRUNCLENGTH) : 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_VENDOR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tokop(PP_VENDOR, p3, p, i0, TOKOP_UNSET|TOKOP_STRING|TOKOP_DUP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_VERSION:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(*pp.control & SKIP) && pp.pragma && !(pp.state & NOTEXT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(pp.tmpbuf, MAXTOKEN, "\"%s\"", pp.version);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*pp.pragma)(dirname(PRAGMA), pp.pass, p3, pp.tmpbuf, !n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.linesync && !n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*pp.linesync)(error_info.line, error_info.file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin emitted = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_WARN:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppop(PP_WARN, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_ZEOF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setoption(ZEOF, i0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_INCLUDED:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_NOTICED:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_OPTION:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case X_STATEMENT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(PANIC, "%s: option recognized but not implemented", pp.valbuf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p4 = i2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto checkmap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto donedirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case RENAME:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.state & STRICT) && !(pp.mode & (HOSTED|RELAX)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "#%s: non-standard directive", pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = pplex()) != T_ID)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "%s: invalid macro name", pptokstr(pp.token, 0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(sym = pprefmac(pp.token, REF_DELETE)) || !sym->macro)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sym->flags & (SYM_ACTIVE|SYM_READONLY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pp.option & ALLPOSSIBLE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: macro is %s", sym->name, (sym->flags & SYM_READONLY) ? "readonly" : "active");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = pplex()) != T_ID)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "%s: invalid macro name", pptokstr(pp.token, 0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.symbol = pprefmac(pp.token, REF_CREATE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mac = var.symbol->macro)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (var.symbol->flags & (SYM_ACTIVE|SYM_READONLY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pp.option & ALLPOSSIBLE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: macro is %s", var.symbol->name, (var.symbol->flags & SYM_READONLY) ? "readonly" : "active");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pp.mode & HOSTED) || !(var.symbol->flags & SYM_INITIAL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "%s redefined", var.symbol->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mac->formals) free(mac->formals);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(mac->value);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(mac);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppfsm(FSM_MACRO, var.symbol->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.symbol->flags = sym->flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->flags &= ~(SYM_BUILTIN|SYM_FUNCTION|SYM_INIT|SYM_MULTILINE|SYM_PREDEFINED|SYM_REDEFINE|SYM_VARIADIC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var.symbol->macro = sym->macro;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->macro = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case UNDEF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = pplex()) != T_ID)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "%s: invalid macro name", pptokstr(pp.token, 0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sym = pprefmac(pp.token, REF_DELETE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mac = sym->macro)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sym->flags & (SYM_ACTIVE|SYM_READONLY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pp.option & ALLPOSSIBLE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s: macro is %s", sym->name, (sym->flags & SYM_READONLY) ? "readonly" : "active");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mac->formals) free(mac->formals);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(mac->value);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(mac);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mac = sym->macro = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((pp.option & (DEFINITIONS|PREDEFINITIONS|REGUARD)) && !sym->hidden && !(sym->flags & SYM_MULTILINE) && ((pp.option & PREDEFINITIONS) || !(pp.mode & INIT)) && ((pp.option & (DEFINITIONS|PREDEFINITIONS)) || !(pp.state & NOTEXT)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppsync();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppprintf("#%s %s", dirname(UNDEF), sym->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin emitted = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sym->flags &= ~(SYM_BUILTIN|SYM_FUNCTION|SYM_INIT|SYM_MULTILINE|SYM_PREDEFINED|SYM_REDEFINE|SYM_VARIADIC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n2 = error_info.line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto benign;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else pprefmac(pp.token, REF_UNDEF);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(PANIC, "#%s: directive recognized but not implemented", pp.token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "%s: invalid directive name", pptokstr(pp.token, 0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto eatdirective;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin enddirective:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if COMPATIBLE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c != '\n' && !(pp.state & COMPATIBILITY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c != '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= DISABLE|NOSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((c = pplex()) != '\n' && (pp.mode & (HOSTED|PEDANTIC)) == PEDANTIC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(1, "%s: invalid characters after directive", pptokstr(pp.token, 0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin eatdirective:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c != '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= DISABLE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (pplex() != '\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin donedirective:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _HUH_2002_05_09
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(pp.state & EOF2NL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s in directive", pptokchr(0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state &= ~RESTORE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.mode &= ~RELAX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(*pp.control & SKIP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= restore;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (directive)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case LINE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case INCLUDE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.include)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PUSH_FILE(pp.include, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!pp.vendor && (pp.found->type & TYPE_VENDOR))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.vendor = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.include = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pp.incref)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*pp.incref)(error_info.file, ppgetfile(pp.path)->name, error_info.line, PP_SYNC_IGNORE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (pp.linesync && pp.macref)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.flags |= PP_lineignore;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*pp.linesync)(error_info.line, ppgetfile(pp.path)->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.in->flags |= IN_tokens;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ENDIF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (emitted)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppputchar('\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ppcheckout();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= HIDDEN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.hidden++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.state |= restore|HIDDEN|SKIPCONTROL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.hidden++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.level++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.line++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * grow the pp nesting control stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinppnest(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct ppinstk* ip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int oz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int nz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long adjust;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long* op;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long* np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin oz = pp.constack;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin op = pp.maxcon - oz + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nz = oz * 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = newof(op, long, nz, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (adjust = (np - op))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ip = pp.in;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ip->control)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ip->control += adjust;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (ip = ip->prev);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.control = np + oz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.constack = nz;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp.maxcon = np + nz - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}