URI:
       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