diff options
author | Jacob Moody <moody@posixcafe.org> | 2023-03-21 21:24:16 +0000 |
---|---|---|
committer | Jacob Moody <moody@posixcafe.org> | 2023-03-21 21:24:16 +0000 |
commit | d79edf98b8d3dd8c1cbf9ad1be7728e13ed7a364 (patch) | |
tree | b56605292a50c28e7e8c2e1e83b91f2f7a5a259b /sys | |
parent | ec19c5697f3caf52e6be57049169e2eb048299e6 (diff) |
cpp: #pragma once support
Diffstat (limited to 'sys')
-rw-r--r-- | sys/src/cmd/cpp/cpp.c | 13 | ||||
-rw-r--r-- | sys/src/cmd/cpp/cpp.h | 3 | ||||
-rw-r--r-- | sys/src/cmd/cpp/include.c | 13 |
3 files changed, 28 insertions, 1 deletions
diff --git a/sys/src/cmd/cpp/cpp.c b/sys/src/cmd/cpp/cpp.c index 2a49ea8bc..aed6ecb7c 100644 --- a/sys/src/cmd/cpp/cpp.c +++ b/sys/src/cmd/cpp/cpp.c @@ -85,6 +85,7 @@ control(Tokenrow *trp) { Nlist *np; Token *tp; + Dir *d; tp = trp->tp; if (tp->type!=NAME) { @@ -148,7 +149,17 @@ control(Tokenrow *trp) break; case KPRAGMA: - return; + tp += 1; + if (tp->type!=NAME || tp->len < 4 || memcmp(tp->t, "once", 4) != 0) + return; + if (nblocked >= NONCE) + error(FATAL, "#pragma once list max length exceeded"); + d = dirfstat(cursource->fd); + if (d == nil) + error(FATAL, "Out of memory from dirfstat"); + incblocked[nblocked++] = d->qid; + free(d); + break; case KIFDEF: case KIFNDEF: diff --git a/sys/src/cmd/cpp/cpp.h b/sys/src/cmd/cpp/cpp.h index 25a832a12..0d5a5c269 100644 --- a/sys/src/cmd/cpp/cpp.h +++ b/sys/src/cmd/cpp/cpp.h @@ -2,6 +2,7 @@ #define OBS 4096 /* outbut buffer */ #define NARG 64 /* Max number arguments to a macro */ #define NINCLUDE 64 /* Max number of include directories (-I) */ +#define NONCE 256 /* Max number of #pragma once directives */ #define NIF 32 /* depth of nesting of #if */ #ifndef EOF #define EOF (-1) @@ -153,4 +154,6 @@ extern int verbose; extern int Cplusplus; extern Nlist *kwdefined; extern Includelist includelist[NINCLUDE]; +extern Qid incblocked[NONCE]; +extern int nblocked; extern char wd[]; diff --git a/sys/src/cmd/cpp/include.c b/sys/src/cmd/cpp/include.c index a4e716482..347916981 100644 --- a/sys/src/cmd/cpp/include.c +++ b/sys/src/cmd/cpp/include.c @@ -6,12 +6,16 @@ Includelist includelist[NINCLUDE]; char *objname; +Qid incblocked[NONCE]; +int nblocked = 0; + void doinclude(Tokenrow *trp) { char fname[256], iname[256], *p; Includelist *ip; int angled, len, fd, i; + Dir *d; trp->tp += 1; if (trp->tp>=trp->lp) @@ -87,6 +91,15 @@ doinclude(Tokenrow *trp) write(1,"\n",1); } if (fd >= 0) { + d = dirfstat(fd); + if (d == nil) + error(FATAL, "Out of memory from dirfstat"); + for (i=0; i<nblocked; i++) + if (incblocked[i].path == d->qid.path && incblocked[i].type == d->qid.type) { + free(d); + return; + } + free(d); if (++incdepth > 20) error(FATAL, "#include too deeply nested"); setsource((char*)newstring((uchar*)iname, strlen(iname), 0), fd, NULL); |