ref: d79edf98b8d3dd8c1cbf9ad1be7728e13ed7a364
parent: ec19c5697f3caf52e6be57049169e2eb048299e6
author: Jacob Moody <moody@posixcafe.org>
date: Tue Mar 21 17:24:16 EDT 2023
cpp: #pragma once support
--- a/sys/src/cmd/cpp/cpp.c
+++ b/sys/src/cmd/cpp/cpp.c
@@ -85,6 +85,7 @@
{
Nlist *np;
Token *tp;
+ Dir *d;
tp = trp->tp;
if (tp->type!=NAME) {
@@ -148,7 +149,17 @@
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:
--- 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 Cplusplus;
extern Nlist *kwdefined;
extern Includelist includelist[NINCLUDE];
+extern Qid incblocked[NONCE];
+extern int nblocked;
extern char wd[];
--- a/sys/src/cmd/cpp/include.c
+++ b/sys/src/cmd/cpp/include.c
@@ -6,6 +6,9 @@
char *objname;
+Qid incblocked[NONCE];
+int nblocked = 0;
+
void
doinclude(Tokenrow *trp)
{
@@ -12,6 +15,7 @@
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 @@
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);