/***********************************************************************
* *
* 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 stacked input stream support
*/
#include "pplib.h"
/*
* convert path to native representation
*/
#include "../../lib/libast/path/pathnative.c" /* drop in 2002 */
static char*
native(register const char* s)
{
register int c;
int m;
int n;
if (!s)
return 0;
return (char*)s;
n = PATH_MAX;
do
{
m = n;
} while (n > m);
for (;;)
{
switch (c = *s++)
{
case 0:
break;
case '\\':
case '"':
/*FALLTHROUGH*/
default:
continue;
}
break;
}
return (char*)s;
}
/*
* push stream onto input stack
* used by the PUSH_type macros
*/
void
pppush(register int t, register char* s, register char* p, int n)
{
switch (t)
{
case IN_FILE:
s = native(s);
#if CHECKPOINT
{
}
#endif
n = 1;
#if CHECKPOINT
#endif
#if ARCHIVE
{
{
case 0:
#if CHECKPOINT
#endif
break;
case TYPE_BUFFER:
#if CHECKPOINT
case TYPE_CHECKPOINT|TYPE_BUFFER:
#endif
break;
#if CHECKPOINT
case TYPE_CHECKPOINT:
break;
#endif
}
}
else
#endif
{
errno = 0;
#if PROTOTYPE
if (!(pp.option & NOPROTO) && !(pp.test & TEST_noproto) && ((pp.state & (COMPATIBILITY|TRANSITION)) == COMPATIBILITY || (pp.option & PLUSPLUS) || (pp.mode & EXTERNALIZE)) && (cur->buffer = pppopen(NiL, cur->fd, NiL, NiL, NiL, NiL, (PROTO_HEADER|PROTO_RETAIN)|(((pp.mode & EXTERNALIZE) || (pp.option & PROTOTYPED)) ? PROTO_FORCE : PROTO_PASS)|((pp.mode & EXTERNALIZE) ? PROTO_EXTERNALIZE : 0)|((pp.mode & MARKC) ? PROTO_PLUSPLUS : 0))))
{
}
else
#endif
}
/*FALLTHROUGH*/
case IN_BUFFER:
case IN_INIT:
case IN_RESCAN:
pushcontrol();
{
error_info.file = s;
error_info.line = n;
}
{
ppputchar('\n');
}
{
}
{
case IN_FILE:
{
}
#if CATSTRINGS
else
#endif
#if ARCHIVE && CHECKPOINT
#endif
{
{
return;
}
}
{
return;
}
break;
case IN_BUFFER:
break;
default:
break;
}
break;
#if DEBUG
default:
break;
#endif
}
}
/*
* external buffer push
*/
void
ppinput(char* b, char* f, int n)
{
PUSH_BUFFER(f, b, n);
}
/*
* return expanded value of buffer p
*/
char*
ppexpand(register char* p)
{
register char* m;
register int n;
register int c;
long restore;
char* pptoken;
char* ppmactop;
{
}
PUSH_STRING(p);
n = 2 * MAXTOKEN;
m = p + MAXTOKEN;
for (;;)
{
if (pplex())
{
{
m = p + n - MAXTOKEN;
}
{
}
}
break;
}
if (ppmactop)
return p;
}
#if CHECKPOINT
/*
* macro definition dump
*/
static int
{
register int flags;
{
ppputchar(0);
flags = 0;
{
ppputchar(0);
{
ppputchar(0);
}
}
ppputchar(0);
}
return(0);
}
/*
* dump macro definitions for quick loading via ppload()
*/
void
ppdump(void)
{
unsigned long macro_offset;
unsigned long index_offset;
/*
* NOTE: we assume '\0' does not occur in valid preprocessed output
*/
ppputchar(0);
/*
* output global flags
*/
macro_offset = ppoffset();
ppputchar(0);
/*
* output macro definitions
*/
ppputchar(0);
/*
* output include file index
*/
index_offset = ppoffset();
while (ip)
{
ppputchar(0);
ppputchar(0);
ppputchar(0);
ppputchar(0);
}
ppputchar(0);
/*
* output offset directory
*/
ppputchar(0);
ppputchar(0);
ppflushout();
}
/*
* load text and macro definitions from a previous ppdump()
* s is the string argument from the pragma (including quotes)
*/
void
ppload(register char* s)
{
register char* b;
int m;
char* g;
char* t;
unsigned long n;
unsigned long p;
unsigned long macro_offset;
unsigned long index_offset;
unsigned long file_offset;
unsigned long file_size;
unsigned long keep_begin;
unsigned long keep_end;
unsigned long skip_end;
unsigned long next_begin;
unsigned long next_end;
char* ip = 0;
#if ARCHIVE
{
}
else
#endif
{
file_offset = 0;
{
}
else
{
if (!(sp = sfnew(NiL, pp.in->buffer + ((pp.in->flags & IN_static) ? 0 : PPBAKSIZ), file_size, -1, SF_READ|SF_STRING)))
}
}
/*
* get the macro and index offsets
*/
/*
* read the include index
*/
b = s;
/*
* loop on the index and copy the non-ignored chunks to the output
*/
ppcheckout();
keep_begin = 0;
keep_end = 0;
skip_end = 0;
while (*b)
{
while (*b++);
g = b;
while (*b++);
if (pp.test & 0x0200) error(2, "%s: %s p=%lu next=<%lu,%lu> keep=<%lu,%lu> skip=<-,%lu> guard=%s", keyname(X_CHECKPOINT), fp->name, p, next_begin, next_end, keep_begin, keep_end, skip_end, fp->guard == INC_CLEAR ? "[CLEAR]" : fp->guard == INC_TEST ? "[TEST]" : fp->guard == INC_IGNORE ? "[IGNORE]" : fp->guard->name);
b = t + 1;
if (next_begin >= skip_end)
{
{
if (keep_begin)
{
n = next_begin - keep_begin;
if (pp.test & 0x0100) error(2, "%s: copy <%lu,%lu> n=%lu p=%lu", keyname(X_CHECKPOINT), keep_begin, next_begin - 1, n, p);
while (n > p)
{
n -= p;
p = PPBUFSIZ;
}
if (n)
{
p -= n;
}
keep_begin = 0;
keep_end = 0;
}
}
else if (!keep_begin)
{
if (skip_end)
{
skip_end = 0;
}
else keep_begin = next_begin;
}
}
}
if (keep_end)
{
if (!keep_begin)
g = b;
goto flush;
}
/*
* read the compacted definitions
*/
/*
* read the flags
*/
while (*s)
{
#if _options_dumped_
else
#endif
}
s++;
/*
* unpack and enter the definitions
*/
while (*s)
{
b = s;
while (*s++);
m = *s++;
{
if (m & LOAD_FUNCTION)
{
if (*s++ != '0')
while (*s++);
while (*s++);
}
while (*s++);
}
else
{
{
for (n = 0; *s >= '0' && *s <= '9'; n = n * 10 + *s++ - '0');
{
b = s;
while (*s++);
}
}
b = s;
while (*s++);
}
}
/*
* we are now at EOF
*/
if (ip)
{
}
#if ARCHIVE
else
#endif
{
}
}
#endif