changeset 67:737ffe27b4bd

Merge
author Joerg Sonnenberger <joerg@bec.de>
date Sun, 31 Mar 2013 07:19:49 +0200
parents 8a204d153398 (diff) a3dd0db23b0c (current diff)
children 8eee66a25533
files tests/Makefile tests/t13.c tests/t13.good tests/t14.c tests/t14.good tests/t15.c tests/t15.good tests/t17.c tests/t17.good tests/t18.c tests/t18.good tests/t19.c tests/t19.good
diffstat 16 files changed, 179 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/directive.c	Sun Mar 31 06:45:44 2013 +0200
+++ b/directive.c	Sun Mar 31 07:19:49 2013 +0200
@@ -39,6 +39,7 @@
 #include "directive.h"
 #include "macro.h"
 #include "eval.h"
+#include "output.h"
 
 struct ifstate {
 	struct ifstate *prev;
@@ -49,6 +50,7 @@
 };
 
 static struct ifstate *ifstate;
+static bool in_multiline_comment;
 
 ////////////////////////////////////////////////////////////
 // common parsing bits
@@ -408,23 +410,138 @@
 	complain_fail();
 }
 
+/*
+ * If desired, warn about a nested comment. The comment begins at
+ * offset POS from the place P.
+ */
+static
+void
+warn_nestcomment(const struct place *p, size_t pos)
+{
+	struct place p2;
+
+	if (warns.nestcomment) {
+		p2 = *p;
+		p2.column += pos;
+		complain(p, "Warning: %c%c within comment",
+			 '/', '*');
+		if (mode.werror) {
+			complain_failed();
+		}
+	}
+}
+
+/*
+ * Check for comment delimiters in LINE. If a multi-line comment is
+ * continuing or ending, set ACOMM to its length. If a multi-line
+ * comment is starting, set BCOMM to its length. Set TEXT to the
+ * length of text that is not commented out, or that contains comments
+ * that both begin and end on this line. ACOMM + TEXT + BCOMM == LEN.
+ *
+ * Updates in_multiline_comment to the appropriate state for after
+ * this line is handled.
+ */
+static
+size_t
+directive_scancomments(const struct place *p, char *line, size_t len,
+		       size_t *acomm, size_t *text, size_t *bcomm)
+{
+	size_t pos;
+	size_t first_commentend;
+	size_t last_commentstart;
+	bool incomment;
+
+	first_commentend = len;
+	last_commentstart = len;
+	incomment = in_multiline_comment;
+	for (pos = 0; pos+1 < len; pos++) {
+		if (line[pos] == '/' && line[pos+1] == '*') {
+			if (incomment) {
+				warn_nestcomment(p, pos);
+			} else {
+				incomment = true;
+				last_commentstart = pos;
+			}
+		} else if (line[pos] == '*' && line[pos+1] == '/') {
+			if (incomment) {
+				incomment = false;
+				if (first_commentend == len) {
+					first_commentend = pos;
+				}
+				last_commentstart = len;
+			} else {
+				/* stray end-comment; should we care? */
+			}
+		}
+	}
+
+	if (in_multiline_comment && first_commentend < last_commentstart) {
+		/* multiline comment ends */
+		/* first_commentend points to the star, adjust */
+		*acomm = first_commentend + 2;
+		*text = len - *acomm;
+	} else if (in_multiline_comment) {
+		/* comment did not end, so another one cannot have started */
+		assert(last_commentstart == len);
+		*acomm = len;
+		*text = 0;
+	} else {
+		*acomm = 0;
+		*text = len;
+	}
+
+	*bcomm = len - last_commentstart;
+	*text -= *bcomm;
+
+	in_multiline_comment = incomment;
+	return len;
+}
+
 void
 directive_gotline(struct place *p, char *line, size_t len)
 {
+	size_t acomm;	/* length of comment ending on this line */
+	size_t text;	/* length of non-multi-line-comment text */
+	size_t bcomm;	/* length of comment beginning on this line */
 	size_t skip;
 
+	directive_scancomments(p, line, len, &acomm, &text, &bcomm);
+
+	if (acomm > 0) {
+		if (mode.output_retain_comments && ifstate->curtrue) {
+			/*
+			 * Do not expand the comment; send it straight
+			 * to the output. This will cause it to appear
+			 * first if we're partway through collecting a
+			 * macro argument. Too bad. This isn't a
+			 * standard mode anyway.
+			 */
+			output(p, line, acomm);
+		}
+		p->column += acomm;
+	}
+
 	/* check if we have a directive line */
-	skip = strspn(line, ws);
-	if (line[skip] == '#') {
+	skip = strspn(line + acomm, ws);
+	if (acomm == 0 && line[skip] == '#') {
 		skip = skip + 1 + strspn(line + skip + 1, ws);
+		assert(skip <= text);
 		p->column += skip;
-		directive_gotdirective(p, line+skip, len-skip);
+		directive_gotdirective(p, line+skip, text-skip);
+		p->column += text-skip;
 	} else if (ifstate->curtrue) {
-		macro_sendline(p, line, len);
+		macro_sendline(p, line + acomm, text);
+		p->column += text;
+	}
+
+	if (bcomm > 0) {
+		if (mode.output_retain_comments && ifstate->curtrue) {
+			output(p, line + acomm + text, bcomm);
+		}
+		p->column += bcomm;
 	}
 }
 
-
 void
 directive_goteof(struct place *p)
 {
--- a/tests/Makefile	Sun Mar 31 06:45:44 2013 +0200
+++ b/tests/Makefile	Sun Mar 31 07:19:49 2013 +0200
@@ -11,7 +11,8 @@
 TRADCPP_OBJDIR!=	${MAKE} -C .. -V .OBJDIR
 TRADCPP=	${TRADCPP_OBJDIR}/tradcpp
 
-TESTS=t01 t02 t03 t04 t05 t06 t07 t08 t09 t10 t11 t12 t13 t14 t15 t16
+TESTS=t01 t02 t03 t04 t05 t06 t07 t08 t09 t10 t11 t12 t13 t14 t15 t16 \
+      t17 t18 t19
 
 .for T in $(TESTS)
 run-tests: $(T).diff
--- a/tests/t07.good	Sun Mar 31 06:45:44 2013 +0200
+++ b/tests/t07.good	Sun Mar 31 07:19:49 2013 +0200
@@ -1,1 +1,3 @@
 
+
+
--- a/tests/t09.good	Sun Mar 31 06:45:44 2013 +0200
+++ b/tests/t09.good	Sun Mar 31 07:19:49 2013 +0200
@@ -1,1 +1,3 @@
- fnord 
+
+
+
--- a/tests/t13.c	Sun Mar 31 06:45:44 2013 +0200
+++ b/tests/t13.c	Sun Mar 31 07:19:49 2013 +0200
@@ -1,11 +1,4 @@
-#define a() x
-a()
-a ()
-#define b(p) p
-x/**/b(1)/**/x
-x/**/b (1)/**/x
-x/**/b()/**/x
-#define c(p,q) p/**/q
-x/**/c(1,2)/**/x
-x/**/c(1)/**/x
-x/**/c()/**/x
+/*
+#define FOO BAR
+*/
+FOO
--- a/tests/t13.good	Sun Mar 31 06:45:44 2013 +0200
+++ b/tests/t13.good	Sun Mar 31 07:19:49 2013 +0200
@@ -1,11 +1,4 @@
-x
-x
-x1x
-x1x
-xx
-x12x
-t13.c:10:1: Wrong number of arguments for macro c; found 1, expected 2
-x1x
-t13.c:11:1: Wrong number of arguments for macro c; found 0, expected 2
-xx
-FAILED
+
+
+
+FOO
--- a/tests/t14.c	Sun Mar 31 06:45:44 2013 +0200
+++ b/tests/t14.c	Sun Mar 31 07:19:49 2013 +0200
@@ -1,2 +1,4 @@
-#define file "subdir/test.h"
-#include file
+/*
+#define FOO BAR */
+FOO
+FOO
--- a/tests/t14.good	Sun Mar 31 06:45:44 2013 +0200
+++ b/tests/t14.good	Sun Mar 31 07:19:49 2013 +0200
@@ -1,1 +1,4 @@
-hello
+
+
+FOO
+FOO
--- a/tests/t15.c	Sun Mar 31 06:45:44 2013 +0200
+++ b/tests/t15.c	Sun Mar 31 07:19:49 2013 +0200
@@ -1,2 +1,3 @@
-#if FOO /* ignore me */
-#endif
+#define FOO /* BAR */ BAZ
+FOO
+FOO
--- a/tests/t15.good	Sun Mar 31 06:45:44 2013 +0200
+++ b/tests/t15.good	Sun Mar 31 07:19:49 2013 +0200
@@ -0,0 +1,2 @@
+ BAZ
+ BAZ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/t17.c	Sun Mar 31 07:19:49 2013 +0200
@@ -0,0 +1,11 @@
+#define a() x
+a()
+a ()
+#define b(p) p
+x/**/b(1)/**/x
+x/**/b (1)/**/x
+x/**/b()/**/x
+#define c(p,q) p/**/q
+x/**/c(1,2)/**/x
+x/**/c(1)/**/x
+x/**/c()/**/x
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/t17.good	Sun Mar 31 07:19:49 2013 +0200
@@ -0,0 +1,11 @@
+x
+x
+x1x
+x1x
+xx
+x12x
+t17.c:10:1: Wrong number of arguments for macro c; found 1, expected 2
+x1x
+t17.c:11:1: Wrong number of arguments for macro c; found 0, expected 2
+xx
+FAILED
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/t18.c	Sun Mar 31 07:19:49 2013 +0200
@@ -0,0 +1,2 @@
+#define file "subdir/test.h"
+#include file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/t18.good	Sun Mar 31 07:19:49 2013 +0200
@@ -0,0 +1,1 @@
+hello
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/t19.c	Sun Mar 31 07:19:49 2013 +0200
@@ -0,0 +1,2 @@
+#if FOO /* ignore me */
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/t19.good	Sun Mar 31 07:19:49 2013 +0200
@@ -0,0 +1,2 @@
+
+