cc1: Add hideset by input - scc - simple c99 compiler
HTML git clone git://git.simple-cc.org/scc
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
DIR commit d59f0b5d2d11178047efaa052eb6659e48bb827e
DIR parent cd2e378821e5e5f86215643e87a6b806a8b54492
HTML Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date: Tue, 16 Jun 2026 22:07:09 +0200
cc1: Add hideset by input
Having a hideset by input allows to follow the Prosser algorithm [1],
because hideset changes happens only when expansions happen, so we
can continue using the push up input streams to implemenet the algorithm
while we maintain the hideset for every new input push up.
[1] https://www.spinellis.gr/blog/20060626/cpp.algo.pdf
Diffstat:
M src/cmd/scc-cc/cc1/cc1.h | 4 +++-
M src/cmd/scc-cc/cc1/cpp.c | 76 +++++++++++++++++++++++--------
M src/cmd/scc-cc/cc1/error.c | 2 ++
M src/cmd/scc-cc/cc1/lex.c | 23 +++++++++++++++++++++--
4 files changed, 82 insertions(+), 23 deletions(-)
---
DIR diff --git a/src/cmd/scc-cc/cc1/cc1.h b/src/cmd/scc-cc/cc1/cc1.h
@@ -428,7 +428,7 @@ struct macro {
};
#endif
-#ifdef stdin
+#if defined(stdin) && defined(NR_MACROARG)
struct input {
char flags;
unsigned lineno;
@@ -436,6 +436,7 @@ struct input {
FILE *fp;
Macro *macro;
char *line, *begin, *p;
+ Symbol *hideset[NR_MACROARG];
struct input *next;
};
#endif
@@ -530,6 +531,7 @@ void defdefine(char *, char *, char *);
void undefmacro(char *);
void ppragmaln(void);
void delmacro(Macro *);
+void sethideset(Input *), unsethideset(Input *);
Macro *newmacro(Symbol *);
Node *defined(void);
DIR diff --git a/src/cmd/scc-cc/cc1/cpp.c b/src/cmd/scc-cc/cc1/cpp.c
@@ -361,6 +361,7 @@ expandarg(char *arg, char *def, char *curdef, char *buf, int bufsiz)
buf += siz;
}
} else {
+ disexpand++;
addinput(IPARAM, arg, FAIL);
for (siz = 0; ; siz += yylen) {
yyspace = '\0';
@@ -383,6 +384,7 @@ expandarg(char *arg, char *def, char *curdef, char *buf, int bufsiz)
}
delinput();
+ disexpand--;
}
*buf = '\0';
@@ -472,13 +474,19 @@ expansion_too_long:
error("macro expansion of \"%s\" too long", mp->sym->name);
}
+/*
+ * Functions to deal with macro hidesets. Yes, this sucks, a lot,
+ * but before blaming me read
+ * https://www.spinellis.gr/blog/20060626/cpp.algo.pdf
+ * It is not my fault.
+ */
static void
-addhideset(Input *ip, Symbol *sym)
+addhideset(Symbol *sym)
{
- Symbol **set;
- Symbol **p;
+ char *iname;
+ Symbol **set, **p;
- set = ip->macro->hideset;
+ set = input->hideset;
for (p = set; p < &set[NR_MACROARG] && *p; ++p) {
if (*p == sym)
return;
@@ -489,7 +497,7 @@ addhideset(Input *ip, Symbol *sym)
*p = sym;
DBG("MACRO Adding %s to hideset of %s",
- sym->name, ip->macro->sym->name);
+ sym->name, input->macro->sym->name);
}
static void
@@ -507,6 +515,26 @@ unhide(Symbol *sym)
}
void
+unsethideset(Input *ip)
+{
+ Symbol **set, **p;
+
+ set = ip->hideset;
+ for (p = set; p < &set[NR_MACROARG] && *p; ++p)
+ unhide(*p);
+}
+
+void
+sethideset(Input *ip)
+{
+ Symbol **set, **p;
+
+ set = ip->hideset;
+ for (p = set; p < &set[NR_MACROARG] && *p; ++p)
+ hide(*p);
+}
+
+void
delmacro(Macro *mp)
{
int i;
@@ -520,9 +548,6 @@ delmacro(Macro *mp)
free(mp->arglist[i]);
}
- for (p = mp->hideset; p < &mp->hideset[NR_MACROARG] && *p; ++p)
- unhide(*p);
-
free(mp->arglist);
free(mp);
}
@@ -532,8 +557,7 @@ newmacro(Symbol *sym)
{
Macro *mp;
- mp = xmalloc(sizeof(*mp));
- *mp = (Macro) {0};
+ mp = memset(xmalloc(sizeof(*mp)), 0, sizeof(*mp));
mp->sym = sym;
mp->def = sym->u.s + 3;
if (sym->u.s)
@@ -542,13 +566,27 @@ newmacro(Symbol *sym)
return mp;
}
+static void
+intersect(Symbol **dst, Symbol **set)
+{
+ Symbol *sym, **cur, **p;
+
+ for (cur = dst; sym = *cur; ++cur) {
+ for (p = set; *p && *p != sym; ++p)
+ ;
+ if (*p)
+ *dst++ = sym;
+ }
+
+ while (dst != cur)
+ *dst++ = NULL;
+}
+
int
expand(Symbol *sym)
{
int siz;
Macro *mp;
- Input *ip;
- Symbol **p;
DBG("MACRO '%s' detected disexpand=%d hide=%d",
sym->name, disexpand, sym->hide);
@@ -558,27 +596,25 @@ expand(Symbol *sym)
mp = newmacro(sym);
mp->fname = filenam;
+ memcpy(mp->hideset, input->hideset, sizeof(mp->hideset));
if (!parsepars(mp)) {
delmacro(mp);
return 0;
}
+ if (mp->npars != -1)
+ intersect(mp->hideset, input->hideset);
addinput(IMACRO, mp, FAIL);
+ addhideset(sym);
+ hide(sym);
+
mp->buffer = input->line;
mp->bufsiz = INPUTSIZ-1;
siz = copymacro(mp);
mp->buffer[siz] = '\0';
- for (ip = input; ip; ip = ip->next) {
- if ((ip->flags & ITYPE) == IMACRO)
- addhideset(ip, sym);
- }
-
- for (p = mp->hideset; p < &mp->hideset[NR_MACROARG] && *p; ++p)
- hide(*p);
-
DBG("MACRO '%s' expanded to :'%s'", mp->sym->name, mp->buffer);
return 1;
DIR diff --git a/src/cmd/scc-cc/cc1/error.c b/src/cmd/scc-cc/cc1/error.c
@@ -2,7 +2,9 @@
#include <stdio.h>
#include <stdlib.h>
+#include <scc/cstd.h>
#include <scc/scc.h>
+
#include "cc1.h"
#define MAXERRNUM 10
DIR diff --git a/src/cmd/scc-cc/cc1/lex.c b/src/cmd/scc-cc/cc1/lex.c
@@ -60,7 +60,7 @@ addinput(int type, void *arg, int fail)
char *extp, *fname, *buffer, *infile;
int infileln;
Macro *mp;
- Symbol *sym;
+ Symbol *sym, **hs;
Input *newip, *curip = input;
if (curip)
@@ -122,6 +122,9 @@ addinput(int type, void *arg, int fail)
buffer = xstrdup(buffer);
}
+ if (input)
+ unsethideset(input);
+
newip = xmalloc(sizeof(*newip));
newip->next = curip;
newip->macro = mp;
@@ -130,8 +133,21 @@ addinput(int type, void *arg, int fail)
newip->lineno = 0;
newip->fp = fp;
newip->flags = type;
+ memset(newip->hideset, 0, sizeof(newip->hideset));
input = newip;
+ hs = NULL;
+ if (curip)
+ hs = curip->hideset;
+ if (type == IMACRO)
+ hs = mp->hideset;
+ if (type == IPARAM && curip)
+ hs = curip->macro->hideset;
+ if (hs) {
+ memcpy(input->hideset, hs, sizeof(input->hideset));
+ sethideset(input);
+ }
+
setloc(fname, lineno);
return 1;
}
@@ -160,13 +176,16 @@ delinput(void)
default:
abort();
}
+ unsethideset(input);
input = ip->next;
free(ip->filenam);
free(ip->line);
free(ip);
- if (input)
+ if (input) {
+ sethideset(input);
setloc(input->filenam, input->lineno);
+ }
}
static void