revision 1235:8da2f3dad9c0
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 1235:8da2f3dad9c0 |
parent | 1234:1b836bf92653 |
child | 1236:d93175c36387 |
author | nkeynes |
date | Fri Feb 24 21:11:58 2012 +1000 (12 years ago) |
Add preprocessing support to genglsl
config.h.in | view | annotate | diff | log | ||
configure | view | annotate | diff | log | ||
configure.in | view | annotate | diff | log | ||
src/tools/genglsl.c | view | annotate | diff | log |
1.1 --- a/config.h.in Fri Feb 24 17:31:18 2012 +10001.2 +++ b/config.h.in Fri Feb 24 21:11:58 2012 +10001.3 @@ -10,9 +10,15 @@1.4 /* Building on an apple platform. Things are different... */1.5 #undef APPLE_BUILD1.7 +/* CPP to use for build tools */1.8 +#undef BUILD_CPP_PROG1.9 +1.10 /* Enable dynamic plugin support */1.11 #undef BUILD_PLUGINS1.13 +/* Sed to use for build tools */1.14 +#undef BUILD_SED_PROG1.15 +1.16 /* always defined to indicate that i18n is enabled */1.17 #undef ENABLE_NLS
2.1 --- a/configure Fri Feb 24 17:31:18 2012 +10002.2 +++ b/configure Fri Feb 24 21:11:58 2012 +10002.3 @@ -8611,6 +8611,17 @@2.7 +cat >>confdefs.h <<_ACEOF2.8 +#define BUILD_SED_PROG "${SED}"2.9 +_ACEOF2.10 +2.11 +2.12 +cat >>confdefs.h <<_ACEOF2.13 +#define BUILD_CPP_PROG "${CPP}"2.14 +_ACEOF2.15 +2.16 +2.17 +2.18 # Check whether --enable-strict-warn was given.2.19 if test "${enable_strict_warn+set}" = set; then2.20 enableval=$enable_strict_warn; if test "$enableval" == "yes"; then
3.1 --- a/configure.in Fri Feb 24 17:31:18 2012 +10003.2 +++ b/configure.in Fri Feb 24 21:11:58 2012 +10003.3 @@ -26,6 +26,9 @@3.4 AC_PATH_PROG(POD2MAN, [pod2man])3.5 AC_PATH_PROG(POD2HTML, [pod2html])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.12 AC_ARG_ENABLE( strict-warn,
4.1 --- a/src/tools/genglsl.c Fri Feb 24 17:31:18 2012 +10004.2 +++ b/src/tools/genglsl.c Fri Feb 24 21:11:58 2012 +10004.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.11 #define MAX_LINE 40964.12 #define DEF_ALLOC_SIZE 40964.13 @@ -144,14 +146,65 @@4.15 }4.17 +static GList *temp_filenames = NULL;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 result4.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.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.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.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.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.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.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);
.