<html>
<body>
  <div id="body" style="background-color:#ffffff;" >
<table cellspacing="0" cellpadding="0" border="0" rules="cols">
<tr class="head" style="border-bottom-width:1px;border-bottom-style:solid;" ><td class="headtd" style="padding:0;padding-top:.2em;" colspan="4">Commit in <b><tt>lxdream</tt></b></td></tr>
<tr><td><tt><a href="#file1">config.h.in</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+6</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">1b836bf92653 -> 8da2f3dad9c0</td></tr>
<tr class="alt" style=";" ><td><tt><a href="#file2">configure</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+11</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">1b836bf92653 -> 8da2f3dad9c0</td></tr>
<tr><td><tt><a href="#file3">configure.in</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+3</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">1b836bf92653 -> 8da2f3dad9c0</td></tr>
<tr class="alt" style=";" ><td><tt>src/tools/<a href="#file4">genglsl.c</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+105</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-40</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">1b836bf92653 -> 8da2f3dad9c0</td></tr>
<tr><td></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+125</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-40</td><td></td></tr>
</table>
<small id="info" style="color: #888888;" >4 modified files</small><br />
<pre class="comment" style="white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;padding:4px;border:1px dashed #000000;background-color:#ffffdd;" >
Add preprocessing support to genglsl
</pre>
<hr /><a name="file1" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>config.h.in</b></big> <small id="info" style="color: #888888;" >1b836bf92653 -> 8da2f3dad9c0</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/config.h.in
+++ lxdream/config.h.in
@@ -10,9 +10,15 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > /* Building on an apple platform. Things are different... */
 #undef APPLE_BUILD
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+/* CPP to use for build tools */
+#undef BUILD_CPP_PROG
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > /* Enable dynamic plugin support */
 #undef BUILD_PLUGINS
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+/* Sed to use for build tools */
+#undef BUILD_SED_PROG
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > /* always defined to indicate that i18n is enabled */
 #undef ENABLE_NLS
 
</pre></div>
<hr /><a name="file2" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>configure</b></big> <small id="info" style="color: #888888;" >1b836bf92653 -> 8da2f3dad9c0</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/configure
+++ lxdream/configure
@@ -8611,6 +8611,17 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
 
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+cat >>confdefs.h <<_ACEOF
+#define BUILD_SED_PROG "${SED}"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define BUILD_CPP_PROG "${CPP}"
+_ACEOF
+
+
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > # Check whether --enable-strict-warn was given.
 if test "${enable_strict_warn+set}" = set; then
   enableval=$enable_strict_warn; if test "$enableval" == "yes"; then
