-/* $Id: cpp.c,v 1.258 2016/03/14 20:27:56 ragge Exp $ */
+/* $Id: cpp.c,v 1.274 2016/04/12 18:49:35 ragge Exp $ */
/*
* Copyright (c) 2004,2010 Anders Magnusson (ragge@ludd.luth.se).
/*
* Buffers used:
- * - expansion buffers (via getobuf etc...)
+ * - expansion buffers (BNORMAL)
* - string buffers (used to store macros)
- * - tree buffers (used by macro search algorithm)
- * - scratch buffer (identifier readin)
*/
-
-
-
-#define SBSIZE 1000000
-
-static usch sbf[SBSIZE];
static int counter;
/* C command */
int tflag; /* traditional cpp syntax */
#ifdef PCC_DEBUG
int dflag; /* debug printouts */
-//static void imp(const char *);
static void prline(const usch *s);
static void prrep(const usch *s);
#define DPRINT(x) if (dflag) printf x
int Aflag, Cflag, Eflag, Mflag, dMflag, Pflag, MPflag, MMDflag;
char *Mfile, *MPfile;
-struct initar *initar;
char *Mxfile;
int warnings, Mxlen;
-FILE *of;
+static usch utbuf[CPPBUF];
+struct iobuf pb = { utbuf, 0, CPPBUF, 0, 1, BUTBUF };
+#if LIBVMF
+struct vspace ibspc;
+#endif
/* include dirs */
struct incs {
int flslvl;
int elflvl;
int elslvl;
-usch *stringbuf = sbf;
/*
* Macro replacement list syntax:
struct blocker *blkidx[RECMAX];
int blkidp;
-static struct iobuf *readargs2(usch **, struct symtab *sp, const usch **args);
-static int readargs1(struct symtab *sp, const usch **args);
+static struct iobuf *readargs2(struct iobuf *, struct symtab *sp, const usch **args);
+static struct iobuf *readargs1(struct symtab *sp, const usch **args);
static struct iobuf *exparg(int, struct iobuf *, struct iobuf *, struct blocker *);
static struct iobuf *subarg(struct symtab *sp, const usch **args, int, struct blocker *);
static void usage(void);
static int skipws(struct iobuf *ib);
static int getyp(usch *s);
-usch locs[] =
- { FILLOC, LINLOC, PRAGLOC, DEFLOC,
- 'd','e','f','i','n','e','d',0, CTRLOC };
-
int
main(int argc, char **argv)
{
- struct initar *it;
+ struct includ bic;
+ struct iobuf *fb = getobuf(BNORMAL);
register int ch;
const usch *fn1, *fn2;
+ char *a;
#ifdef TIMING
struct timeval t1, t2;
(void)gettimeofday(&t1, NULL);
#endif
+#if LIBVMF
+ if (vminit(2))
+ error("vminit");
+ if (vmopen(&ibspc, NULL) < 0)
+ error("vmopen ibspc");
+#endif
+
while ((ch = getopt(argc, argv, "ACD:d:EI:i:MPS:tU:Vvx:")) != -1) {
switch (ch) {
case 'A': /* assembler input */
break;
case 'D': /* define something */
+ if ((a = strchr(optarg, '=')) != NULL)
+ *a = ' ';
+ bsheap(fb, "#define %s%s", optarg, a ? "\n" : " 1\n");
+ break;
+
case 'i': /* include */
+ bsheap(fb, "#include \"%s\"\n", optarg);
+ break;
+
case 'U': /* undef */
- /* XXX should not need malloc() here */
- if ((it = xmalloc(sizeof(struct initar))) == NULL)
- error("couldn't apply -%c %s", ch, optarg);
- it->type = ch;
- it->str = optarg;
- it->next = initar;
- initar = it;
+ bsheap(fb, "#undef %s\n", optarg);
break;
case 'd':
pragloc = lookup((const usch *)"_Pragma", ENTER);
defloc = lookup((const usch *)"defined", ENTER);
ctrloc = lookup((const usch *)"__COUNTER__", ENTER);
- filloc->value = locs;
- linloc->value = locs+1;
- pragloc->value = locs+2;
- defloc->value = locs+3; /* also have macro name here */
- ctrloc->value = locs+12;
+ filloc->value = linloc->value = pragloc->value =
+ ctrloc->value = (const usch *)"";
+ defloc->value = defloc->namep;
+ filloc->type = FILLOC;
+ linloc->type = LINLOC;
+ pragloc->type = PRAGLOC;
+ defloc->type = DEFLOC;
+ ctrloc->type = CTRLOC;
if (Mflag && !dMflag) {
char *c;
}
if (argc == 2) {
- if ((of = freopen(argv[1], "w", stdout)) == NULL)
+ close(1);
+ if (open(argv[1], O_WRONLY|O_CREAT, 0600) < 0)
error("Can't creat %s", argv[1]);
- } else
- of = stdout;
+ }
if (argc && strcmp(argv[0], "-")) {
fn1 = fn2 = (usch *)argv[0];
fn1 = NULL;
fn2 = (const usch *)"";
}
+
+ /* initialization defines */
+ if (dMflag)
+ write(1, fb->buf, fb->cptr);
+ fb->buf[fb->cptr] = 0;
+ memset(&bic, 0, sizeof(bic));
+ bic.fname = bic.orgfn = (const usch *)"<command line>";
+ bic.lineno = 1;
+ bic.infil = -1;
+ bic.ib = fb;
+ fb->bsz = fb->cptr;
+ fb->cptr = 0;
+ ifiles = &bic;
+ fastscan();
+ bufree(fb);
+ ifiles = NULL;
+ /* end initial defines */
+
if (pushfile(fn1, fn2, 0, NULL))
error("cannot open %s", argv[0]);
- fclose(of);
+ if (Mflag == 0)
+ write(1, pb.buf, pb.cptr);
#ifdef TIMING
(void)gettimeofday(&t2, NULL);
t2.tv_sec -= t1.tv_sec;
putob(struct iobuf *ob, int ch)
{
if (ob->cptr == ob->bsz) {
- int sz = ob->bsz - ob->buf;
- ob->buf = xrealloc(ob->buf, sz + BUFSIZ);
- ob->cptr = ob->buf + sz;
- ob->bsz = ob->buf + sz + BUFSIZ;
+ int sz = ob->bsz;
+ switch (ob->type) {
+ case BNORMAL:
+ ob->buf = xrealloc(ob->buf, sz + CPPBUF+1);
+ /* ob->cptr = ob->buf + sz; */
+ ob->bsz = sz + CPPBUF;
+ break;
+ case BMAC:
+ case BINBUF:
+ error("putob");
+ case BUTBUF:
+ if (Mflag == 0)
+ (void)write(1, ob->buf, sz);
+ ob->cptr = 0;
+ break;
+ }
}
// DDPRINT(("putob: iob %p pos %p ch %c (%d)\n", ob, ob->cptr, ch, ch));
- *ob->cptr++ = ch;
+ ob->buf[ob->cptr++] = ch;
}
-static int nbufused;
+static struct iobuf *
+giob(int typ, const usch *bp, int bsz)
+{
+ struct iobuf *iob = xmalloc(sizeof(struct iobuf));
+
+ if (bp == NULL)
+ bp = xmalloc(bsz);
+ iob->buf = (usch *)bp;
+ iob->cptr = 0;
+ iob->bsz = bsz;
+ iob->ro = 0;
+ iob->type = typ;
+ return iob;
+}
+
+
+int nbufused;
/*
* Write a character to an out buffer.
*/
struct iobuf *
-getobuf(void)
+getobuf(int type)
{
- struct iobuf *iob = xmalloc(sizeof(struct iobuf));
+ struct iobuf *iob = 0;
- nbufused++;
- iob->buf = iob->cptr = xmalloc(BUFSIZ);
- iob->bsz = iob->buf + BUFSIZ;
- iob->ro = 0;
+ switch (type) {
+ case BNORMAL:
+ nbufused++;
+ iob = giob(BNORMAL, NULL, CPPBUF);
+ iob->bsz = CPPBUF-1; /* space for \0 */
+ break;
+ case BINBUF:
+#if LIBVMF
+ iob = giob(BINBUF, (usch *)ifiles->vseg->s_cinfo, CPPBUF);
+#else
+ iob = giob(BINBUF, NULL, CPPBUF);
+#endif
+ break;
+ default:
+ error("getobuf");
+ }
return iob;
}
static struct iobuf *
mkrobuf(const usch *s)
{
- struct iobuf *iob = xmalloc(sizeof(struct iobuf));
+ struct iobuf *iob;
nbufused++;
- DPRINT(("mkrobuf %s\n", s));
- iob->buf = iob->cptr = (usch *)s;
- iob->bsz = iob->buf + strlen((char *)iob->buf);
+ iob = giob(BNORMAL, s, strlen((char *)s));
iob->ro = 1;
+ DPRINT(("mkrobuf %s\n", s));
+ return iob;
+}
+
+/*
+ * Copy a buffer to another buffer.
+ */
+struct iobuf *
+buftobuf(struct iobuf *in, struct iobuf *iob)
+{
+ int cp;
+
+ DPRINT(("strtobuf iob %p buf %p str %p\n", iob, iob->buf, in));
+ if (iob == NULL)
+ iob = getobuf(BNORMAL);
+ for (cp = 0; cp < in->cptr; cp++)
+ putob(iob, in->buf[cp]);
return iob;
}
/*
* Copy a string to a buffer.
*/
-static struct iobuf *
-strtobuf(usch *str, struct iobuf *iob)
+struct iobuf *
+strtobuf(const usch *str, struct iobuf *iob)
{
- DPRINT(("strtobuf iob %p buf %p str %s\n", iob, iob->buf, str));
if (iob == NULL)
- iob = getobuf();
+ iob = getobuf(BNORMAL);
+ DPRINT(("strtobuf iob %p buf %p str %s\n", iob, iob->buf, str));
do {
putob(iob, *str);
} while (*str++);
error("macro too large");
tb = xmalloc(CPPBUF);
memcpy(tb, macbase+cmbase, CPPBUF-cmbase);
- xrealloc(macbase, cmbase);
macpos -= cmbase;
cmbase = 0;
macbase = tb;
void
bufree(struct iobuf *iob)
{
- nbufused--;
+ if (iob->type == BNORMAL)
+ nbufused--;
if (iob->ro == 0)
free(iob->buf);
free(iob);
if ((nl = lookup(dp, FIND)) == 0 || (ob = kfind(nl)) == 0)
goto bad;
} else {
- ob = getobuf();
+ ob = getobuf(BNORMAL);
do {
putob(ob, c);
} while (ISDIGIT(c = cinput()));
if (c != '\"')
goto bad;
- setcmbase();
- ifiles->fname = macbase+1;
- faststr(c, macsav);
- macbase[--macpos] = 0;
- if (strcmp((char *)ifiles->fname, (char *)macbase+cmbase+1))
- ifiles->fname = xstrdup(macbase+cmbase+1);
- clrcmbase();
+ ob = faststr(c, NULL);
+ if (strcmp((char *)ifiles->fname, (char *)ob->buf))
+ ifiles->fname = xstrdup(ob->buf);
+ bufree(ob);
c = skipws(0);
}
#ifdef MACHOABI
/*
+ * Example:
+ * Library/Frameworks/VideoToolbox.framework/Headers/VTSession.h
+ *
* Search for framework header file.
* Return 1 on success.
*/
static int
fsrch_macos_framework(const usch *fn, const usch *dir)
{
- usch *saved_stringbuf = stringbuf;
+ struct iobuf *ob;
usch *s = (usch *)strchr((const char*)fn, '/');
- usch *nm;
- usch *p;
+ usch *p, *q, *nm;
int len = s - fn;
if (s == NULL)
return 0;
-// fprintf(stderr, "searching for %s in %s\n", (const char *)fn, (const char *)dir);
-
- nm = savstr(dir);
- savch(0);
- p = savstr(fn);
- stringbuf = p + len;
- savch(0);
-// fprintf(stderr, "comparing \"%s\" against \"%.*s\"\n", nm, len, fn);
- p = (usch *)strstr((const char *)nm, (const char *)p);
-// fprintf(stderr, "p = %s\n", (const char *)p);
- if (p != NULL) {
- stringbuf = p;
- savch(0);
+ nm = xstrdup(dir);
+ p = xstrdup(fn);
+ *(p + len) = 0;
+
+ q = (usch *)strstr((const char *)nm, (const char *)p);
+ if (q != NULL) {
+ *q = 0;
return fsrch_macos_framework(fn, nm);
}
+ free(p);
p = nm + strlen((char *)nm) - 1;
while (*p == '/')
p--;
while (*p != '/')
p--;
- stringbuf = ++p;
- savstr((const usch *)"Frameworks/");
- stringbuf = savstr(fn) + len;
- savstr((const usch*)".framework/Headers");
- savstr(s);
- savch(0);
-
-// fprintf(stderr, "nm: %s\n", nm);
-
+ ++p;
+
+ ob = bsheap(NULL, "%s/Frameworks/%s.framework/Headers%s", nm, fn, s);
+ free(nm);
+ nm = xstrdup(ob->buf);
+ bufree(ob);
if (pushfile(nm, fn, SYSINC, NULL) == 0)
return 1;
-// fprintf(stderr, "not found %s, continuing...\n", nm);
-
- stringbuf = saved_stringbuf;
return 0;
}
* to resolve framework headers.
*/
{
- usch *dir = stringbuf;
- savstr(ifiles->orgfn);
- stringbuf = (usch *)strrchr((char *)dir, '/');
- if (stringbuf != NULL) {
- stringbuf++;
- savch(0);
+ /*
+ * Dig out org filename path and try to find.
+ */
+ usch *p, *dir = xstrdup(ifiles->orgfn);
+ if ((p = (usch *)strrchr((char *)dir, '/')) != NULL) {
+ p[1] = 0;
if (fsrch_macos_framework(fn, dir) == 1)
return 1;
}
- stringbuf = dir;
+ free(dir);
- if (fsrch_macos_framework(fn, (const usch *)"/Library/Frameworks/") == 1)
+ if (fsrch_macos_framework(fn,
+ (const usch *)"/Library/Frameworks/") == 1)
return 1;
- if (fsrch_macos_framework(fn, (const usch *)"/System/Library/Frameworks/") == 1)
+ if (fsrch_macos_framework(fn,
+ (const usch *)"/System/Library/Frameworks/") == 1)
return 1;
}
#endif
if ((ob = kfind(nl)) == 0)
return NULL;
} else {
- ob = getobuf();
+ ob = getobuf(BNORMAL);
putob(ob, c);
while ((c = cinput()) && c != '\n')
putob(ob, c);
}
/* now we have an (expanded?) filename in obuf */
- while (ob->buf < ob->cptr && ISWS(ob->cptr[-1]))
+ while (0 < ob->cptr && ISWS(ob->buf[ob->cptr-1]))
ob->cptr--;
if (ob->buf[0] != '\"' && ob->buf[0] != '<')
return NULL;
- if (ob->cptr[-1] != '\"' && ob->cptr[-1] != '>')
+ if (ob->buf[ob->cptr-1] != '\"' && ob->buf[ob->cptr-1] != '>')
return NULL;
- ob->cptr[-1] = 0;
+ ob->buf[ob->cptr-1] = 0;
return ob;
}
/* nope, failed, try to create a path for it */
if ((nm = (usch *)strrchr((char *)ifiles->orgfn, '/'))) {
ob = strtobuf((usch *)ifiles->orgfn, NULL);
- ob->cptr = ob->buf + (nm - ifiles->orgfn) + 1;
+ ob->cptr = (nm - ifiles->orgfn) + 1;
strtobuf(fn, ob);
- putob(ob, 0);
nm = xstrdup(ob->buf);
bufree(ob);
- } else {
+ } else
nm = xstrdup(fn);
- }
if (pushfile(nm, nm, 0, NULL) == 0) {
free(fn-1);
goto okret;
}
static int
-findarg(usch *s, usch **args, int narg)
+findarg(usch *s, struct iobuf *ab, int *arg, int narg)
{
int i;
for (i = 0; i < narg; i++)
- if (strcmp((char *)s, (char *)args[i]) == 0)
+ if (strcmp((char *)s, (char *)ab->buf + arg[i]) == 0)
return i;
return -1;
}
void
define(void)
{
+ struct iobuf *ib, *ab;
struct symtab *np;
- usch *args[MAXARGS+1], cc[2], *vararg, *dp;
+ usch cc[2], *vararg, *dp;
+ int arg[MAXARGS+1];
int c, i, redef, oCflag, t;
- int narg = -1;
+ int type, narg;
int wascon;
if (flslvl)
if (!ISID0(c = skipws(0)))
goto bad;
- setcmbase();
dp = readid(c);
np = lookup(dp, ENTER);
if (np->value) {
redef = 0;
}
+ type = OBJCT;
+ narg = 0;
+ ab = getobuf(BNORMAL);
vararg = NULL;
- macsav(0); /* set type slot */
if ((c = cinput()) == '(') {
- narg = 0;
+ type = 0;
/* function-like macros, deal with identifiers */
c = skipws(0);
for (;;) {
if (!ISID0(c))
goto bad;
- dp = readid(c);
+ dp = bufid(c, ab);
/* make sure there is no arg of same name */
- if (findarg(dp, args, narg) >= 0)
+ if (findarg(dp, ab, arg, narg) >= 0)
error("Duplicate parameter \"%s\"", dp);
if (narg == MAXARGS)
error("Too many macro args");
- args[narg++] = xstrdup(dp);
+ putob(ab, 0);
+ arg[narg++] = dp - ab->buf;
switch ((c = skipws(0))) {
case ',': break;
case ')': continue;
case '.':
if (isell() == 0 || skipws(0) != ')')
goto bad;
- vararg = args[--narg];
+ vararg = ab->buf + arg[--narg];
c = ')';
continue;
default:
Cflag = oCflag; /* Enable comments again */
- if (vararg)
- macsav(0); /* for macro type */
-
+ setcmbase();
if (ISWS(c))
c = skipwscmnt(0);
-#define DELEWS() while (macpos > cmbase+1+(vararg!=NULL) && \
+#define DELEWS() while ((macpos > cmbase) && \
ISWS(macbase[macpos-1])) macpos--
/* parse replacement-list, substituting arguments */
(void)cinput(); /* eat # */
DELEWS();
macsav(CONC);
- if (ISID0(c = skipws(0)) && narg >= 0)
+ if (ISID0(c = skipws(0)) && type == 0)
wascon = 1;
if (c == '\n')
goto bad; /* 6.10.3.3 p1 */
continue;
}
- if (narg < 0) {
+ if (type == OBJCT) {
/* no meaning in object-type macro */
macsav('#');
break;
break;
}
- if ((i = findarg(dp, args, narg)) < 0)
+ if ((i = findarg(dp, ab, arg, narg)) < 0)
goto bad;
macsav(WARN);
macsav(i);
macsav(SNUFF);
break;
+ case CMNT:
+ Ccmnt(macsav);
+ break;
+
case NUMBER:
- c = fastnum(c, macsav);
+ ib = getobuf(BNORMAL);
+ c = fastnum(c, ib);
+ for (dp = ib->buf; dp < ib->buf + ib->cptr; dp++)
+ macsav(*dp);
+ bufree(ib);
continue;
case STRING:
}
if (tflag)
macsav(c);
- else
- faststr(c, macsav);
+ else {
+ ib = faststr(c, NULL);
+ for (dp = ib->buf; *dp ; dp++)
+ macsav(*dp);
+ bufree(ib);
+ }
break;
case IDENT:
dp = readid(c);
- if (narg < 0) {
+ if (type == OBJCT) {
macstr(dp);
break; /* keep on heap */
}
}
/* check if its an argument */
- if ((i = findarg(dp, args, narg)) < 0) {
+ if ((i = findarg(dp, ab, arg, narg)) < 0) {
macstr(dp);
break;
}
/* remove trailing whitespace */
DELEWS();
- if (macbase[cmbase+1+(vararg != 0)] == CONC)
- goto bad; /* 6.10.3.3 p1 */
-
- if (vararg) {
- macbase[cmbase] = VARG;
- macbase[cmbase+1] = narg;
- } else
- macbase[cmbase] = (narg < 0 ? OBJCT : narg);
macsav(0);
+ if (vararg)
+ type = VARG;
+
+ if (macbase[cmbase] == CONC)
+ goto bad; /* 6.10.3.3 p1 */
if (redef && ifiles->idx != SYSINC) {
- if (cmprepl(np->value, macbase+cmbase)) { /* not equal */
+ if (cmprepl(np->value, macbase+cmbase) ||
+ np->type != type || np->narg != narg) { /* not equal */
np->value = macbase+cmbase;
warning("%s redefined (previously defined at \"%s\" line %d)",
np->namep, np->file, np->line);
macpos = cmbase; /* forget this space */
} else
np->value = macbase+cmbase;
+ np->type = type;
+ np->narg = narg;
#ifdef PCC_DEBUG
if (dflag) {
const usch *w = np->value;
printf("!define %s: ", np->namep);
- if (*w == OBJCT)
+ if (type == OBJCT)
printf("[object]");
- else if (*w == VARG)
- printf("[VARG%d]", *++w);
+ else if (type == VARG)
+ printf("[VARG%d]", narg);
else
- printf("[%d]", *w);
+ printf("[%d]", narg);
putchar('\'');
- prrep(++w);
+ prrep(w);
printf("\'\n");
}
#endif
- for (i = 0; i < narg; i++)
- free(args[i]);
+ bufree(ab);
return;
bad: error("bad #define");
exit(1);
}
-/*
- * store a character into the "define" buffer.
- */
-void
-savch(int c)
-{
- if (stringbuf >= &sbf[SBSIZE])
- error("out of macro space!");
-
- *stringbuf++ = (usch)c;
-}
-
static int
pragwin(struct iobuf *ib)
{
- return ib ? *ib->cptr++ : cinput();
+ return ib ? ib->buf[ib->cptr++] : cinput();
}
static int
pragoper(struct iobuf *ib)
{
int t;
- struct iobuf *ob = getobuf();
+ struct iobuf *ob = getobuf(BNORMAL);
if (skipws(ib) != '(' || ((t = skipws(ib)) != '\"' && t != 'L'))
goto err;
static struct iobuf *
unfname(void)
{
- struct iobuf *ob = getobuf();
+ struct iobuf *ob = getobuf(BNORMAL);
const usch *bp = ifiles->fname;
putob(ob, '\"');
* Version of fastnum that reads from a string and saves in ob.
* We know that it is a number before calling this routine.
*/
-static usch *
-fstrnum(usch *s, struct iobuf *ob)
+static void
+fstrnum(struct iobuf *ib, struct iobuf *ob)
{
+ usch *s = ib->buf+ib->cptr;
+
if (*s == '.') {
/* not digit, dot. Next will be digit */
putob(ob, *s++);
} else if ((*s != '.') && ((spechr[*s] & C_ID) == 0))
break;
}
- return s;
+ ib->cptr = s - ib->buf;
}
/*
* get a string or character constant.
* similar to faststr.
*/
-static usch *
-fstrstr(usch *s, struct iobuf *ob)
+static void
+fstrstr(struct iobuf *ib, struct iobuf *ob)
{
+ usch *s = ib->buf+ib->cptr;
int ch;
if (*s == 'L' || *s == 'U' || *s == 'u')
putob(ob, *s++);
}
putob(ob, *s++);
- return s;
+ ib->cptr = s - ib->buf;
}
/*
* Save standard comments if found.
*/
-static usch *
-fcmnt(usch *s, struct iobuf *ob)
+static void
+fcmnt(struct iobuf *ib, struct iobuf *ob)
{
+ usch *s = ib->buf+ib->cptr;
+
putob(ob, *s++); /* / */
putob(ob, *s++); /* * */
for (;;s++) {
if (s[-1] == '*' && *s == '/')
break;
}
- return s+1;
+ ib->cptr = s - ib->buf + 1;
}
static int
struct iobuf *xb, *xob;
struct symtab *sp;
usch *cp;
- int l, c, t;
+ int l, c, t, cn;
- ib->cptr = ib->buf; /* start from beginning */
+ ib->cptr = 0; /* start from beginning */
#ifdef PCC_DEBUG
if (dflag) {
printf("loopover: '");
- prline(ib->cptr);
+ prline(ib->buf+ib->cptr);
printf("'\n");
}
#endif
- xb = getobuf();
- while ((c = *ib->cptr)) {
- switch (t = getyp(ib->cptr)) {
+ xb = getobuf(BNORMAL);
+ while ((c = ib->buf[ib->cptr])) {
+ switch (t = getyp(ib->buf+ib->cptr)) {
case CMNT:
- ib->cptr = fcmnt(ib->cptr, ob);
+ fcmnt(ib, ob);
continue;
case NUMBER:
- ib->cptr = fstrnum(ib->cptr, ob);
+ fstrnum(ib, ob);
continue;
case STRING:
- xb->cptr = xb->buf;
- ib->cptr = fstrstr(ib->cptr,xb);
- *xb->cptr = 0;
+ xb->cptr = 0;
+ fstrstr(ib, xb);
+ xb->buf[xb->cptr] = 0;
for (cp = xb->buf; *cp; cp++) {
if (*cp <= BLKID) {
if (*cp == BLKID)
}
continue;
case BLKID:
- l = ib->cptr[1];
+ l = ib->buf[ib->cptr+1];
ib->cptr+=2;
/* FALLTHROUGH */
case IDENT:
* BUT: if this macro is blocked then this
* should not be done.
*/
- for (cp = ib->cptr; ISID(*ib->cptr); ib->cptr++)
+ for (cn = ib->cptr;
+ ISID(ib->buf[ib->cptr]); ib->cptr++)
;
- if ((sp = lookup(cp, FIND)) == NULL) {
-sstr: for (; cp < ib->cptr; cp++)
- putob(ob, *cp);
+ if ((sp = lookup(cn+ib->buf, FIND)) == NULL) {
+sstr: for (; cn < ib->cptr; cn++)
+ putob(ob, ib->buf[cn]);
continue;
}
if (expok(sp, l) == 0) {
/* blocked */
goto sstr;
} else {
- if (*sp->value != OBJCT) {
- cp = ib->cptr;
- while (ISWS(*ib->cptr))
+ if (sp->type != OBJCT) {
+ cn = ib->cptr;
+ while (ISWS(ib->buf[ib->cptr]))
ib->cptr++;
- if (*ib->cptr == 0) {
+ if (ib->buf[ib->cptr] == 0) {
bufree(xb);
return sp;
}
- ib->cptr = cp;
+ ib->cptr = cn;
}
newmac: if ((xob = submac(sp, 1, ib, NULL)) == NULL) {
strtobuf((usch *)sp->namep, ob);
* Handle defined macro keywords found on input stream.
* When finished print out the full expanded line.
* Input here is from the lex buffer.
- * Return 1 if success, 0 otherwise. fastscan restores stringbuf.
+ * Return 1 if success, 0 otherwise.
* Scanned data is stored on heap. Last scan prints out the buffer.
*/
struct iobuf *
{
extern int inexpr;
struct blocker *bl;
- struct iobuf *ib, *ob, *outb;
- const usch *argary[MAXARGS+1], *sbp;
+ struct iobuf *ib, *ob, *outb, *ab;
+ const usch *argary[MAXARGS+1];
int c, n = 0;
blkidp = 1;
outb = NULL;
- sbp = stringbuf;
DPRINT(("%d:enter kfind(%s)\n",0,sp->namep));
- switch (*sp->value) {
+ DPRINT(("%d:enter kfind2(%s)\n",0,sp->value));
+ switch ((unsigned int)sp->type) {
case FILLOC:
ob = unfname();
return ob;
case PRAGLOC:
pragoper(NULL);
- return getobuf();
+ return getobuf(BNORMAL);
case DEFLOC:
case OBJCT:
bl = blkget(sp, NULL);
- ib = mkrobuf(sp->value+1);
- ob = getobuf();
+ ib = mkrobuf(sp->value);
+ ob = getobuf(BNORMAL);
ob = exparg(1, ib, ob, bl);
bufree(ib);
break;
}
/* fetch arguments */
-again: if (readargs1(sp, argary))
+again: if ((ab = readargs1(sp, argary)) == 0)
error("readargs");
bl = blkget(sp, NULL);
ib = subarg(sp, argary, 1, bl);
- ob = getobuf();
+ bufree(ab);
+ ob = getobuf(BNORMAL);
ob = exparg(1, ib, ob, bl);
bufree(ib);
break;
}
/*
- * Loop over stringbuf, output the data and remove remaining
+ * Loop over ob, output the data and remove remaining
* directives. Start with extracting the last keyword (if any).
*/
putob(ob, 0); /* XXX needed? */
if (outb == NULL)
- outb = getobuf();
+ outb = getobuf(BNORMAL);
- stringbuf = (usch *)sbp; /* XXX should check cleanup */
if ((sp = loopover(ob, outb))) {
/* Search for '(' */
while (ISWSNL(c = cinput()))
for (ifiles->lineno += n; n; n--)
putob(outb, '\n');
- stringbuf = (usch *)sbp;
if (nbufused != 1)
error("lost buffer");
return outb;
struct blocker *bl;
struct iobuf *ob, *ab;
const usch *argary[MAXARGS+1];
- usch *cp, *pr;
+ int cn;
DPRINT(("%d:submac: trying '%s'\n", lvl, sp->namep));
- switch (*sp->value) {
+ switch ((unsigned int)sp->type) {
case FILLOC:
ob = unfname();
break;
break;
case PRAGLOC:
pragoper(ib);
- ob = getobuf();
+ ob = getobuf(BNORMAL);
break;
case OBJCT:
bl = blkget(sp, obl);
- ib = mkrobuf(sp->value+1);
- ob = getobuf();
+ ib = mkrobuf(sp->value);
+ ob = getobuf(BNORMAL);
DPRINT(("%d:submac: calling exparg\n", lvl));
ob = exparg(lvl+1, ib, ob, bl);
bufree(ib);
ob = bsheap(NULL, "%d", counter++);
break;
default:
- cp = ib->cptr;
- while (ISWSNL(*ib->cptr))
+ cn = ib->cptr;
+ while (ISWSNL(ib->buf[ib->cptr]))
ib->cptr++;
- if (*ib->cptr != '(') {
- ib->cptr = cp;
+ if (ib->buf[ib->cptr] != '(') {
+ ib->cptr = cn;
return 0;
}
- cp = ib->cptr++;
- pr = stringbuf;
- if ((ab = readargs2(&ib->cptr, sp, argary)) == 0) {
+ cn = ib->cptr++;
+ if ((ab = readargs2(ib, sp, argary)) == 0) {
/* Bailed out in the middle of arg list */
- ib->cptr = cp; /* XXX */
+ ib->cptr = cn; /* XXX */
return 0;
}
bl = blkget(sp, obl);
ib = subarg(sp, argary, lvl+1, bl);
bufree(ab);
- stringbuf = pr;
- ob = getobuf();
+ ob = getobuf(BNORMAL);
DPRINT(("%d:submac(: calling exparg\n", lvl));
ob = exparg(lvl+1, ib, ob, bl);
bufree(ib);
}
static int
-ra1_wsnl(int sp)
+ra1_wsnl(void)
{
int c;
putch('\n');
chkdir();
ifiles->lineno++;
- if (sp) savch(' ');
}
}
return c;
* Read arguments and put in argument array.
* If EOF is encountered return 1, otherwise 0.
*/
-int
+struct iobuf *
readargs1(struct symtab *sp, const usch **args)
{
- struct iobuf *ob;
+ struct iobuf *ab;
const usch *vp = sp->value;
- int c, i, plev, narg, ellips = 0;
+ int c, i, j, plev, narg, ellips = 0;
+ int argary[MAXARGS+1];
DPRINT(("readargs1\n"));
- narg = *vp++;
- if (narg == VARG) {
- narg = *vp++;
- ellips = 1;
- }
+ narg = sp->narg;
+ ellips = sp->type == VARG;
+
#ifdef PCC_DEBUG
if (dflag > 1) {
printf("narg %d varg %d: ", narg, ellips);
/*
* read arguments and store them on heap.
*/
+ ab = getobuf(BNORMAL);
c = '(';
for (i = 0; i < narg && c != ')'; i++) {
- args[i] = stringbuf;
+ argary[i] = ab->cptr;
plev = 0;
- c = ra1_wsnl(0);
+ c = ra1_wsnl();
for (;;) {
if (plev == 0 && (c == ')' || c == ','))
break;
if (c == ')') plev--;
if (c == 0)
error("eof in macro");
- else if (c == '/') Ccmnt(savch);
- else if (c == '\"' || c == '\'') faststr(c, savch);
- else if (ISID0(c)) {
- usch *bp = stringbuf;
- do {
- savch(c);
- } while ((spechr[c = cinput()] & C_ID));
- if ((sp = lookup(bp, FIND)) != NULL) {
- if (sp == linloc) {
- stringbuf = bp;
- ob = bsheap(NULL, "%d", ifiles->lineno);
- savstr(ob->buf);
- bufree(ob);
- } else if (sp == ctrloc) {
- stringbuf = bp;
- ob = bsheap(NULL, "%d", counter++);
- savstr(ob->buf);
- bufree(ob);
- }
+ else if (c == '/') {
+ int mp = macpos;
+ Ccmnt(macsav);
+ macsav(0);
+ strtobuf(macbase+mp, ab);
+ macpos = mp;
+ } else if (c == '\"' || c == '\'') {
+ faststr(c, ab);
+ } else if (ISID0(c)) {
+ int mp = ab->cptr;
+ bufid(c, ab);
+ if ((sp = lookup(ab->buf+mp, FIND)) != NULL &&
+ (sp == linloc || sp == ctrloc)) {
+ ab->cptr = mp;
+ bsheap(ab,"%d", (sp == linloc ?
+ ifiles->lineno : counter++));
}
- cunput(c);
} else
- savch(c);
+ putob(ab, c);
if ((c = cinput()) == '\n') {
chkdir();
ifiles->lineno++, putch(c), c = ' ';
}
}
- while (args[i] < stringbuf && ISWSNL(stringbuf[-1]))
- stringbuf--;
- savch('\0');
+ while (argary[i] < ab->cptr && ISWSNL(ab->buf[ab->cptr-1]))
+ ab->cptr--;
+ putob(ab, '\0');
#ifdef PCC_DEBUG
if (dflag) {
printf("readargs: save arg %d '", i);
- prline(args[i]);
+ prline(ab->buf+argary[i]);
printf("'\n");
}
#endif
}
/* Handle varargs readin */
- if (ellips)
- args[i] = (const usch *)"";
+ argary[i] = ab->cptr;
+ putob(ab, 0);
+ ab->cptr--;
if (ellips && c != ')') {
- args[i] = stringbuf;
plev = 0;
- c = ra1_wsnl(0);
+ c = ra1_wsnl();
for (;;) {
if (plev == 0 && c == ')')
break;
if (c == '(') plev++;
if (c == ')') plev--;
- if (c == '\"' || c == '\'') faststr(c, savch);
- else
- savch(c);
+ if (c == '\"' || c == '\'') {
+ faststr(c, ab);
+ } else
+ putob(ab, c);
if ((c = cinput()) == '\n')
ifiles->lineno++, c = ' ';
}
- while (args[i] < stringbuf && ISWSNL(stringbuf[-1]))
- stringbuf--;
- savch('\0');
+ while (argary[i] < ab->cptr && ISWSNL(ab->buf[ab->cptr-1]))
+ ab->cptr--;
+ putob(ab, '\0');
#ifdef PCC_DEBUG
if (dflag) {
printf("readargs: vararg arg %d '", i);
- prline(args[i]);
+ prline(ab->buf+argary[i]);
printf("'\n");
}
#endif
-
}
+ if (ellips)
+ i++;
if (narg == 0 && ellips == 0)
- c = ra1_wsnl(0);
+ c = ra1_wsnl();
if (c != ')' || (i != narg && ellips == 0) || (i < narg && ellips == 1))
error("wrong arg count");
- return 0;
+ for (j = 0; j < i; j++)
+ args[j] = ab->buf + argary[j];
+ return ab;
}
-static usch *raptr;
+static struct iobuf *rabuf;
static int
raread(void)
{
int rv;
- if (raptr) {
- if ((rv = *raptr))
- raptr++;
+ if (rabuf) {
+ if ((rv = rabuf->buf[rabuf->cptr]))
+ rabuf->cptr++;
} else
rv = cinput();
return rv;
}
-
/*
* Read arguments and put in argument array.
* If EOF is encountered return 1, otherwise 0.
*/
struct iobuf *
-readargs2(usch **inp, struct symtab *sp, const usch **args)
+readargs2(struct iobuf *in, struct symtab *sp, const usch **args)
{
struct iobuf *ab;
const usch *vp = sp->value;
DPRINT(("readargs2 %s '", sp->namep));
#ifdef PCC_DEBUG
- if (dflag && inp) {
- prline(*inp);
+ if (dflag) {
+ prline(in->buf+in->cptr);
printf("'\n");
}
#endif
- raptr = inp ? *inp : 0;
- narg = *vp++;
- if (narg == VARG) {
- narg = *vp++;
- ellips = 1;
- }
+ rabuf = in;
+ narg = sp->narg;
+ ellips = sp->type == VARG;
+
#ifdef PCC_DEBUG
if (dflag > 1) {
prrep(vp);
/*
* read arguments and store them on heap.
*/
- ab = getobuf();
+ ab = getobuf(BNORMAL);
c = '(';
for (i = 0; i < narg && c != ')'; i++) {
- argary[i] = ab->cptr - ab->buf;
+ argary[i] = ab->cptr;
plev = 0;
while ((c = raread()) == ' ' || c == '\t')
if (c == '(') plev++;
if (c == ')') plev--;
if (c == 0) {
- if (raptr) {
- *inp = raptr;
- raptr = 0;
+ if (rabuf) {
+ rabuf = 0;
} else
error("eof in macro");
} else if (c == BLKID) {
putob(ab, '/');
continue;
} else if (c == '\"' || c == '\'') {
- if (raptr) {
- raptr = fstrstr(raptr-1, ab);
+ if (rabuf) {
+ rabuf->cptr--;
+ fstrstr(rabuf, ab);
} else {
- int mp = macpos;
- faststr(c, macsav);
- strtobuf(macbase+mp, ab);
- macpos = mp;
+ faststr(c, ab);
}
} else if (ISID0(c)) {
- int mp = macpos;
+ int mp = ab->cptr;
do {
- macsav(c);
+ putob(ab, c);
} while (ISID(c = raread()));
- macsav(0);
- macpos = mp;
- if ((sp = lookup(macbase+mp, FIND)) &&
+ ab->buf[ab->cptr] = 0;
+ if ((sp = lookup(ab->buf+mp, FIND)) &&
(sp == linloc)) {
+ ab->cptr = mp;
bsheap(ab, "%d", ifiles->lineno);
- } else
- strtobuf(macbase+mp, ab);
+ }
continue;
} else
putob(ab, c);
c = raread();
}
- while (argary[i] < ab->cptr-ab->buf && ISWSNL(ab->cptr[-1]))
+ while (argary[i] < ab->cptr && ISWSNL(ab->buf[ab->cptr-1]))
ab->cptr--;
putob(ab, '\0');
#ifdef PCC_DEBUG
if (ellips)
args[i] = (const usch *)"";
if (ellips && c != ')') {
- argary[i] = ab->cptr - ab->buf;
+ argary[i] = ab->cptr;
plev = 0;
while ((c = raread()) == ' ' || c == '\t')
;
if (c == '(') plev++;
if (c == ')') plev--;
if (c == '\"' || c == '\'') {
- if (raptr) {
- raptr = fstrstr(raptr-1, ab);
+ if (rabuf) {
+ rabuf->cptr--;
+ fstrstr(rabuf, ab);
} else {
- int mp = macpos;
- faststr(c, macsav);
- strtobuf(macbase+mp, ab);
- macpos = mp;
+ faststr(c, ab);
}
} else
putob(ab, c);
c = raread();
}
- while (argary[i] < ab->cptr-ab->buf && ISWSNL(ab->cptr[-1]))
+ while (argary[i] < ab->cptr && ISWSNL(ab->buf[ab->cptr-1]))
ab->cptr--;
putob(ab, '\0');
i++;
if (c != ')' || (i != narg && ellips == 0) || (i < narg && ellips == 1))
error("wrong arg count");
- if (raptr)
- *inp = raptr;
for (j = 0; j < i; j++)
args[j] = ab->buf + argary[j];
return ab;
const usch *sp, *bp, *ap, *vp, *tp;
DPRINT(("%d:subarg '%s'\n", lvl, nl->namep));
- ob = getobuf();
+ ob = getobuf(BNORMAL);
vp = nl->value;
- narg = *vp++;
- if (narg == VARG)
- narg = *vp++;
+ narg = nl->narg;
sp = vp;
instr = snuff = 0;
*/
w = bl ? bl->next : NULL;
cb = mkrobuf(bp);
- nb = getobuf();
+ nb = getobuf(BNORMAL);
DPRINT(("%d:subarg: calling exparg\n", lvl));
nb = exparg(lvl+1, cb, nb, w);
DPRINT(("%d:subarg: return exparg\n", lvl));
sp++;
}
putob(ob, 0);
- ob->cptr = ob->buf;
+ ob->cptr = 0;
DPRINT(("%d:subarg retline %s\n", lvl, ob->buf));
return ob;
}
exparg(int lvl, struct iobuf *ib, struct iobuf *ob, struct blocker *bl)
{
extern int inexpr;
- struct iobuf *nob;
+ struct iobuf *nob, *tb;
struct symtab *nl;
int c, m;
- usch *cp, *bp, *sbp;
+ usch *cp;
- DPRINT(("%d:exparg: entry ib %s\n", lvl, ib->cptr));
+ DPRINT(("%d:exparg: entry ib %s\n", lvl, ib->buf+ib->cptr));
#ifdef PCC_DEBUG
if (dflag > 1) {
printf("exparg entry: full ");
- prline(ib->cptr);
+ prline(ib->buf+ib->cptr);
printf("\n");
}
#endif
- while ((c = getyp(ib->cptr)) != 0) {
+ while ((c = getyp(ib->buf+ib->cptr)) != 0) {
ib->cptr++;
switch (c) {
case CMNT:
- ib->cptr = fcmnt(ib->cptr-1, ob);
+ ib->cptr--;
+ fcmnt(ib, ob);
break;
case NUMBER:
- ib->cptr = fstrnum(ib->cptr-1, ob);
+ ib->cptr--;
+ fstrnum(ib, ob);
break;
case STRING:
- ib->cptr = fstrstr(ib->cptr-1, ob);
+ ib->cptr--;
+ fstrstr(ib, ob);
break;
case BLKID:
- m = *ib->cptr++;
+ m = ib->buf[ib->cptr++];
ib->cptr++;
/* FALLTHROUGH */
case IDENT:
if (c != BLKID)
m = 0;
- for (cp = ib->cptr-1; ISID(*cp); cp++)
- ;
-#ifdef PCC_DEBUG
-if (dflag) { printf("!! ident "); prline(ib->cptr-1); printf("\n"); }
-#endif
- sbp = stringbuf;
- if (*cp == BLKID) {
- /* concatenation */
- bp = stringbuf;
- for (cp = ib->cptr-1;
- ISID(*cp) || *cp == BLKID; cp++) {
- if (*cp == BLKID) {
- /* XXX add to block list */
- cp++;
- } else
- savch(*cp);
- }
- ib->cptr = cp;
- cp = stringbuf;
- savch(0);
- } else {
- bp = ib->cptr-1;
- ib->cptr = cp;
+ tb = getobuf(BNORMAL);
+ cp = ib->buf+ib->cptr-1;
+ for (; ISID(*cp) || *cp == BLKID; cp++) {
+ if (*cp == BLKID) {
+ /* XXX add to block list */
+ cp++;
+ } else
+ putob(tb, *cp);
}
-#ifdef PCC_DEBUG
-if (dflag) { printf("!! ident2 "); prline(bp); printf("\n"); }
-#endif
- if ((nl = lookup(bp, FIND)) == NULL) {
-sstr: for (; bp < cp; bp++)
- putob(ob, *bp);
- stringbuf = sbp;
- break;
- } else if (inexpr && *nl->value == DEFLOC) {
+ tb->buf[tb->cptr] = 0;
+ ib->cptr = cp - ib->buf;
+
+ /* Any match? */
+ if ((nl = lookup(tb->buf, FIND)) == NULL) {
+ buftobuf(tb, ob);
+ } else if (inexpr && nl->type == DEFLOC) {
+ /* Used in #if stmts */
int gotlp = 0;
- while (ISWS(*ib->cptr)) ib->cptr++;
- if (*ib->cptr == '(')
- gotlp++, ib->cptr++;
- while (ISWS(*ib->cptr)) ib->cptr++;
- if (!ISID0(*ib->cptr))
+
+ cp = ib->buf+ib->cptr;
+ while (ISWS(*cp)) cp++;
+ if (*cp == '(')
+ gotlp++, cp++;
+ while (ISWS(*cp)) cp++;
+ if (!ISID0(*cp))
error("bad defined");
- putob(ob, lookup(ib->cptr, FIND) ? '1' : '0');
- while (ISID(*ib->cptr)) ib->cptr++;
- while (ISWS(*ib->cptr)) ib->cptr++;
- if (gotlp && *ib->cptr != ')')
+ putob(ob, lookup(cp, FIND) ? '1' : '0');
+ while (ISID(*cp)) cp++;
+ while (ISWS(*cp)) cp++;
+ if (gotlp && *cp != ')')
error("bad defined");
- ib->cptr++;
- break;
- }
- stringbuf = sbp;
- if (expokb(nl, bl) && expok(nl, m)) {
- if ((nob = submac(nl, lvl+1, ib, bl))) {
- if (nob->buf[0] == '-' ||
- nob->buf[0] == '+')
- putob(ob, ' ');
- strtobuf(nob->buf, ob);
- if (ob->cptr[-1] == '-' ||
- ob->cptr[-1] == '+')
- putob(ob, ' ');
- bufree(nob);
- } else {
- goto sblk;
- }
+ cp++;
+ ib->cptr = cp - ib->buf;
+ } else if (expokb(nl, bl) && expok(nl, m) &&
+ (nob = submac(nl, lvl+1, ib, bl))) {
+ if (nob->buf[0] == '-' || nob->buf[0] == '+')
+ putob(ob, ' ');
+ strtobuf(nob->buf, ob);
+ if (ob->cptr > 0 &&
+ (ob->buf[ob->cptr-1] == '-' ||
+ ob->buf[ob->cptr-1] == '+'))
+ putob(ob, ' ');
+ bufree(nob);
} else {
- /* blocked */
-sblk: storeblk(blkix(mergeadd(bl, m)), ob);
- goto sstr;
+ storeblk(blkix(mergeadd(bl, m)), ob);
+ buftobuf(tb, ob);
}
+ bufree(tb);
break;
default:
}
#endif
-usch *
-savstr(const usch *str)
-{
- usch *rv = stringbuf;
-
- do {
- if (stringbuf >= &sbf[SBSIZE])
- error("out of macro space!");
- } while ((*stringbuf++ = *str++));
- stringbuf--;
- return rv;
-}
-
void
putch(int ch)
{
- if (Mflag)
- return;
- fputc(ch, stdout);
+ putob(&pb, ch);
}
void
putstr(const usch *s)
{
- for (; *s; s++) {
- if (Mflag == 0)
- fputc(*s, stdout);
- }
+ strtobuf(s, &pb);
}
/*
va_list ap;
if (ob == NULL)
- ob = getobuf();
+ ob = getobuf(BNORMAL);
va_start(ap, fmt);
vsheap(ob, fmt, ap);
static struct tree *tp;
if (ntrees == 0) {
- tp = xmalloc(BUFSIZ);
- ntrees = BUFSIZ/sizeof(*tp);
+ tp = xmalloc(CPPBUF);
+ ntrees = CPPBUF/sizeof(*tp);
}
return &tp[--ntrees];
}
struct symtab *sp;
if (nsyms == 0) {
- spp = xmalloc(BUFSIZ);
- nsyms = BUFSIZ/sizeof(*sp);
+ spp = xmalloc(CPPBUF);
+ nsyms = CPPBUF/sizeof(*sp);
}
sp = &spp[--nsyms];
-/* $Id: token.c,v 1.162 2016/03/12 15:46:06 ragge Exp $ */
+/* $Id: token.c,v 1.172 2016/04/12 18:49:35 ragge Exp $ */
/*
* Copyright (c) 2004,2009 Anders Magnusson. All rights reserved.
#define PUTCH(ch) if (!flslvl) putch(ch)
/* protection against recursion in #include */
#define MAX_INCLEVEL 100
-static int inclevel;
+int inclevel;
struct includ *ifiles;
if (ifiles->infil == -1)
return 0;
- len = read(ifiles->infil, ifiles->buffer, CPPBUF);
+ len = read(ifiles->infil, ifiles->buffer, CPPBUF-PBMAX);
if (len == -1)
error("read error on file %s", ifiles->orgfn);
if (len > 0) {
- ifiles->buffer[len] = 0;
- ifiles->curptr = ifiles->buffer;
- ifiles->maxread = ifiles->buffer + len;
+ ifiles->ib->cptr = PBMAX;
+ ifiles->ib->bsz = PBMAX + len;
}
return len;
}
if (ifiles->curptr+minsz < ifiles->maxread)
return 0; /* already enough in input buffer */
- sz = ifiles->maxread - ifiles->curptr;
- dp = ifiles->buffer - sz;
+ sz = ifiles->ib->bsz - ifiles->ib->cptr;
+ dp = ifiles->ib->buf+PBMAX - sz;
for (i = 0; i < sz; i++)
- dp[i] = ifiles->curptr[i];
+ dp[i] = ifiles->ib->buf[ifiles->ib->cptr+i];
i = inpbuf();
- ifiles->curptr = dp;
+ ifiles->ib->cptr = dp - ifiles->ib->buf;
if (i == 0) {
- ifiles->maxread = ifiles->buffer;
- ifiles->buffer[0] = 0;
+ ifiles->ib->bsz = PBMAX;
+ ifiles->ib->buf[PBMAX] = 0;
}
return 0;
}
{
do {
- if (ifiles->curptr < ifiles->maxread)
- return *ifiles->curptr++;
+ if (ifiles->ib->cptr < ifiles->ib->bsz)
+ return ifiles->ib->buf[ifiles->ib->cptr++];
} while (inpbuf() > 0);
return -1;
if (c == -1)
return;
- ifiles->curptr--;
- if (ifiles->curptr < ifiles->bbuf)
+ ifiles->ib->cptr--;
+ if (ifiles->ib->cptr < 0)
error("pushback buffer full");
- *ifiles->curptr = (usch)c;
+ ifiles->ib->buf[ifiles->ib->cptr] = (usch)c;
}
/*
return ch;
}
+/*
+ * readin chars and store in buf. Warn about too long names.
+ */
+usch *
+bufid(int ch, struct iobuf *ob)
+{
+ int n = ob->cptr;
+
+ do {
+ if (ob->cptr - n == MAXIDSZ)
+ warning("identifier exceeds C99 5.2.4.1");
+ if (ob->cptr < ob->bsz)
+ ob->buf[ob->cptr++] = ch;
+ else
+ putob(ob, ch);
+ } while (spechr[ch = inch()] & C_ID);
+ ob->buf[ob->cptr] = 0; /* legal */
+ unch(ch);
+ return ob->buf+n;
+}
+
usch idbuf[MAXIDSZ+1];
/*
* readin chars and store in buf. Warn about too long names.
/*
* get a string or character constant and save it as given by d.
*/
-void
-faststr(int bc, void (*d)(int))
+struct iobuf *
+faststr(int bc, struct iobuf *ob)
{
int ch;
+ if (ob == NULL)
+ ob = getobuf(BNORMAL);
+
incmnt = 1;
- d(bc);
+ putob(ob, bc);
while ((ch = inc2()) != bc) {
if (ch == '\n') {
warning("unterminated literal");
incmnt = 0;
unch(ch);
- return;
+ return ob;
}
if (ch < 0)
- return;
+ return ob;
if (ch == '\\') {
incmnt = 0;
if (chkucn())
continue;
incmnt = 1;
- d(ch);
+ putob(ob, ch);
ch = inc2();
}
- d(ch);
+ putob(ob, ch);
}
- d(ch);
+ putob(ob, ch);
+ ob->buf[ob->cptr] = 0;
incmnt = 0;
+ return ob;
}
/*
- * get a preprocessing number and save it as given by d.
- * Initial char ch is always stored.
+ * get a preprocessing number and save it as given by ob.
* returns first non-pp-number char.
+ * We know that this is a valid number already.
*
* pp-number: digit
* . digit
* pp-number .
*/
int
-fastnum(int ch, void (*d)(int))
+fastnum(int ch, struct iobuf *ob)
{
int c2;
if ((spechr[ch] & C_DIGIT) == 0) {
/* not digit, dot */
- d(ch);
+ putob(ob, ch);
ch = inch();
- if ((spechr[ch] & C_DIGIT) == 0)
- return ch;
}
for (;;) {
- d(ch);
+ putob(ob, ch);
if ((ch = inch()) < 0)
return -1;
if ((spechr[ch] & C_EP)) {
unch(c2);
break;
}
- d(ch);
+ putob(ob, ch);
ch = c2;
} else if (ch == '.' || (spechr[ch] & C_ID)) {
continue;
* Only data from pp files are scanned here, never any rescans.
* This loop is always at trulvl.
*/
-static void
+void
fastscan(void)
{
- struct iobuf *ob;
+ struct iobuf *ob, rbs, *rb = &rbs;
+ extern struct iobuf pb;
struct symtab *nl;
int ch, c2, i, nch;
- usch *cp, *dp;
+ usch *dp;
+
+#define IDSIZE 128
+ rb->buf = xmalloc(IDSIZE+1);
+ rb->cptr = 0;
+ rb->bsz = IDSIZE;
goto run;
/* tight loop to find special chars */
/* should use getchar/putchar here */
for (;;) {
- if (ifiles->curptr < ifiles->maxread) {
- ch = *ifiles->curptr++;
+ if (ifiles->ib->cptr < ifiles->ib->bsz) {
+ ch = ifiles->ib->buf[ifiles->ib->cptr++];
} else {
if (inpbuf() > 0)
continue;
+ free(rb->buf);
return;
}
-xloop: if (ch < 0)
+xloop: if (ch < 0) {
+ free(rb->buf);
return; /* EOF */
+ }
if ((spechr[ch] & C_SPEC) != 0)
break;
putch(ch);
}
REFILL(2);
- nch = *ifiles->curptr;
+ nch = ifiles->ib->buf[ifiles->curptr];
switch (ch) {
case WARN:
case CONC:
}
/* FALLTHROUGH */
case '\"': /* strings */
- faststr(ch, putch);
+ faststr(ch, &pb);
break;
case '.': /* for pp-number */
+ if ((spechr[nch] & C_DIGIT) == 0) {
+ putch('.');
+ break;
+ }
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
- ch = fastnum(ch, putch);
+ ch = fastnum(ch, &pb);
goto xloop;
case 'u':
- if (nch == '8' && ifiles->curptr[1] == '\"') {
+ if (nch == '8' && ifiles->ib->buf[ifiles->curptr+1] == '\"') {
putch(ch);
break;
}
ident:
if (flslvl)
error("fastscan flslvl");
- dp = readid(ch);
- if ((nl = lookup(dp, FIND))) {
- if ((ob = kfind(nl))) {
+ rb->cptr = 0;
+ dp = bufid(ch, rb);
+ if ((nl = lookup(dp, FIND)) != NULL) {
+ if ((ob = kfind(nl)) != NULL) {
if (*ob->buf == '-' || *ob->buf == '+')
putch(' ');
- for (cp = ob->buf; cp < ob->cptr; cp++)
- putch(*cp);
- if (ob->cptr[-1] == '-' ||
- ob->cptr[-1] == '+')
+ buftobuf(ob, &pb);
+ if (ob->cptr > 0 &&
+ (ob->buf[ob->cptr-1] == '-' ||
+ ob->buf[ob->cptr-1] == '+'))
putch(' ');
bufree(ob);
}
- } else
+ } else {
putstr(dp);
+ }
break;
case '\\':
static int
exprline(void)
{
- struct iobuf *ob;
+ extern int nbufused;
+ struct iobuf *ob, *rb;
struct symtab *nl;
int oCflag = Cflag;
- usch *bp = stringbuf, *dp;
+ usch *dp;
int c, d, ifdef;
+ rb = getobuf(BNORMAL);
+ nbufused--;
Cflag = ifdef = 0;
- while ((c = inch()) != '\n') {
- if (c == '\'' || c == '\"') {
- faststr(c, savch);
- continue;
+ for (;;) {
+ c = inch();
+xloop: if (c == '\n')
+ break;
+ if (c == '.') {
+ putob(rb, '.');
+ if ((spechr[c = inch()] & C_DIGIT) == 0)
+ goto xloop;
}
- if (ISDIGIT(c) || c == '.') {
- c = fastnum(c, savch);
- if (c == '\n')
- break;
- unch(c);
+ if (ISDIGIT(c)) {
+ c = fastnum(c, rb);
+ goto xloop;
+ }
+ if (c == '\'' || c == '\"') {
+ faststr(c, rb);
continue;
}
if (c == 'L' || c == 'u' || c == 'U') {
if (ISID0(c)) {
dp = readid(c);
nl = lookup(dp, FIND);
- if (nl && *nl->value == DEFLOC) {
+ if (nl && nl->type == DEFLOC) {
ifdef = 1;
} else if (ifdef) {
- savch(nl ? '1' : '0');
+ putob(rb, nl ? '1' : '0');
ifdef = 0;
} else if (nl != NULL) {
inexpr = 1;
if ((ob = kfind(nl))) {
- putob(ob, 0);
- savstr(ob->buf);
+ ob->buf[ob->cptr] = 0;
+ strtobuf(ob->buf, rb);
bufree(ob);
} else
- savch('0');
+ putob(rb, '0');
inexpr = 0;
} else
- savch('0');
+ putob(rb, '0');
} else
- savch(c);
+ putob(rb, c);
}
- savch(0);
+ rb->buf[rb->cptr] = 0;
unch('\n');
- yyinp = bp;
+ yyinp = rb->buf;
c = yyparse();
- stringbuf = bp;
+ bufree(rb);
+ nbufused++;
Cflag = oCflag;
return c;
}
return ch;
}
-/*
- * Let the command-line args be faked defines at beginning of file.
- */
-static void
-prinit(struct initar *it, struct includ *ic)
-{
- const char *pre, *post;
- char *a;
-
- if (it->next)
- prinit(it->next, ic);
- pre = post = NULL; /* XXX gcc */
- switch (it->type) {
- case 'D':
- pre = "#define ";
- if ((a = strchr(it->str, '=')) != NULL) {
- *a = ' ';
- post = "\n";
- } else
- post = " 1\n";
- break;
- case 'U':
- pre = "#undef ";
- post = "\n";
- break;
- case 'i':
- pre = "#include \"";
- post = "\"\n";
- break;
- default:
- error("prinit");
- }
- strlcat((char *)ic->buffer, pre, CPPBUF+1);
- strlcat((char *)ic->buffer, it->str, CPPBUF+1);
- if (strlcat((char *)ic->buffer, post, CPPBUF+1) >= CPPBUF+1)
- error("line exceeds buffer size");
-
- ic->lineno--;
- while (*ic->maxread)
- ic->maxread++;
-}
-
/*
* A new file included.
* If ifiles == NULL, this is the first file and already opened (stdin).
int
pushfile(const usch *file, const usch *fn, int idx, void *incs)
{
- extern struct initar *initar;
struct includ ibuf;
struct includ *ic;
int otrulvl;
ic->infil = 0;
ic->orgfn = ic->fname = (const usch *)"<stdin>";
}
-#ifndef BUF_STACK
- ic->bbuf = malloc(BBUFSZ);
+#if LIBVMF
+ if (ifiles) {
+ vmmodify(ifiles->vseg);
+ vmunlock(ifiles->vseg);
+ }
+ ic->vseg = vmmapseg(&ibspc, inclevel);
+ vmlock(ic->vseg);
#endif
- ic->buffer = ic->bbuf+PBMAX;
- ic->curptr = ic->buffer;
ifiles = ic;
+ ic->ib = getobuf(BINBUF);
ic->lineno = 1;
ic->escln = 0;
ic->maxread = ic->curptr;
ic->incs = incs;
ic->fn = fn;
prtline(1);
- if (initar) {
- int oin = ic->infil;
- ic->infil = -1;
- *ic->maxread = 0;
- prinit(initar, ic);
- initar = NULL;
- if (dMflag)
- printf("%s", (char *)ic->buffer);
- fastscan();
- prtline(1);
- ic->infil = oin;
- }
-
otrulvl = trulvl;
fastscan();
if (otrulvl != trulvl || flslvl)
error("unterminated conditional");
-#ifndef BUF_STACK
- free(ic->bbuf);
-#endif
ifiles = ic->next;
- close(ic->infil);
inclevel--;
+#if LIBVMF
+ vmmodify(ic->vseg);
+ vmunlock(ic->vseg);
+ ic->ib->ro = 1; /* XXX no free */
+ if (ifiles) {
+ int diff;
+
+ ifiles->vseg = vmmapseg(&ibspc, inclevel);
+ vmlock(ifiles->vseg);
+ /* XXX recalc ptr diffs */
+ diff = (usch *)ifiles->vseg->s_cinfo - ifiles->bbuf;
+ ifiles->bbuf += diff;
+ ifiles->maxread += diff;
+ ifiles->curptr += diff;
+ }
+#endif
+ close(ic->infil);
+ bufree(ic->ib);
return 0;
}
return; /* no output */
if (ifiles->lineno == 1 &&
(MMDflag == 0 || ifiles->idx != SYSINC)) {
- printf("%s: %s\n", Mfile, ifiles->fname);
+ ob = bsheap(0, "%s: %s\n", Mfile, ifiles->fname);
if (MPflag &&
strcmp((const char *)ifiles->fname, (char *)MPfile))
- printf("%s:\n", ifiles->fname);
+ bsheap(ob, "%s:\n", ifiles->fname);
+ write(1, ob->buf, ob->cptr);
+ bufree(ob);
}
} else if (!Pflag) {
- ob = bsheap(0, "\n# %d \"%s\"", ifiles->lineno, ifiles->fname);
+ bsheap(&pb, "\n# %d \"%s\"", ifiles->lineno, ifiles->fname);
if (ifiles->idx == SYSINC)
- bsheap(ob, " 3");
- if (nl) bsheap(ob, "\n");
- putstr(ob->buf);
- bufree(ob);
+ strtobuf((usch *)" 3", &pb);
+ if (nl) strtobuf((usch *)"\n", &pb);
}
}
error("#elif in non-conditional section");
}
-/* save line into stringbuf */
-static usch *
+/* save line into iobuf */
+static struct iobuf *
savln(void)
{
+ struct iobuf *ob = getobuf(BNORMAL);
int c;
- usch *cp = stringbuf;
while ((c = inch()) != -1) {
if (c == '\n') {
unch(c);
break;
}
- savch(c);
+ putob(ob, c);
}
- savch(0);
-
- return cp;
+ ob->buf[ob->cptr] = 0;
+ return ob;
}
static void
cpperror(void)
{
- usch *cp;
-
- cp = savln();
- error("#error %s", cp);
- stringbuf = cp;
+ struct iobuf *ob = savln();
+ error("#error %s", ob->buf);
+ bufree(ob);
}
static void
cppwarning(void)
{
- usch *cp;
-
- cp = savln();
- warning("#warning %s", cp);
- stringbuf = cp;
+ struct iobuf *ob = savln();
+ error("#warning %s", ob->buf);
+ bufree(ob);
}
static void
if (ob)
bufree(ob);
} else if (ch == '\"') {
- faststr(ch, savch);
+ bufree(faststr(ch, NULL));
+
} else
goto bad;
chknl(1);