Search
lxdream.org :: lxdream :: r1235:8da2f3dad9c0
lxdream 0.9.1
released Jun 29
Download Now
changeset1235:8da2f3dad9c0
parent1234:1b836bf92653
child1236:d93175c36387
authornkeynes
dateFri Feb 24 21:11:58 2012 +1000 (7 years ago)
Add preprocessing support to genglsl
config.h.in
configure
configure.in
src/tools/genglsl.c
1.1 --- a/config.h.in Fri Feb 24 17:31:18 2012 +1000
1.2 +++ b/config.h.in Fri Feb 24 21:11:58 2012 +1000
1.3 @@ -10,9 +10,15 @@
1.4 /* Building on an apple platform. Things are different... */
1.5 #undef APPLE_BUILD
1.6
1.7 +/* CPP to use for build tools */
1.8 +#undef BUILD_CPP_PROG
1.9 +
1.10 /* Enable dynamic plugin support */
1.11 #undef BUILD_PLUGINS
1.12
1.13 +/* Sed to use for build tools */
1.14 +#undef BUILD_SED_PROG
1.15 +
1.16 /* always defined to indicate that i18n is enabled */
1.17 #undef ENABLE_NLS
1.18
2.1 --- a/configure Fri Feb 24 17:31:18 2012 +1000
2.2 +++ b/configure Fri Feb 24 21:11:58 2012 +1000
2.3 @@ -8611,6 +8611,17 @@
2.4
2.5
2.6
2.7 +cat >>confdefs.h <<_ACEOF
2.8 +#define BUILD_SED_PROG "${SED}"
2.9 +_ACEOF
2.10 +
2.11 +
2.12 +cat >>confdefs.h <<_ACEOF
2.13 +#define BUILD_CPP_PROG "${CPP}"
2.14 +_ACEOF
2.15 +
2.16 +
2.17 +
2.18 # Check whether --enable-strict-warn was given.
2.19 if test "${enable_strict_warn+set}" = set; then
2.20 enableval=$enable_strict_warn; if test "$enableval" == "yes"; then
3.1 --- a/configure.in Fri Feb 24 17:31:18 2012 +1000
3.2 +++ b/configure.in Fri Feb 24 21:11:58 2012 +1000
3.3 @@ -26,6 +26,9 @@
3.4 AC_PATH_PROG(POD2MAN, [pod2man])
3.5 AC_PATH_PROG(POD2HTML, [pod2html])
3.6
3.7 +AC_DEFINE_UNQUOTED(BUILD_SED_PROG, ["${SED}"], [Sed to use for build tools])
3.8 +AC_DEFINE_UNQUOTED(BUILD_CPP_PROG, ["${CPP}"], [CPP to use for build tools])
3.9 +
3.10 dnl ---------------- enable/with flags ------------------
3.11
3.12 AC_ARG_ENABLE( strict-warn,
4.1 --- a/src/tools/genglsl.c Fri Feb 24 17:31:18 2012 +1000
4.2 +++ b/src/tools/genglsl.c Fri Feb 24 21:11:58 2012 +1000
4.3 @@ -28,7 +28,9 @@
4.4 #include <string.h>
4.5 #include <getopt.h>
4.6 #include <glib/gstrfuncs.h>
4.7 +#include <glib/gshell.h>
4.8 #include <glib/glist.h>
4.9 +#include "../../config.h"
4.10
4.11 #define MAX_LINE 4096
4.12 #define DEF_ALLOC_SIZE 4096
4.13 @@ -144,14 +146,65 @@
4.14
4.15 }
4.16
4.17 +static GList *temp_filenames = NULL;
4.18
4.19 -static void readInput( const char *filename, glsldata_t result )
4.20 +static void cleanup_tempfiles(void)
4.21 +{
4.22 + while( temp_filenames != NULL ) {
4.23 + unlink( (char *)temp_filenames->data );
4.24 + g_free(temp_filenames->data);
4.25 + temp_filenames = temp_filenames->next;
4.26 + }
4.27 +}
4.28 +
4.29 +/**
4.30 + * Preprocess the input file and return a temporary filename containing the result
4.31 + */
4.32 +static FILE *preprocessInput( const char *filename, GList *cpp_opts )
4.33 +{
4.34 + char tmpname[] = "/tmp/genglsl.XXXXXXXX";
4.35 + int fd = mkstemp(tmpname);
4.36 + if( fd == -1 ) {
4.37 + fprintf( stderr, "Error: unable to get a temporary filename (%s)\n", strerror(errno) );
4.38 + exit(2);
4.39 + }
4.40 + char *quoted_filename = g_shell_quote(filename);
4.41 +
4.42 + int nOpts = g_list_length(cpp_opts);
4.43 + gchar *quoted_opts_arr[nOpts];
4.44 + int length = 0, count=0;
4.45 + for( GList *ptr = cpp_opts; ptr != NULL; ptr = ptr->next ) {
4.46 + quoted_opts_arr[count] = g_shell_quote((gchar *)ptr->data);
4.47 + length += strlen(quoted_opts_arr[count++]) + 1;
4.48 + }
4.49 + gchar quoted_cpp_opts[length];
4.50 + quoted_cpp_opts[0] = '\0';
4.51 + for( count=0; count<nOpts; count++ ) {
4.52 + if( count != 0 )
4.53 + strcat(quoted_cpp_opts, " ");
4.54 + strcat(quoted_cpp_opts, quoted_opts_arr[count]);
4.55 + g_free(quoted_opts_arr[count++]);
4.56 + }
4.57 +
4.58 + const char *command = g_strdup_printf("%s -E 's/^#(program|vertex|fragment)/#pragma \\1/' %s | %s %s - > %s",
4.59 + BUILD_SED_PROG, quoted_filename, BUILD_CPP_PROG, quoted_cpp_opts, tmpname );
4.60 + if( system(command) != 0 ) {
4.61 + fprintf( stderr, "Error: unable to run preprocessor command '%s' (%s)\n", command, strerror(errno) );
4.62 + exit(2);
4.63 + }
4.64 +
4.65 + temp_filenames = g_list_append(temp_filenames, g_strdup(tmpname));
4.66 + return fdopen(fd, "r");
4.67 +}
4.68 +
4.69 +static void readInput( const char *filename, GList *cpp_opts, glsldata_t result )
4.70 {
4.71 char buf[MAX_LINE];
4.72 size_t current_size = 0, current_posn = 0;
4.73 unsigned i;
4.74
4.75 - FILE *f = fopen( filename, "ro" );
4.76 +
4.77 + FILE *f = preprocessInput(filename, cpp_opts );
4.78 if( f == NULL ) {
4.79 fprintf( stderr, "Error: unable to open input file '%s': %s\n", filename, strerror(errno) );
4.80 exit(2);
4.81 @@ -170,42 +223,49 @@
4.82 if( strlen(buf) == 0 )
4.83 continue;
4.84
4.85 - if( strncmp(buf, "#vertex ", 8) == 0 ) {
4.86 - shader = g_malloc0(sizeof(struct shader));
4.87 - assert( shader != NULL );
4.88 - shader->type = VERTEX_SHADER;
4.89 - shader->name = strdup(g_strstrip(buf+8));
4.90 - shader->body = malloc(DEF_ALLOC_SIZE);
4.91 - shader->body[0] = '\0';
4.92 - current_size = DEF_ALLOC_SIZE;
4.93 - current_posn = 0;
4.94 - result->shaders = g_list_append(result->shaders, shader);
4.95 - } else if( strncmp( buf, "#fragment ", 10 ) == 0 ) {
4.96 - shader = g_malloc0(sizeof(struct shader));
4.97 - assert( shader != NULL );
4.98 - shader->type = FRAGMENT_SHADER;
4.99 - shader->name = strdup(g_strstrip(buf+10));
4.100 - shader->body = malloc(DEF_ALLOC_SIZE);
4.101 - shader->body[0] = '\0';
4.102 - current_size = DEF_ALLOC_SIZE;
4.103 - current_posn = 0;
4.104 - result->shaders = g_list_append(result->shaders, shader);
4.105 - } else if( strncmp( buf, "#program ", 9 ) == 0 ) {
4.106 - shader = NULL;
4.107 - program_t program = g_malloc0(sizeof(struct program));
4.108 - char *rest = buf+9;
4.109 - char *equals = strchr(rest, '=');
4.110 - if( equals == NULL ) {
4.111 - fprintf( stderr, "Error: invalid program line %s\n", buf );
4.112 - exit(2);
4.113 + if( buf[0] == '#' ) {
4.114 + char *p = buf+1;
4.115 + if( strncmp(p, "pragma ", 7) == 0 ) {
4.116 + p += 7;
4.117 }
4.118 - *equals = '\0';
4.119 - program->name = g_strdup(g_strstrip(rest));
4.120 - program->shader_names = g_strsplit_set(g_strstrip(equals+1), " \t\r,", 0);
4.121 - result->programs = g_list_append(result->programs, program);
4.122 - for(i=0;program->shader_names[i] != NULL; i++ );
4.123 - if( i > result->max_shaders )
4.124 - result->max_shaders = i;
4.125 + if( strncmp(p, "vertex ", 7) == 0 ) {
4.126 + shader = g_malloc0(sizeof(struct shader));
4.127 + assert( shader != NULL );
4.128 + shader->type = VERTEX_SHADER;
4.129 + shader->name = strdup(g_strstrip(p+7));
4.130 + shader->body = malloc(DEF_ALLOC_SIZE);
4.131 + shader->body[0] = '\0';
4.132 + current_size = DEF_ALLOC_SIZE;
4.133 + current_posn = 0;
4.134 + result->shaders = g_list_append(result->shaders, shader);
4.135 + } else if( strncmp( p, "fragment ", 9 ) == 0 ) {
4.136 + shader = g_malloc0(sizeof(struct shader));
4.137 + assert( shader != NULL );
4.138 + shader->type = FRAGMENT_SHADER;
4.139 + shader->name = strdup(g_strstrip(p+9));
4.140 + shader->body = malloc(DEF_ALLOC_SIZE);
4.141 + shader->body[0] = '\0';
4.142 + current_size = DEF_ALLOC_SIZE;
4.143 + current_posn = 0;
4.144 + result->shaders = g_list_append(result->shaders, shader);
4.145 + } else if( strncmp( p, "program ", 8 ) == 0 ) {
4.146 + shader = NULL;
4.147 + program_t program = g_malloc0(sizeof(struct program));
4.148 + char *rest = p+8;
4.149 + char *equals = strchr(rest, '=');
4.150 + if( equals == NULL ) {
4.151 + fprintf( stderr, "Error: invalid program line %s\n", buf );
4.152 + exit(2);
4.153 + }
4.154 + *equals = '\0';
4.155 + program->name = g_strdup(g_strstrip(rest));
4.156 + program->shader_names = g_strsplit_set(g_strstrip(equals+1), " \t\r,", 0);
4.157 + result->programs = g_list_append(result->programs, program);
4.158 + for(i=0;program->shader_names[i] != NULL; i++ );
4.159 + if( i > result->max_shaders )
4.160 + result->max_shaders = i;
4.161 + }
4.162 + /* Else discard any other # lines */
4.163 } else if( shader != NULL ) {
4.164 size_t len = strlen(buf);
4.165 if( current_posn + len > current_size ) {
4.166 @@ -446,10 +506,10 @@
4.167 }
4.168 }
4.169
4.170 -static char *option_list = "hi:o:";
4.171 +static char *option_list = "hi:I:D:U:o:";
4.172 static struct option long_option_list[] = {
4.173 { "help", no_argument, NULL, 'h' },
4.174 - { "interface", required_argument, 'i' },
4.175 + { "interface", required_argument, NULL, 'i' },
4.176 { "output", required_argument, NULL, 'o' },
4.177 { NULL, 0, 0, 0 } };
4.178
4.179 @@ -460,6 +520,7 @@
4.180 {
4.181 const char *output_file = NULL;
4.182 const char *iface_file = NULL;
4.183 + GList *cpp_opts = NULL;
4.184 int opt;
4.185
4.186 while( (opt = getopt_long( argc, argv, option_list, long_option_list, NULL )) != -1 ) {
4.187 @@ -468,6 +529,9 @@
4.188 usage();
4.189 exit(0);
4.190 break;
4.191 + case 'D': case 'I': case 'U':
4.192 + cpp_opts = g_list_append(cpp_opts, g_strdup_printf( "-%c%s", opt, optarg ));
4.193 + break;
4.194 case 'i':
4.195 if( iface_file != NULL ) {
4.196 fprintf( stderr, "Error: at most one interface file can be supplied\n" );
4.197 @@ -498,9 +562,10 @@
4.198 iface_file = makeExtension(output_file, ".h");
4.199 }
4.200
4.201 + atexit(cleanup_tempfiles);
4.202 glsldata_t data = g_malloc0(sizeof(struct glsldata));
4.203 while( optind < argc ) {
4.204 - readInput(argv[optind++], data);
4.205 + readInput(argv[optind++], cpp_opts, data);
4.206 }
4.207 linkPrograms(data);
4.208
.