summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJacob Moody <moody@posixcafe.org>2023-03-21 21:24:16 +0000
committerJacob Moody <moody@posixcafe.org>2023-03-21 21:24:16 +0000
commitd79edf98b8d3dd8c1cbf9ad1be7728e13ed7a364 (patch)
treeb56605292a50c28e7e8c2e1e83b91f2f7a5a259b /sys
parentec19c5697f3caf52e6be57049169e2eb048299e6 (diff)
cpp: #pragma once support
Diffstat (limited to 'sys')
-rw-r--r--sys/src/cmd/cpp/cpp.c13
-rw-r--r--sys/src/cmd/cpp/cpp.h3
-rw-r--r--sys/src/cmd/cpp/include.c13
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);