Mesa (master): Revert "glcpp: Rewrite line-continuation support to act globally."

Carl Worth cworth at kemper.freedesktop.org
Sat Dec 1 01:17:17 UTC 2012


Module: Mesa
Branch: master
Commit: a47a0200a78ed8bddcf0c79b4b630e475e7357ca
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a47a0200a78ed8bddcf0c79b4b630e475e7357ca

Author: Carl Worth <cworth at cworth.org>
Date:   Fri Nov 30 17:17:56 2012 -0800

Revert "glcpp: Rewrite line-continuation support to act globally."

This reverts commit 962a1c07b44fe500b79b3ca6806d72a432c1f055.

Further testing revealed that this commit can cause the pre-processor to enter
infinite loops. For now, simply revert this code until a cleaner,
better-tested version is available.

---

 src/glsl/glcpp/pp.c |  109 +++++++++++++++++++++++++++++++--------------------
 1 files changed, 66 insertions(+), 43 deletions(-)

diff --git a/src/glsl/glcpp/pp.c b/src/glsl/glcpp/pp.c
index 427f09a..11b2941 100644
--- a/src/glsl/glcpp/pp.c
+++ b/src/glsl/glcpp/pp.c
@@ -70,59 +70,82 @@ glcpp_warning (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...)
 				     &parser->info_log_length, "\n");
 }
 
-/* Remove any line continuation characters in the shader, (whether in
- * preprocessing directives or in GLSL code).
+/* Searches backwards for '^ *#' from a given starting point. */
+static int
+in_directive(const char *shader, const char *ptr)
+{
+	assert(ptr >= shader);
+
+	/* Search backwards for '#'. If we find a \n first, it doesn't count */
+	for (; ptr >= shader && *ptr != '#'; ptr--) {
+		if (*ptr == '\n')
+			return 0;
+	}
+	if (ptr >= shader) {
+		/* Found '#'...look for spaces preceded by a newline */
+		for (ptr--; ptr >= shader && isblank(*ptr); ptr--);
+		// FIXME: I don't think the '\n' case can happen
+		if (ptr < shader || *ptr == '\n')
+			return 1;
+	}
+	return 0;
+}
+
+/* Remove any line continuation characters in preprocessing directives.
+ * However, ignore any in GLSL code, as "There is no line continuation
+ * character" (1.30 page 9) in GLSL.
  */
 static char *
 remove_line_continuations(glcpp_parser_t *ctx, const char *shader)
 {
+	int in_continued_line = 0;
+	int extra_newlines = 0;
 	char *clean = ralloc_strdup(ctx, "");
-	const char *backslash, *newline;
-	int collapsed_newlines = 0;
-
-	while (true) {
-		backslash = strchr(shader, '\\');
-
-		/* If we have previously collapsed any line-continuations,
-		 * then we want to insert additional newlines at the next
-		 * occurrence of a newline character to avoid changing any
-		 * line numbers.
-		 */
-		if (collapsed_newlines) {
-			newline = strchr(shader, '\n');
-			if (newline &&
-			    (backslash == NULL || newline < backslash))
-			{
-				ralloc_strncat(&clean, shader,
-					       newline - shader + 1);
-				while (collapsed_newlines--)
-					ralloc_strcat(&clean, "\n");
-				shader = newline + 1;
-			}
+	const char *search_start = shader;
+	const char *newline;
+	while ((newline = strchr(search_start, '\n')) != NULL) {
+		const char *backslash = NULL;
+
+		/* # of characters preceding the newline. */
+		int n = newline - shader;
+
+		/* Find the preceding '\', if it exists */
+		if (n >= 1 && newline[-1] == '\\')
+			backslash = newline - 1;
+		else if (n >= 2 && newline[-1] == '\r' && newline[-2] == '\\')
+			backslash = newline - 2;
+
+		/* Double backslashes don't count (the backslash is escaped) */
+		if (backslash != NULL && backslash[-1] == '\\') {
+			backslash = NULL;
 		}
 
-		if (backslash == NULL)
-			break;
-
-		/* At each line continuation, (backslash followed by a
-		 * newline), copy all preceding text to the output, then
-		 * advance the shader pointer to the character after the
-		 * newline.
-		 */
-		if (backslash[1] == '\n' ||
-		    (backslash[1] == '\r' && backslash[2] == '\n'))
-		{
-			collapsed_newlines++;
-			ralloc_strncat(&clean, shader, backslash - shader);
-			if (backslash[1] == '\n')
-				shader = backslash + 2;
-			else
-				shader = backslash + 3;
+		if (backslash != NULL) {
+			/* We found a line continuation, but do we care? */
+			if (!in_continued_line) {
+				if (in_directive(shader, backslash)) {
+					in_continued_line = 1;
+					extra_newlines = 0;
+				}
+			}
+			if (in_continued_line) {
+				/* Copy everything before the \ */
+				ralloc_strncat(&clean, shader, backslash - shader);
+				shader = newline + 1;
+				extra_newlines++;
+			}
+		} else if (in_continued_line) {
+			/* Copy everything up to and including the \n */
+			ralloc_strncat(&clean, shader, newline - shader + 1);
+			shader = newline + 1;
+			/* Output extra newlines to make line numbers match */
+			for (; extra_newlines > 0; extra_newlines--)
+				ralloc_strcat(&clean, "\n");
+			in_continued_line = 0;
 		}
+		search_start = newline + 1;
 	}
-
 	ralloc_strcat(&clean, shader);
-
 	return clean;
 }
 




More information about the mesa-commit mailing list