shithub: scc

Download patch

ref: 432127aad4a212d5d02dd74d9c7340ef68a85804
parent: 06411a4af49b020ced2d40e295afe72605caaec8
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sat May 23 16:03:06 EDT 2015

Improve ifdef/ifndef

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -290,7 +290,7 @@
 extern Node *expr(void), *negate(Node *np);
 
 /* cpp.c */
-extern char *preprocessor(char *s);
+extern bool preprocessor(char *s);
 extern bool expand(Symbol *sym);
 
 /*
--- a/cc1/cpp.c
+++ b/cc1/cpp.c
@@ -13,8 +13,16 @@
 
 static char *argp;
 static unsigned arglen;
-static unsigned numif;
+static unsigned numif, iffalse;
 static Symbol *lastmacro;
+static void
+cleanup(char *s)
+{
+	while (isspace(*s))
+		++s;
+	if (*s != '\0')
+		error("trailing characters after preprocessor directive");
+}
 
 static void
 nextcpp(void)
@@ -264,7 +272,7 @@
 	return s;
 }
 
-static char *
+static bool
 define(char *s)
 {
 	char *t;
@@ -291,7 +299,9 @@
 		/* nothing */;
 	for (t = s + strlen(s); isspace(*--t); *t = '\0')
 		/* nothing */;
-	return mkdefine(s, sym);
+	s = mkdefine(s, sym);
+	cleanup(s);
+	return 1;
 
 too_long:
 	error("macro identifier too long");
@@ -299,7 +309,7 @@
 	error("macro names must be identifiers");
 }
 
-static char *
+static bool
 include(char *s)
 {
 	char fname[FILENAME_MAX], delim, c, *p;
@@ -329,7 +339,8 @@
 		abort();
 	}
 
-	return p+1;
+	cleanup(p+1);
+	return 1;
 
 not_found:
 	error("included file '%s' not found", fname);
@@ -339,7 +350,7 @@
 	error("#include expects \"FILENAME\" or <FILENAME>");
 }
 
-static char *
+static bool
 line(char *s)
 {
 	char *p, *q;
@@ -364,8 +375,10 @@
 		p = q+1;
 		/* passthrough */
 	case '\0':
+		/* TODO: check this atoi */
 		setfline(atoi(s)-1);
-		return p;
+		cleanup(p);
+		return 1;
 	default:
 		goto bad_file;
 	}
@@ -376,22 +389,20 @@
 	error("first parameter of #line is not a positive integer");
 }
 
-static char *
+static bool
 pragma(char *s)
 {
-	while (*s)
-		++s;
-	return s;
+	cleanup(s);
+	return 1;
 }
 
-static char *
+static bool
 usererr(char *s)
 {
-	fprintf(stderr, "%s:%u:error: #error %s\n", getfname(), getfline(), s);
-	exit(-1);
+	error("#error %s", s);
 }
 
-static char *
+static bool
 ifclause(char *s, int isdef)
 {
 	unsigned curif, len;
@@ -398,7 +409,6 @@
 	char *endp;
 	Symbol *sym;
 
-
 	while (isspace(*s))
 		++s;
 	for (endp = s; isalnum(*endp) || *endp == '_'; ++endp)
@@ -407,44 +417,47 @@
 		error("...");
 	memcpy(yytext, s, len);
 	yytext[len] = '\0';
-	while (isspace(*endp))
-		++endp;
-	if (*endp != '\0')
-		error("trailing characters after preprocessor directive");
-
+	cleanup(endp);
 	curif = numif++;
-	sym = lookup(NS_CPP);
-	if ((sym->flags & ISDEFINED) != 0 == isdef)
-		return endp;
+
+	if (iffalse != 0) {
+		sym = lookup(NS_CPP);
+		if ((sym->flags & ISDEFINED) != 0 == isdef)
+			return 1;
+	}
+
+	++iffalse;
 	while (curif != numif) {
 		if (!moreinput())
 			error("found EOF while ...");
 	}
-	return "";
+	--iffalse;
+
+	return 1;
 }
 
-static char *
+static bool
 ifdef(char *s)
 {
 	return ifclause(s, 1);
 }
 
-static char *
+static bool
 ifndef(char *s)
 {
 	return ifclause(s, 0);
 }
 
-static char *
+static bool
 endif(char *s)
 {
 	if (numif == 0)
 		error("#endif without #if");
 	--numif;
-	return NULL;
+	return iffalse == 0;
 }
 
-char *
+bool
 preprocessor(char *p)
 {
 	char *q;
@@ -451,7 +464,7 @@
 	unsigned short n;
 	static struct {
 		char *name;
-		char *(*fun)(char *);
+		bool (*fun)(char *);
 	} *bp, cmds[] =  {
 		"define", define,
 		"include", include,
@@ -467,11 +480,11 @@
 	while (isspace(*p))
 		++p;
 	if (*p != '#')
-		return p;
+		return 0;
 	for (++p; isspace(*p); ++p)
 		/* nothing */;
 	if (*p == '\0')
-		return p;
+		return 1;
 	for (q = p; isalpha(*q); ++q)
 		/* nothing */;
 	if ((n = q - p) == 0)
@@ -481,13 +494,7 @@
 	for (bp = cmds; bp->name; ++bp) {
 		if (strncmp(bp->name, p, n))
 			continue;
-		if ((q = (*bp->fun)(q)) == NULL)
-			return NULL;
-		while (isspace(*q))
-			++q;
-		if (*q != '\0')
-			error("trailing characters after preprocessor directive");
-		return q;
+		return (*bp->fun)(q);
 	}
 incorrect:
 	error("incorrect preprocessor directive");
--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -202,9 +202,7 @@
 
 	*(p = input->line) = '\0';
 	readline();
-	if ((p = preprocessor(p)) == NULL)
-		return 1;
-	if (*p == '\0')
+	if (preprocessor(p))
 		goto repeat;
 	input->p = input->begin = p;
 	return 1;