shithub: scc

Download patch

ref: 06411a4af49b020ced2d40e295afe72605caaec8
parent: 5d75fa9ad62267658ce6ee314cd185fb02510960
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sat May 23 15:06:18 EDT 2015

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.

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -266,6 +266,7 @@
 /* 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);
--- 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 @@
 static char *
 define(char *s)
 {
-	extern char yytext[];
 	char *t;
 	size_t len;
 	Symbol *sym;
@@ -391,6 +391,59 @@
 	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 @@
 	} *bp, cmds[] =  {
 		"define", define,
 		"include", include,
+		"ifdef", ifdef,
+		"ifndef", ifndef,
+		"endif", endif,
 		"line", line,
 		"pragma", pragma,
 		"error", usererr,
@@ -425,9 +481,10 @@
 	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;
--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -186,7 +186,7 @@
 	*bp = '\0';
 }
 
-static bool
+bool
 moreinput(void)
 {
 	char *p;
@@ -202,7 +202,9 @@
 
 	*(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;