glsl: Preserve newline inside comment blocks.
authorMichal Krol <michal@vmware.com>
Fri, 4 Sep 2009 13:11:58 +0000 (15:11 +0200)
committerMichal Krol <michal@vmware.com>
Mon, 7 Sep 2009 08:12:06 +0000 (10:12 +0200)
src/glsl/pp/sl_pp_purify.c

index ded4dc8963b0bf4d4f3d6c51e46d9b4ec773a198..3fb91430f3714cdab303b86f2622bc016608392c 100644 (file)
@@ -106,9 +106,44 @@ _purify_backslash(const char *input,
 }
 
 
+struct out_buf {
+   char *out;
+   unsigned int len;
+   unsigned int capacity;
+};
+
+
+static int
+_out_buf_putc(struct out_buf *obuf,
+              char c)
+{
+   if (obuf->len >= obuf->capacity) {
+      unsigned int new_max = obuf->capacity;
+
+      if (new_max < 0x100) {
+         new_max = 0x100;
+      } else if (new_max < 0x10000) {
+         new_max *= 2;
+      } else {
+         new_max += 0x10000;
+      }
+
+      obuf->out = realloc(obuf->out, new_max);
+      if (!obuf->out) {
+         return -1;
+      }
+      obuf->capacity = new_max;
+   }
+
+   obuf->out[obuf->len++] = c;
+
+   return 0;
+}
+
+
 static unsigned int
 _purify_comment(const char *input,
-                char *out)
+                struct out_buf *obuf)
 {
    unsigned int eaten;
    char curr;
@@ -130,7 +165,9 @@ _purify_comment(const char *input,
             eaten += next_eaten;
             input += next_eaten;
             if (next == '\n' || next == '\0') {
-               *out = next;
+               if (_out_buf_putc(obuf, next)) {
+                  return 0;
+               }
                return eaten;
             }
          }
@@ -148,17 +185,26 @@ _purify_comment(const char *input,
                eaten += next_eaten;
                input += next_eaten;
                if (next == '/') {
-                  *out = ' ';
+                  if (_out_buf_putc(obuf, ' ')) {
+                     return 0;
+                  }
                   return eaten;
                }
             }
+            if (next == '\n') {
+               if (_out_buf_putc(obuf, '\n')) {
+                  return 0;
+               }
+            }
             if (next == '\0') {
                return 0;
             }
          }
       }
    }
-   *out = curr;
+   if (_out_buf_putc(obuf, curr)) {
+      return 0;
+   }
    return eaten;
 }
 
@@ -168,45 +214,26 @@ sl_pp_purify(const char *input,
              const struct sl_pp_purify_options *options,
              char **output)
 {
-   char *out = NULL;
-   unsigned int out_len = 0;
-   unsigned int out_max = 0;
+   struct out_buf obuf;
+
+   obuf.out = NULL;
+   obuf.len = 0;
+   obuf.capacity = 0;
 
    for (;;) {
-      char c;
       unsigned int eaten;
 
-      eaten = _purify_comment(input, &c);
+      eaten = _purify_comment(input, &obuf);
       if (!eaten) {
          return -1;
       }
       input += eaten;
 
-      if (out_len >= out_max) {
-         unsigned int new_max = out_max;
-
-         if (new_max < 0x100) {
-            new_max = 0x100;
-         } else if (new_max < 0x10000) {
-            new_max *= 2;
-         } else {
-            new_max += 0x10000;
-         }
-
-         out = realloc(out, new_max);
-         if (!out) {
-            return -1;
-         }
-         out_max = new_max;
-      }
-
-      out[out_len++] = c;
-
-      if (c == '\0') {
+      if (obuf.out[obuf.len - 1] == '\0') {
          break;
       }
    }
 
-   *output = out;
+   *output = obuf.out;
    return 0;
 }