commit 06411a4af49b020ced2d40e295afe72605caaec8
parent 5d75fa9ad62267658ce6ee314cd185fb02510960
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Sat, 23 May 2015 19:06:18 +0200
Add ifdef and ifndef clauses
This is a first versin, but it is functional. There is some points that are
not very elegant, but they can be solved later.
Diffstat:
3 files changed, 66 insertions(+), 6 deletions(-)
diff --git a/cc1/cc1.h b/cc1/cc1.h
@@ -266,6 +266,7 @@ extern void extdecl(void), decl(void);
/* lex.c */
extern char ahead(void);
extern unsigned next(void);
+extern bool moreinput(void);
extern void expect(unsigned tok);
extern void discard(void);
extern char *getfname(void);
diff --git a/cc1/cpp.c b/cc1/cpp.c
@@ -13,6 +13,7 @@
static char *argp;
static unsigned arglen;
+static unsigned numif;
static Symbol *lastmacro;
static void
@@ -266,7 +267,6 @@ mkdefine(char *s, Symbol *sym)
static char *
define(char *s)
{
- extern char yytext[];
char *t;
size_t len;
Symbol *sym;
@@ -391,6 +391,59 @@ usererr(char *s)
exit(-1);
}
+static char *
+ifclause(char *s, int isdef)
+{
+ unsigned curif, len;
+ char *endp;
+ Symbol *sym;
+
+
+ while (isspace(*s))
+ ++s;
+ for (endp = s; isalnum(*endp) || *endp == '_'; ++endp)
+ /* nothing */;
+ if ((len = endp - s) > IDENTSIZ)
+ error("...");
+ memcpy(yytext, s, len);
+ yytext[len] = '\0';
+ while (isspace(*endp))
+ ++endp;
+ if (*endp != '\0')
+ error("trailing characters after preprocessor directive");
+
+ curif = numif++;
+ sym = lookup(NS_CPP);
+ if ((sym->flags & ISDEFINED) != 0 == isdef)
+ return endp;
+ while (curif != numif) {
+ if (!moreinput())
+ error("found EOF while ...");
+ }
+ return "";
+}
+
+static char *
+ifdef(char *s)
+{
+ return ifclause(s, 1);
+}
+
+static char *
+ifndef(char *s)
+{
+ return ifclause(s, 0);
+}
+
+static char *
+endif(char *s)
+{
+ if (numif == 0)
+ error("#endif without #if");
+ --numif;
+ return NULL;
+}
+
char *
preprocessor(char *p)
{
@@ -402,6 +455,9 @@ preprocessor(char *p)
} *bp, cmds[] = {
"define", define,
"include", include,
+ "ifdef", ifdef,
+ "ifndef", ifndef,
+ "endif", endif,
"line", line,
"pragma", pragma,
"error", usererr,
@@ -425,9 +481,10 @@ preprocessor(char *p)
for (bp = cmds; bp->name; ++bp) {
if (strncmp(bp->name, p, n))
continue;
- q = (*bp->fun)(q);
- while (isspace(*q++))
- /* nothing */;
+ if ((q = (*bp->fun)(q)) == NULL)
+ return NULL;
+ while (isspace(*q))
+ ++q;
if (*q != '\0')
error("trailing characters after preprocessor directive");
return q;
diff --git a/cc1/lex.c b/cc1/lex.c
@@ -186,7 +186,7 @@ readline(void)
*bp = '\0';
}
-static bool
+bool
moreinput(void)
{
char *p;
@@ -202,7 +202,9 @@ repeat:
*(p = input->line) = '\0';
readline();
- if (*(p = preprocessor(p)) == '\0')
+ if ((p = preprocessor(p)) == NULL)
+ return 1;
+ if (*p == '\0')
goto repeat;
input->p = input->begin = p;
return 1;