diff options
Diffstat (limited to 'src/glsl/pp/sl_pp_process.c')
-rw-r--r-- | src/glsl/pp/sl_pp_process.c | 245 |
1 files changed, 143 insertions, 102 deletions
diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index e2adc2a021..f89986dd8e 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -27,19 +27,11 @@ #include <stdlib.h> #include <string.h> +#include "sl_pp_context.h" #include "sl_pp_process.h" #include "sl_pp_public.h" -static void -skip_whitespace(const struct sl_pp_token_info *input, - unsigned int *pi) -{ - while (input[*pi].token == SL_PP_WHITESPACE) { - (*pi)++; - } -} - int sl_pp_process_out(struct sl_pp_process_state *state, const struct sl_pp_token_info *token) @@ -67,133 +59,157 @@ sl_pp_process_out(struct sl_pp_process_state *state, } int -sl_pp_process(struct sl_pp_context *context, - const struct sl_pp_token_info *input, - struct sl_pp_token_info **output) +sl_pp_process_get(struct sl_pp_context *context, + struct sl_pp_token_info *output) { - unsigned int i = 0; - int found_eof = 0; - struct sl_pp_process_state state; + if (!context->process_state.out) { + if (context->line > 1) { + struct sl_pp_token_info ti; - memset(&state, 0, sizeof(state)); + ti.token = SL_PP_LINE; + ti.data.line.lineno = context->line - 1; + ti.data.line.fileno = context->file; + if (sl_pp_process_out(&context->process_state, &ti)) { + strcpy(context->error_msg, "out of memory"); + return -1; + } - if (context->line > 1) { - struct sl_pp_token_info ti; + ti.token = SL_PP_NEWLINE; + if (sl_pp_process_out(&context->process_state, &ti)) { + strcpy(context->error_msg, "out of memory"); + return -1; + } + } + } - ti.token = SL_PP_LINE; - ti.data.line.lineno = context->line - 1; - ti.data.line.fileno = context->file; - if (sl_pp_process_out(&state, &ti)) { - strcpy(context->error_msg, "out of memory"); - return -1; + for (;;) { + struct sl_pp_token_info input; + int found_eof = 0; + + if (context->process_state.out_len) { + *output = context->process_state.out[0]; + + if (context->process_state.out_len > 1) { + unsigned int i; + + for (i = 1; i < context->process_state.out_len; i++) { + context->process_state.out[i - 1] = context->process_state.out[i]; + } + } + context->process_state.out_len--; + + return 0; } - ti.token = SL_PP_NEWLINE; - if (sl_pp_process_out(&state, &ti)) { - strcpy(context->error_msg, "out of memory"); + if (sl_pp_token_buffer_skip_white(&context->tokens, &input)) { return -1; } - } - - while (!found_eof) { - skip_whitespace(input, &i); - if (input[i].token == SL_PP_HASH) { - i++; - skip_whitespace(input, &i); - switch (input[i].token) { + if (input.token == SL_PP_HASH) { + if (sl_pp_token_buffer_skip_white(&context->tokens, &input)) { + return -1; + } + switch (input.token) { case SL_PP_IDENTIFIER: { int name; int found_eol = 0; - unsigned int first; - unsigned int last; struct sl_pp_token_info endof; + struct sl_pp_token_peek peek; + int result = 0; /* Directive name. */ - name = input[i].data.identifier; - i++; - skip_whitespace(input, &i); + name = input.data.identifier; - first = i; + if (sl_pp_token_buffer_skip_white(&context->tokens, &input)) { + return -1; + } + sl_pp_token_buffer_unget(&context->tokens, &input); + + if (sl_pp_token_peek_init(&peek, &context->tokens)) { + return -1; + } while (!found_eol) { - switch (input[i].token) { + if (sl_pp_token_peek_get(&peek, &input)) { + sl_pp_token_peek_destroy(&peek); + return -1; + } + switch (input.token) { case SL_PP_NEWLINE: /* Preserve newline just for the sake of line numbering. */ - endof = input[i]; - i++; + endof = input; found_eol = 1; break; case SL_PP_EOF: - endof = input[i]; - i++; + endof = input; found_eof = 1; found_eol = 1; break; default: - i++; + break; } } - last = i - 1; - if (name == context->dict._if) { - if (sl_pp_process_if(context, input, first, last)) { - return -1; + struct sl_pp_token_buffer buffer; + + result = sl_pp_token_peek_to_buffer(&peek, &buffer); + if (result == 0) { + result = sl_pp_process_if(context, &buffer); + sl_pp_token_buffer_destroy(&buffer); } } else if (name == context->dict.ifdef) { - if (sl_pp_process_ifdef(context, input, first, last)) { - return -1; - } + result = sl_pp_process_ifdef(context, peek.tokens, 0, peek.size - 1); } else if (name == context->dict.ifndef) { - if (sl_pp_process_ifndef(context, input, first, last)) { - return -1; - } + result = sl_pp_process_ifndef(context, peek.tokens, 0, peek.size - 1); } else if (name == context->dict.elif) { - if (sl_pp_process_elif(context, input, first, last)) { - return -1; + struct sl_pp_token_buffer buffer; + + result = sl_pp_token_peek_to_buffer(&peek, &buffer); + if (result == 0) { + result = sl_pp_process_elif(context, &buffer); + sl_pp_token_buffer_destroy(&buffer); } } else if (name == context->dict._else) { - if (sl_pp_process_else(context, input, first, last)) { - return -1; - } + result = sl_pp_process_else(context, peek.tokens, 0, peek.size - 1); } else if (name == context->dict.endif) { - if (sl_pp_process_endif(context, input, first, last)) { - return -1; - } + result = sl_pp_process_endif(context, peek.tokens, 0, peek.size - 1); } else if (context->if_value) { if (name == context->dict.define) { - if (sl_pp_process_define(context, input, first, last)) { - return -1; - } + result = sl_pp_process_define(context, peek.tokens, 0, peek.size - 1); } else if (name == context->dict.error) { - sl_pp_process_error(context, input, first, last); - return -1; + sl_pp_process_error(context, peek.tokens, 0, peek.size - 1); + result = -1; } else if (name == context->dict.extension) { - if (sl_pp_process_extension(context, input, first, last, &state)) { - return -1; - } + result = sl_pp_process_extension(context, peek.tokens, 0, peek.size - 1, &context->process_state); } else if (name == context->dict.line) { - if (sl_pp_process_line(context, input, first, last, &state)) { - return -1; + struct sl_pp_token_buffer buffer; + + result = sl_pp_token_peek_to_buffer(&peek, &buffer); + if (result == 0) { + result = sl_pp_process_line(context, &buffer, &context->process_state); + sl_pp_token_buffer_destroy(&buffer); } } else if (name == context->dict.pragma) { - if (sl_pp_process_pragma(context, input, first, last, &state)) { - return -1; - } + result = sl_pp_process_pragma(context, peek.tokens, 0, peek.size - 1, &context->process_state); } else if (name == context->dict.undef) { - if (sl_pp_process_undef(context, input, first, last)) { - return -1; - } + result = sl_pp_process_undef(context, peek.tokens, 0, peek.size - 1); } else { strcpy(context->error_msg, "unrecognised directive name"); - return -1; + result = -1; } } - if (sl_pp_process_out(&state, &endof)) { + sl_pp_token_peek_commit(&peek); + sl_pp_token_peek_destroy(&peek); + + if (result) { + return result; + } + + if (sl_pp_process_out(&context->process_state, &endof)) { strcpy(context->error_msg, "out of memory"); return -1; } @@ -203,21 +219,19 @@ sl_pp_process(struct sl_pp_context *context, case SL_PP_NEWLINE: /* Empty directive. */ - if (sl_pp_process_out(&state, &input[i])) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } context->line++; - i++; break; case SL_PP_EOF: /* Empty directive. */ - if (sl_pp_process_out(&state, &input[i])) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } - i++; found_eof = 1; break; @@ -228,36 +242,40 @@ sl_pp_process(struct sl_pp_context *context, } else { int found_eol = 0; + sl_pp_token_buffer_unget(&context->tokens, &input); + while (!found_eol) { - switch (input[i].token) { + if (sl_pp_token_buffer_get(&context->tokens, &input)) { + return -1; + } + + switch (input.token) { case SL_PP_WHITESPACE: /* Drop whitespace all together at this point. */ - i++; break; case SL_PP_NEWLINE: /* Preserve newline just for the sake of line numbering. */ - if (sl_pp_process_out(&state, &input[i])) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } context->line++; - i++; found_eol = 1; break; case SL_PP_EOF: - if (sl_pp_process_out(&state, &input[i])) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } - i++; found_eof = 1; found_eol = 1; break; case SL_PP_IDENTIFIER: - if (sl_pp_macro_expand(context, input, &i, NULL, &state, + sl_pp_token_buffer_unget(&context->tokens, &input); + if (sl_pp_macro_expand(context, &context->tokens, NULL, &context->process_state, context->if_value ? sl_pp_macro_expand_normal : sl_pp_macro_expand_mute)) { return -1; } @@ -265,22 +283,45 @@ sl_pp_process(struct sl_pp_context *context, default: if (context->if_value) { - if (sl_pp_process_out(&state, &input[i])) { + if (sl_pp_process_out(&context->process_state, &input)) { strcpy(context->error_msg, "out of memory"); return -1; } } - i++; } } } - } - if (context->if_ptr != SL_PP_MAX_IF_NESTING) { - strcpy(context->error_msg, "expected `#endif' directive"); - return -1; + if (found_eof) { + if (context->if_ptr != SL_PP_MAX_IF_NESTING) { + strcpy(context->error_msg, "expected `#endif' directive"); + return -1; + } + } } +} - *output = state.out; - return 0; +int +sl_pp_process(struct sl_pp_context *context, + struct sl_pp_token_info **output) +{ + struct sl_pp_process_state state; + + memset(&state, 0, sizeof(state)); + for (;;) { + struct sl_pp_token_info input; + + if (sl_pp_process_get(context, &input)) { + free(state.out); + return -1; + } + if (sl_pp_process_out(&state, &input)) { + free(state.out); + return -1; + } + if (input.token == SL_PP_EOF) { + *output = state.out; + return 0; + } + } } |