/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1986-2011 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* Glenn Fowler
* AT&T Research
*
* preprocessor library control interface
*/
#include "pplib.h"
#include "pptab.h"
#include <ls.h>
/*
* set option value
* initialization files have lowest precedence
*/
int
{
long* r;
{
debug((-7, "set %s %s skipped -- readonly", p == &pp.state ? "state" : p == &pp.mode ? "mode" : "option", p == &pp.state ? ppstatestr(*r) : p == &pp.mode ? ppmodestr(*r) : ppoptionstr(*r)));
return 0;
}
if (!pp.initialized && (!(pp.mode & INIT) || !(pp.mode & BUILTIN)) && (p != &pp.mode || !(op & BUILTIN)) && (p != &pp.option || !(op & PREDEFINED)))
{
*r |= op;
debug((-7, "set %s %s readonly", p == &pp.state ? "state" : p == &pp.mode ? "mode" : "option", p == &pp.state ? ppstatestr(*r) : p == &pp.mode ? ppmodestr(*r) : ppoptionstr(*r)));
}
if (val)
*p |= op;
else
*p &= ~op;
debug((-7, "set %s %s", p == &pp.state ? "state" : p == &pp.mode ? "mode" : "option", p == &pp.state ? ppstatestr(*r) : p == &pp.mode ? ppmodestr(*r) : ppoptionstr(*r)));
return 1;
}
/*
* initialize hash table with keywords from key
*/
static void
{
register char* s;
{
if (!ppisid(*s))
s++;
}
}
/*
* return ppkeyword table name given value
*/
char*
{
register char* s;
register struct ppkeyword* p;
if (dir && ppiskey(directives, value, p) || !dir && (ppiskey(options, value, p) || ppiskey(predicates, value, p) || ppiskey(variables, value, p)))
{
return s + !ppisid(*s);
}
#if DEBUG
#endif
return "UNKNOWN";
}
/*
* add to the include maps
*/
void
{
register int c;
int fd;
int flags;
int index;
int token;
char* t;
char* old_file;
long old_state;
if (s)
else if (file)
{
if (*file == '-')
{
if (!error_info.file)
{
return;
}
c = *++file;
for (;;)
{
{
s = t;
break;
}
else if (*s == c)
break;
s--;
}
}
return;
}
else
return;
#if CATSTRINGS
#else
#endif
flags = INC_MAPALL;
for (;;)
{
{
case 0:
case T_STRING:
case T_HEADER:
if (fp)
{
{
break;
}
}
if (!token)
break;
if (mp)
{
else
}
else
continue;
case '=':
fp = 0;
continue;
case '\n':
continue;
case T_ID:
{
flags = INC_MAPALL;
continue;
}
{
continue;
}
{
continue;
}
/*FALLTHROUGH*/
default:
break;
}
break;
}
}
/*
* return non-0 if file is identical to fd
*/
static int
{
struct stat a;
struct stat b;
}
/*
* compare up to pp.truncate chars
*
* NOTE: __STD* and symbols containing ' ' are not truncated
*/
static int
trunccomp(register char* a, register char* b)
{
}
/*
* hash up to pp.truncate chars
*
* NOTE: __STD* and symbols containing ' ' are not truncated
*/
static unsigned int
trunchash(char* a)
{
int n;
return memhash(a, (n = strlen(a)) > pp.truncate && !strchr(a, ' ') && !strneq(a, "__STD", 5) ? pp.truncate : n);
}
#if DEBUG & TRACE_debug
/*
* append context to debug trace
*/
static int
{
static int state;
{
}
return 1;
}
#endif
/*
* reset include guard
*/
static int
{
return 0;
}
/*
* reset macro definition
*/
static void
undefine(void* p)
{
if (mac)
{
}
}
/*
* return non-zero if its ok to ppop(op)
*/
static int
{
long n;
long* r;
n = 1L << op;
{
return 0;
}
{
*r |= n;
}
else
return 1;
}
/*
* pp operations
*
* NOTE: PP_INIT must be done before the first pplex() call
* PP_DONE must be done after the last pplex() call
* PP_INIT-PP_DONE must be done for each new PP_INPUT
*/
void
{
register char* p;
register char* s;
int c;
long n;
long* r;
char* t;
static int initialized;
switch (op)
{
case PP_ASSERT:
case PP_DEFINE:
case PP_DIRECTIVE:
case PP_OPTION:
case PP_READ:
case PP_UNDEF:
if (pp.initialized)
goto before;
{
else
}
break;
case PP_BUILTIN:
break;
case PP_CDIR:
if (!p)
pp.c = c;
else if (streq(p, "-"))
{
pp.c = c;
dp->c = c;
}
else if (!pp.c)
{
pp.c = c;
else
{
{
pp.c = 1;
}
if (!pp.c)
{
}
}
}
break;
case PP_CHOP:
{
c = strlen(p);
c = *p++;
while (*p && *p != c)
*s++ = *p++;
*s++ = '/';
*s++ = 0;
if (*p && *++p && *p != c)
{
while (*p && *p != c)
*s++ = *p++;
*s++ = '/';
}
*s = 0;
}
break;
case PP_COMMENT:
else
break;
case PP_COMPATIBILITY:
{
#if COMPATIBLE
if (pp.initialized)
#else
#endif
else
}
break;
case PP_COMPILE:
if (pp.initialized)
goto before;
{
n = SYM_LEX;
switch (*s)
{
case '-':
s++;
break;
case '+':
s++;
break;
/*FALLTHROUGH*/
default:
n |= SYM_KEYWORD;
break;
}
{
}
}
break;
case PP_DEBUG:
break;
case PP_DEFAULT:
p = strdup(p);
break;
case PP_DONE:
#if CHECKPOINT
ppdump();
#endif
{
else
}
{
ppputchar('\n');
ppflushout();
}
error_info.file = 0;
break;
case PP_DUMP:
#if !CHECKPOINT
#endif
break;
case PP_FILEDEPS:
else
break;
case PP_FILENAME:
break;
case PP_HOSTDIR:
break;
if (!p)
else if (streq(p, "-"))
{
if (pp.initialized)
else
{
else
}
}
{
else
{
{
else
}
{
}
}
}
break;
case PP_ID:
if (p)
break;
case PP_IGNORE:
{
pathcanon(p, 0, 0);
}
break;
case PP_IGNORELIST:
if (pp.initialized)
goto before;
break;
case PP_INCLUDE:
{
pathcanon(p, 0, 0);
break;
break;
{
pp.c = 1;
}
{
}
{
if (dp)
{
c = dp->c;
}
}
dp->c = c;
if (n)
else
}
break;
case PP_INCREF:
break;
case PP_RESET:
break;
case PP_INIT:
if (pp.initialized)
{
error_info.errors = 0;
error_info.warnings = 0;
}
else
{
/*
* context initialization
*/
if (!initialized)
{
/*
* out of malloc is fatal
*/
memfatal();
/*
* initialize the error message interface
*/
#if DEBUG & TRACE_debug
pptrace(0);
#endif
/*
* initialize pplex tables
*/
/*
* fixed macro stack size -- room for improvement
*/
initialized = 1;
/*
*/
}
/*
* validate modes
*/
{
case 'a':
case 'C':
ppop(PP_COMPATIBILITY, 0);
break;
case 'A':
case 'c':
ppop(PP_COMPATIBILITY, 0);
break;
case 'f':
break;
case 'F':
ppop(PP_COMPATIBILITY, 0);
break;
case 'k':
case 's':
break;
case 'o':
case 'O':
ppop(PP_TRANSITION, 0);
break;
case 't':
break;
}
{
{
}
else
{
}
}
/*
* create the hash tables
*/
{
}
{
}
/*
* mark macros that are builtin predicates
*/
{
if (!ppisid(*s))
s++;
}
/*
* the remaining entry names must be allocated
*/
{
c = error_info.trace;
error_info.trace = 0;
}
#if DEBUG
{
#endif
/*
* compose, push and read the builtin initialization script
*/
"\
#%s %s:%s \"/#<assert> /\" \"/assert /%s #/\"\n\
#%s %s:%s \"/#<unassert> /\" \"/unassert /%s #/\"\n\
",
{
{
}
{
if (!(pp.ppdefault = pathprobe("C", pp.pass, pp.probe ? pp.probe : PPPROBE, 0, pp.path, MAXTOKEN + 1, NiL, 0)))
}
}
{
{
case PP_ASSERT:
break;
case PP_DEFINE:
else
{
else
}
break;
case PP_DIRECTIVE:
break;
case PP_OPTION:
sfprintf(sp, "#%s %s:%-.*s %s\n", dirname(PRAGMA), pp.pass, s - pp.firstop->value, pp.firstop->value, s + 1);
else
break;
case PP_READ:
break;
case PP_UNDEF:
break;
}
}
"\
#%s %s:%s\n\
#%s %s:%s\n\
#%s !#%s(%s)\n\
#%s !#%s(%s) || #%s(%s)\n\
"
);
"\
#%s #%s(%s)\n\
#%s %s:%s\n\
#%s %s:%s\n\
#%s __STRICT__ 1\n\
#%s\n\
#%s\n\
"
);
{
if (!ppisid(*s))
s++;
}
"\
#%s\n\
#%s __STDPP__ 1\n\
#%s %s:no%s\n\
"
);
"\
#%s __STDPP__directive #(%s)\n\
"
);
if (ppisid(*s) || *s++ == '+')
{
t = *s == '_' ? "" : "__";
}
"\
#%s %s:no%s\n\
#%s %s:no%s\n\
"
);
"\
#%s !defined(__STDC__) && (!#option(compatibility) || #option(transition))\n\
#%s __STDC__ #(STDC)\n\
#%s\n\
"
);
while (pplex());
sfstrclose(sp);
if (error_info.trace)
message((-1, "include directory %s%s%s%s", dp->name, (dp->type & TYPE_VENDOR) ? " [VENDOR]" : "", (dp->type & TYPE_HOSTED) ? " [HOSTED]" : "", dp->c ? " [C]" : ""));
#if DEBUG
}
error_info.trace = c;
#endif
{
/*
* this is sleazy but at least it's
* hidden in the library
*/
#include <preroot.h>
#if FS_PREROOT
#endif
}
{
error(1, "directories up to and including %s are for \"...\" include files only", pp.stddirs->name);
}
{
else
}
if (pp.standalone)
#if COMPATIBLE
#endif
{
}
}
{
{
}
pp.symtab = hashalloc(NiL, HASH_name, "symbols", HASH_free, undefine, HASH_set, HASH_ALLOCATE|HASH_BUCKET, 0);
}
#if CHECKPOINT
{
if (!pp.pragma)
}
#endif
{
if (!(n & PP_deps_file))
{
}
if (n & PP_deps_generated)
if (n & PP_deps_local)
}
/*
* push the main input file -- special case for hosted mark
*/
else
#if CHECKPOINT
#endif
{
if (!(p = error_info.file))
p = "";
else
{
error_info.file = 0;
if (*p)
{
pathcanon(p, 0, 0);
}
}
PUSH_FILE(p, 0);
}
{
s++;
else
s = error_info.file;
if (!*s)
s = "-";
{
if (c = *++p)
while (*++p == c);
if (*p)
t = 0;
else
t++;
}
if (!t)
{
t = s + strlen(s);
*t++ = '.';
}
*(t + 1) = 0;
else
{
*t = 'd';
}
*t = 'o';
if (*error_info.file)
}
{
while (xp)
{
}
sfstrclose(sp);
}
break;
case PP_INPUT:
#if CHECKPOINT && POOL
#else
#if CHECKPOINT
#else
#if POOL
#endif
#endif
#endif
{
if (!error_info.file)
error_info.file = p;
close(0);
if (strmatch(p, "*.(s|S|as|AS|asm|ASM)"))
{
}
break;
}
/*FALLTHROUGH*/
case PP_TEXT:
if (pp.initialized)
goto before;
{
else
}
break;
case PP_KEYARGS:
if (pp.initialized)
goto before;
#if MACKEYARGS
#else
#endif
break;
case PP_LINE:
break;
case PP_LINEBASE:
{
else
}
break;
case PP_LINEFILE:
{
else
}
break;
case PP_LINEID:
{
else if (*p != '-')
else
}
break;
case PP_LINETYPE:
{
else
if (n >= 2)
else
}
break;
case PP_LOCAL:
if (pp.initialized)
goto before;
break;
case PP_MACREF:
break;
case PP_MULTIPLE:
break;
case PP_NOHASH:
break;
case PP_NOISE:
break;
case PP_OPTARG:
break;
case PP_OUTPUT:
close(1);
if (open(pp.outfile, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) != 1)
break;
case PP_PASSTHROUGH:
break;
case PP_PEDANTIC:
break;
case PP_PLUSCOMMENT:
break;
case PP_PLUSPLUS:
if (ppset(&pp.option, PLUSPLUS, va_arg(ap, int)) && ppset(&pp.option, PLUSCOMMENT, va_arg(ap, int)) && pp.initialized)
break;
case PP_POOL:
if (pp.initialized)
goto before;
{
#if POOL
if (!identical(p, 0))
{
if (!identical(p, 1))
}
#else
#endif
}
break;
case PP_PRAGMA:
break;
case PP_PRAGMAFLAGS:
{
n = OPT_GLOBAL;
if (*p == '-')
p++;
else
n |= OPT_PASS;
}
break;
case PP_PROBE:
break;
case PP_QUOTE:
if (p)
break;
case PP_REGUARD:
break;
case PP_RESERVED:
{
if (s = strchr(p, '='))
*s++ = 0;
else
s = p;
while (*s == '_')
s++;
if (*t == '_')
*t = 0;
else
t = 0;
if (t)
*t = '_';
{
}
{
}
sfstrclose(sp);
}
break;
case PP_SPACEOUT:
break;
case PP_STANDALONE:
if (pp.initialized)
goto before;
break;
case PP_STANDARD:
{
else
}
break;
case PP_STRICT:
{
else
}
break;
case PP_TEST:
for (;;)
{
while (*p == ' ' || *p == '\t') p++;
for (s = p; n = *s; s++)
if (n == ',' || n == ' ' || n == '\t')
{
*s++ = 0;
break;
}
if (!*p)
break;
n = 0;
if (*p == 'n' && *(p + 1) == 'o')
{
p += 2;
op = 0;
}
else
op = 1;
if (streq(p, "count"))
n = TEST_count;
else if (streq(p, "hashcount"))
n = TEST_hashcount;
else if (streq(p, "hashdump"))
n = TEST_hashdump;
else if (streq(p, "hit"))
n = TEST_hit;
else if (streq(p, "init"))
n = TEST_noinit|TEST_INVERT;
else if (streq(p, "noise"))
n = TEST_nonoise|TEST_INVERT;
else if (streq(p, "proto"))
n = TEST_noproto|TEST_INVERT;
else if (*p >= '0' && *p <= '9')
else
{
break;
}
if (n & TEST_INVERT)
{
n &= ~TEST_INVERT;
}
if (op)
else
p = s;
}
break;
case PP_TRANSITION:
{
else
}
break;
case PP_TRUNCATE:
if (pp.initialized)
goto before;
op = 0;
{
Hash_bucket_t* b;
Hash_bucket_t* p;
pp.symtab = hashalloc(NiL, HASH_set, tab ? HASH_ALLOCATE : 0, HASH_compare, trunccomp, HASH_hash, trunchash, HASH_name, "truncate", 0);
{
do
{
} while (p = b);
}
}
else
break;
case PP_VENDOR:
if (!p || !*p)
else if (streq(p, "-"))
{
if (c)
else
}
{
c = 0;
{
c = 1;
if (c)
else
}
}
break;
case PP_WARN:
break;
break;
default:
break;
}
}