</pre></div>
<hr /><a name="file3" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>configure.in</b></big> <small id="info" style="color: #888888;" >1b836bf92653 -> 8da2f3dad9c0</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/configure.in
+++ lxdream/configure.in
@@ -26,6 +26,9 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > AC_PATH_PROG(POD2MAN, [pod2man])
 AC_PATH_PROG(POD2HTML, [pod2html])
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+AC_DEFINE_UNQUOTED(BUILD_SED_PROG, ["${SED}"], [Sed to use for build tools])
+AC_DEFINE_UNQUOTED(BUILD_CPP_PROG, ["${CPP}"], [CPP to use for build tools])
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > dnl ---------------- enable/with flags ------------------
 
 AC_ARG_ENABLE( strict-warn,
</pre></div>
<hr /><a name="file4" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/tools</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>genglsl.c</b></big> <small id="info" style="color: #888888;" >1b836bf92653 -> 8da2f3dad9c0</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/tools/genglsl.c
+++ lxdream/src/tools/genglsl.c
@@ -28,7 +28,9 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #include <string.h>
 #include <getopt.h>
 #include <glib/gstrfuncs.h>
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#include <glib/gshell.h>
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #include <glib/glist.h>
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#include "../../config.h"
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
 #define MAX_LINE 4096
 #define DEF_ALLOC_SIZE 4096
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -144,14 +146,65 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
 }
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static GList *temp_filenames = NULL;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static void readInput( const char *filename, glsldata_t result )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static void cleanup_tempfiles(void)
+{
+   while( temp_filenames != NULL ) {
+       unlink( (char *)temp_filenames->data );
+       g_free(temp_filenames->data);
+       temp_filenames = temp_filenames->next;
+   }
+}
+
+/**
+ * Preprocess the input file and return a temporary filename containing the result
+ */
+static FILE *preprocessInput( const char *filename, GList *cpp_opts )
+{
+    char tmpname[] = "/tmp/genglsl.XXXXXXXX";
+    int fd = mkstemp(tmpname);
+    if( fd == -1 ) {
+        fprintf( stderr, "Error: unable to get a temporary filename (%s)\n", strerror(errno) );
+        exit(2);
+    }
+    char *quoted_filename = g_shell_quote(filename);
+
+    int nOpts = g_list_length(cpp_opts);
+    gchar *quoted_opts_arr[nOpts];
+    int length = 0, count=0;
+    for( GList *ptr = cpp_opts; ptr != NULL; ptr = ptr->next ) {
+        quoted_opts_arr[count] = g_shell_quote((gchar *)ptr->data);
+        length += strlen(quoted_opts_arr[count++]) + 1;
+    }
+    gchar quoted_cpp_opts[length];
+    quoted_cpp_opts[0] = '\0';
+    for( count=0; count<nOpts; count++ ) {
+        if( count != 0 )
+            strcat(quoted_cpp_opts, " ");
+        strcat(quoted_cpp_opts, quoted_opts_arr[count]);
+        g_free(quoted_opts_arr[count++]);
+    }
+
+    const char *command = g_strdup_printf("%s -E 's/^#(program|vertex|fragment)/#pragma \\1/' %s | %s %s - > %s",
+            BUILD_SED_PROG, quoted_filename, BUILD_CPP_PROG, quoted_cpp_opts, tmpname );
+    if( system(command) != 0 ) {
+        fprintf( stderr, "Error: unable to run preprocessor command '%s' (%s)\n",  command, strerror(errno) );
+        exit(2);
+    }
+
+    temp_filenames = g_list_append(temp_filenames, g_strdup(tmpname));
+    return fdopen(fd, "r");
+}
+
+static void readInput( const char *filename, GList *cpp_opts, glsldata_t result )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
     char buf[MAX_LINE];
     size_t current_size = 0, current_posn = 0;
     unsigned i;
 
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    FILE *f = fopen( filename, "ro" );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+
+    FILE *f = preprocessInput(filename, cpp_opts );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     if( f == NULL ) {
         fprintf( stderr, "Error: unable to open input file '%s': %s\n", filename, strerror(errno) );
         exit(2);
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -170,42 +223,49 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         if( strlen(buf) == 0 )
             continue;
 
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-        if( strncmp(buf, "#vertex ", 8) == 0 ) {
-            shader = g_malloc0(sizeof(struct shader));
-            assert( shader != NULL );
-            shader->type = VERTEX_SHADER;
-            shader->name = strdup(g_strstrip(buf+8));
-            shader->body = malloc(DEF_ALLOC_SIZE);
-            shader->body[0] = '\0';
-            current_size = DEF_ALLOC_SIZE;
-            current_posn = 0;
-            result->shaders = g_list_append(result->shaders, shader);
-        } else if( strncmp( buf, "#fragment ", 10 ) == 0 ) {
-            shader = g_malloc0(sizeof(struct shader));
-            assert( shader != NULL );
-            shader->type = FRAGMENT_SHADER;
-            shader->name = strdup(g_strstrip(buf+10));
-            shader->body = malloc(DEF_ALLOC_SIZE);
-            shader->body[0] = '\0';
-            current_size = DEF_ALLOC_SIZE;
-            current_posn = 0;
-            result->shaders = g_list_append(result->shaders, shader);
-        } else if( strncmp( buf, "#program ", 9 ) == 0 ) {
-            shader = NULL;
-            program_t program = g_malloc0(sizeof(struct program));
-            char *rest = buf+9;
-            char *equals = strchr(rest, '=');
-            if( equals == NULL ) {
-                fprintf( stderr, "Error: invalid program line %s\n", buf );
-                exit(2);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+        if( buf[0] == '#' ) {
+            char *p = buf+1;
+            if( strncmp(p, "pragma ", 7) == 0 ) {
+                p += 7;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >             }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-            *equals = '\0';
-            program->name = g_strdup(g_strstrip(rest));
-            program->shader_names = g_strsplit_set(g_strstrip(equals+1), " \t\r,", 0);
-            result->programs = g_list_append(result->programs, program);
-            for(i=0;program->shader_names[i] != NULL; i++ );
-            if( i > result->max_shaders )
-                result->max_shaders = i;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+            if( strncmp(p, "vertex ", 7) == 0 ) {
+                shader = g_malloc0(sizeof(struct shader));
+                assert( shader != NULL );
+                shader->type = VERTEX_SHADER;
+                shader->name = strdup(g_strstrip(p+7));
+                shader->body = malloc(DEF_ALLOC_SIZE);
+                shader->body[0] = '\0';
+                current_size = DEF_ALLOC_SIZE;
+                current_posn = 0;
+                result->shaders = g_list_append(result->shaders, shader);
+            } else if( strncmp( p, "fragment ", 9 ) == 0 ) {
+                shader = g_malloc0(sizeof(struct shader));
+                assert( shader != NULL );
+                shader->type = FRAGMENT_SHADER;
+                shader->name = strdup(g_strstrip(p+9));
+                shader->body = malloc(DEF_ALLOC_SIZE);
+                shader->body[0] = '\0';
+                current_size = DEF_ALLOC_SIZE;
+                current_posn = 0;
+                result->shaders = g_list_append(result->shaders, shader);
+            } else if( strncmp( p, "program ", 8 ) == 0 ) {
+                shader = NULL;
+                program_t program = g_malloc0(sizeof(struct program));
+                char *rest = p+8;
+                char *equals = strchr(rest, '=');
+                if( equals == NULL ) {
+                    fprintf( stderr, "Error: invalid program line %s\n", buf );
+                    exit(2);
+                }
+                *equals = '\0';
+                program->name = g_strdup(g_strstrip(rest));
+                program->shader_names = g_strsplit_set(g_strstrip(equals+1), " \t\r,", 0);
+                result->programs = g_list_append(result->programs, program);
+                for(i=0;program->shader_names[i] != NULL; i++ );
+                if( i > result->max_shaders )
+                    result->max_shaders = i;
+            }
+            /* Else discard any other # lines */
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         } else if( shader != NULL ) {
             size_t len = strlen(buf);
             if( current_posn + len > current_size ) {
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -446,10 +506,10 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     }
 }
 
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static char *option_list = "hi:o:";
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static char *option_list = "hi:<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >I:D:U:</span>o:";
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > static struct option long_option_list[] = {
         { "help", no_argument, NULL, 'h' },
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-        { "interface", required_argument, 'i' },
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+        { "interface", required_argument, <span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >NULL, </span>'i' },
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         { "output", required_argument, NULL, 'o' },
         { NULL, 0, 0, 0 } };
 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -460,6 +520,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
     const char *output_file = NULL;
     const char *iface_file = NULL;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    GList *cpp_opts = NULL;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     int opt;
 
     while( (opt = getopt_long( argc, argv, option_list, long_option_list, NULL )) != -1 ) {
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -468,6 +529,9 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >             usage();
             exit(0);
             break;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+        case 'D': case 'I': case 'U':
+            cpp_opts = g_list_append(cpp_opts, g_strdup_printf( "-%c%s", opt, optarg ));
+            break;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         case 'i':
             if( iface_file != NULL ) {
                 fprintf( stderr, "Error: at most one interface file can be supplied\n" );
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -498,9 +562,10 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         iface_file = makeExtension(output_file, ".h");
     }
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    atexit(cleanup_tempfiles);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     glsldata_t data = g_malloc0(sizeof(struct glsldata));
     while( optind < argc ) {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-        readInput(argv[optind++], data);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+        readInput(argv[optind++], <span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >cpp_opts, </span>data);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     }
     linkPrograms(data);
 
</pre></div>
<center><small>Chaos Theory</small></center>
</div></body></html>