# HG changeset patch
# User David A. Holland
# Date 1364709896 14400
# Node ID f50b4ea6cbfef5ea945709f7fc375ac7a2ea0634
# Parent  5e24746d83355807779b785ac84a74fee204a82b
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.

diff -r 5e24746d8335 -r f50b4ea6cbfe directive.c
--- 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);