diff directive.c @ 64:f50b4ea6cbfe

Prune single-line comments from (most) directive lines. Also, don't pass the string length to the directive processing functions, as half of them weren't honoring it. Instead, ensure that the directive line is terminated at the place the directive processing functions should stop looking at it.
author David A. Holland
date Sun, 31 Mar 2013 02:04:56 -0400
parents 90c6052410ce
children f8507e5ed84c
line wrap: on
line diff
--- a/directive.c	Sun Mar 31 02:02:16 2013 -0400
+++ b/directive.c	Sun Mar 31 02:04:56 2013 -0400
@@ -57,6 +57,41 @@
 
 static
 void
+uncomment(char *buf)
+{
+	char *s, *t, *u = NULL;
+	bool incomment = false;
+
+	for (s = t = buf; *s; s++) {
+		if (incomment) {
+			if (s[0] == '*' && s[1] == '/') {
+				s++;
+				incomment = false;
+			}
+		} else {
+			if (s[0] == '/' && s[1] == '*') {
+				incomment = true;
+			} else {
+				if (t != s) {
+					*t = *s;
+				}
+				if (!strchr(ws, *t)) {
+					u = t;
+				}
+				t++;
+			}
+		}
+	}
+	if (u) {
+		/* end string after last non-whitespace char */
+		u[1] = '\0';
+	} else {
+		*t = '\0';
+	}
+}
+
+static
+void
 oneword(const char *what, struct place *p2, char *line)
 {
 	size_t pos;
@@ -119,13 +154,14 @@
 
 static
 void
-d_if(struct place *p, struct place *p2, char *line, size_t len)
+d_if(struct place *p, struct place *p2, char *line)
 {
 	char *expr;
 	bool val;
 	struct place p3 = *p2;
 
-	expr = macroexpand(p2, line, len, true);
+	uncomment(line);
+	expr = macroexpand(p2, line, strlen(line), true);
 	val = eval(&p3, expr);
 	ifstate_push(p, val);
 	dostrfree(expr);
@@ -133,23 +169,25 @@
 
 static
 void
-d_ifdef(struct place *p, struct place *p2, char *line, size_t len)
+d_ifdef(struct place *p, struct place *p2, char *line)
 {
+	uncomment(line);
 	oneword("#ifdef", p2, line);
 	ifstate_push(p, macro_isdefined(line));
 }
 
 static
 void
-d_ifndef(struct place *p, struct place *p2, char *line, size_t len)
+d_ifndef(struct place *p, struct place *p2, char *line)
 {
+	uncomment(line);
 	oneword("#ifndef", p2, line);
 	ifstate_push(p, !macro_isdefined(line));
 }
 
 static
 void
-d_elif(struct place *p, struct place *p2, char *line, size_t len)
+d_elif(struct place *p, struct place *p2, char *line)
 {
 	char *expr;
 	struct place p3 = *p2;
@@ -162,7 +200,8 @@
 	if (ifstate->evertrue) {
 		ifstate->curtrue = false;
 	} else {
-		expr = macroexpand(p2, line, len, true);
+		uncomment(line);
+		expr = macroexpand(p2, line, strlen(line), true);
 		ifstate->curtrue = eval(&p3, expr);
 		ifstate->evertrue = ifstate->curtrue;
 		dostrfree(expr);
@@ -171,7 +210,7 @@
 
 static
 void
-d_else(struct place *p, struct place *p2, char *line, size_t len)
+d_else(struct place *p, struct place *p2, char *line)
 {
 	if (ifstate->seenelse) {
 		complain(p, "Multiple #else directives in one conditional");
@@ -185,7 +224,7 @@
 
 static
 void
-d_endif(struct place *p, struct place *p2, char *line, size_t len)
+d_endif(struct place *p, struct place *p2, char *line)
 {
 	if (ifstate->prev == NULL) {
 		complain(p, "Unmatched #endif");
@@ -200,7 +239,7 @@
 
 static
 void
-d_define(struct place *p, struct place *p2, char *line, size_t len)
+d_define(struct place *p, struct place *p2, char *line)
 {
 	size_t pos, argpos;
 	struct place p3, p4;
@@ -263,8 +302,9 @@
 
 static
 void
-d_undef(struct place *p, struct place *p2, char *line, size_t len)
+d_undef(struct place *p, struct place *p2, char *line)
 {
+	uncomment(line);
 	oneword("#undef", p2, line);
 	macro_undef(line);
 }
@@ -274,8 +314,11 @@
 
 static
 bool
-tryinclude(struct place *p, char *line, size_t len)
+tryinclude(struct place *p, char *line)
 {
+	size_t len;
+
+	len = strlen(line);
 	if (len > 2 && line[0] == '"' && line[len-1] == '"') {
 		line[len-1] = '\0';
 		file_readquote(p, line+1);
@@ -293,15 +336,16 @@
 
 static
 void
-d_include(struct place *p, struct place *p2, char *line, size_t len)
+d_include(struct place *p, struct place *p2, char *line)
 {
 	char *text;
 
-	if (tryinclude(p, line, len)) {
+	uncomment(line);
+	if (tryinclude(p, line)) {
 		return;
 	}
-	text = macroexpand(p2, line, len, false);
-	if (tryinclude(p, text, strlen(text))) {
+	text = macroexpand(p2, line, strlen(line), false);
+	if (tryinclude(p, text)) {
 		dostrfree(text);
 		return;
 	}
@@ -312,7 +356,7 @@
 
 static
 void
-d_line(struct place *p, struct place *p2, char *line, size_t len)
+d_line(struct place *p, struct place *p2, char *line)
 {
 	/* XXX */
 	complain(p, "Sorry, no #line yet");
@@ -323,11 +367,11 @@
 
 static
 void
-d_warning(struct place *p, struct place *p2, char *line, size_t len)
+d_warning(struct place *p, struct place *p2, char *line)
 {
 	char *msg;
 
-	msg = macroexpand(p2, line, len, false);
+	msg = macroexpand(p2, line, strlen(line), false);
 	complain(p, "#warning: %s", msg);
 	if (mode.werror) {
 		complain_fail();
@@ -337,11 +381,11 @@
 
 static
 void
-d_error(struct place *p, struct place *p2, char *line, size_t len)
+d_error(struct place *p, struct place *p2, char *line)
 {
 	char *msg;
 
-	msg = macroexpand(p2, line, len, false);
+	msg = macroexpand(p2, line, strlen(line), false);
 	complain(p, "#error: %s", msg);
 	complain_fail();
 	dostrfree(msg);
@@ -352,7 +396,7 @@
 
 static
 void
-d_pragma(struct place *p, struct place *p2, char *line, size_t len)
+d_pragma(struct place *p, struct place *p2, char *line)
 {
 	complain(p, "#pragma %s", line);
 	complain_fail();
@@ -364,7 +408,7 @@
 static const struct {
 	const char *name;
 	bool ifskip;
-	void (*func)(struct place *, struct place *, char *line, size_t len);
+	void (*func)(struct place *, struct place *, char *line);
 } directives[] = {
 	{ "define",  true,  d_define },
 	{ "elif",    false, d_elif },
@@ -384,7 +428,7 @@
 
 static
 void
-directive_gotdirective(struct place *p, char *line, size_t linelen)
+directive_gotdirective(struct place *p, char *line)
 {
 	struct place p2;
 	size_t len, skip;
@@ -401,9 +445,13 @@
 			skip = len + strspn(line+len, ws);
 			p2.column += skip;
 			line += skip;
-			linelen -= skip;
-			linelen = notrailingws(line, linelen);
-			directives[i].func(p, &p2, line, linelen);
+
+			len = strlen(line);
+			len = notrailingws(line, len);
+			if (len < strlen(line)) {
+				line[len] = '\0';
+			}
+			directives[i].func(p, &p2, line);
 			return;
 		}
 	}
@@ -526,10 +574,19 @@
 	/* check if we have a directive line */
 	skip = strspn(line + acomm, ws);
 	if (acomm == 0 && line[skip] == '#') {
+		char ch;
+
 		skip = skip + 1 + strspn(line + skip + 1, ws);
 		assert(skip <= text);
 		p->column += skip;
-		directive_gotdirective(p, line+skip, text-skip);
+		assert(line[len] == '\0');
+		/* ensure null termination for directives */
+		ch = line[text];
+		if (ch != '\0') {
+			line[text] = '\0';
+		}
+		directive_gotdirective(p, line+skip /*, length = text-skip */);
+		line[text] = ch;
 		p->column += text-skip;
 	} else if (ifstate->curtrue) {
 		macro_sendline(p, line + acomm, text);