diff files.c @ 75:980ed7cb620a

More multiline comment fixes. It looks like the only rational way to handle multiline comments is to treat the newlines as fully part of the comment text.
author David A. Holland
date Mon, 10 Jun 2013 19:56:55 -0400
parents 2e25e55dba6b
children 27c9aafcaca1
line wrap: on
line diff
--- a/files.c	Mon Jun 10 18:49:36 2013 -0400
+++ b/files.c	Mon Jun 10 19:56:55 2013 -0400
@@ -115,18 +115,52 @@
 ////////////////////////////////////////////////////////////
 // parsing
 
+/*
+ * Find the end of the logical line. End of line characters that are
+ * commented out do not count.
+ */
 static
 size_t
-findnl(const char *buf, size_t start, size_t limit)
+findeol(const char *buf, size_t start, size_t limit)
 {
 	size_t i;
+	int incomment = 0;
+
+	for (i=start; i<limit; i++) {
+		if (incomment) {
+			if (i+1 < limit && buf[i] == '*' && buf[i+1] == '/') {
+				i++;
+				incomment = 0;
+			}
+		}
+		else {
+			if (i+1 < limit && buf[i] == '/' && buf[i+1] == '*') {
+				i++;
+				incomment = 1;
+			}
+			else {
+				if (buf[i] == '\n') {
+					return i;
+				}
+			}
+		}
+	}
+	return limit;
+}
+
+static
+unsigned
+countnls(const char *buf, size_t start, size_t limit)
+{
+	size_t i;
+	unsigned count = 0;
 
 	for (i=start; i<limit; i++) {
 		if (buf[i] == '\n') {
-			return i;
+			count++;
 		}
 	}
-	return limit;
+	return count;
 }
 
 static
@@ -151,6 +185,7 @@
 	while (1) {
 		if (lineend >= bufend) {
 			/* do not have a whole line in the buffer; read more */
+			assert(bufend >= linestart);
 			if (linestart > 0 && bufend > linestart) {
 				/* slide to beginning of buffer */
 				memmove(buf, buf+linestart, bufend-linestart);
@@ -194,7 +229,7 @@
 			} else {
 				tmp = bufend;
 				bufend += (size_t)result;
-				lineend = findnl(buf, tmp, bufend);
+				lineend = findeol(buf, tmp, bufend);
 			}
 			/* loop in case we still don't have a whole line */
 			continue;
@@ -222,20 +257,25 @@
 			}
 			bufend -= tmp;
 			nextlinestart -= tmp;
-			lineend = findnl(buf, lineend, bufend);
+			lineend = findeol(buf, lineend, bufend);
 			/* might not have a whole line, so loop */
 			continue;
 		}
 
 		/* line now goes from linestart to lineend */
 		assert(buf[lineend] == '\0');
+
+		/* count how many commented-out newlines we swallowed */
+		nextlinestartplace.line += countnls(buf, linestart, lineend);
+
+		/* if the line isn't empty, process it */
 		if (lineend > linestart) {
 			directive_gotline(&linestartplace,
 					  buf+linestart, lineend-linestart);
 		}
 
 		linestart = nextlinestart;
-		lineend = findnl(buf, linestart, bufend);
+		lineend = findeol(buf, linestart, bufend);
 		linestartplace = nextlinestartplace;
 	}