From 4aa3222df315e3b36c73374e9000a6607c3b995c Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 4 Sep 2009 15:16:21 +0200 Subject: glsl: Correctly handle line numbering. --- src/glsl/pp/sl_pp_context.c | 1 + src/glsl/pp/sl_pp_context.h | 2 ++ src/glsl/pp/sl_pp_line.c | 47 +++++++++++++++++++++++++++++++++++++++++++-- src/glsl/pp/sl_pp_macro.c | 4 ++-- src/glsl/pp/sl_pp_process.c | 20 ++++++++++++++++++- src/glsl/pp/sl_pp_process.h | 3 ++- src/glsl/pp/sl_pp_token.h | 3 +++ src/glsl/pp/sl_pp_version.c | 8 +++++++- 8 files changed, 81 insertions(+), 7 deletions(-) diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 38d633baef..6aaf76828c 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -37,6 +37,7 @@ sl_pp_context_init(struct sl_pp_context *context) context->if_ptr = SL_PP_MAX_IF_NESTING; context->if_value = 1; memset(context->error_msg, 0, sizeof(context->error_msg)); + context->line = 1; } void diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 65ce3e37b7..d656648d0d 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -48,6 +48,8 @@ struct sl_pp_context { int if_value; char error_msg[SL_PP_MAX_ERROR_MSG]; + + unsigned int line; }; void diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index 3300a4785b..b62af185bf 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -29,16 +29,44 @@ #include "sl_pp_process.h" +static int +_parse_integer(const char *input, + unsigned int *number) +{ + unsigned int n = 0; + + while (*input >= '0' && *input <= '9') { + if (n * 10 < n) { + /* Overflow. */ + return -1; + } + + n = n * 10 + (*input++ - '0'); + } + + if (*input != '\0') { + /* Invalid decimal number. */ + return -1; + } + + *number = n; + return 0; +} + + int sl_pp_process_line(struct sl_pp_context *context, const struct sl_pp_token_info *input, unsigned int first, - unsigned int last) + unsigned int last, + struct sl_pp_process_state *pstate) { unsigned int i; struct sl_pp_process_state state; int line_number = -1; int file_number = -1; + const char *str; + unsigned int line; memset(&state, 0, sizeof(state)); for (i = first; i < last;) { @@ -89,7 +117,22 @@ sl_pp_process_line(struct sl_pp_context *context, free(state.out); - /* TODO: Do something with line and file numbers. */ + str = sl_pp_context_cstr(context, line_number); + if (_parse_integer(str, &line)) { + return -1; + } + + if (context->line != line) { + struct sl_pp_token_info ti; + + ti.token = SL_PP_LINE; + ti.data.line = line; + if (sl_pp_process_out(pstate, &ti)) { + return -1; + } + } + + /* TODO: Do something with the file number. */ return 0; } diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index bacd468964..b6214f66ed 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -131,14 +131,14 @@ sl_pp_macro_expand(struct sl_pp_context *context, macro_name = input[*pi].data.identifier; macro_str = sl_pp_context_cstr(context, macro_name); - /* TODO: Having the following built-ins hardcoded is a bit lame. */ if (!strcmp(macro_str, "__LINE__")) { - if (!mute && _out_number(context, state, 1)) { + if (!mute && _out_number(context, state, context->line)) { return -1; } (*pi)++; return 0; } + /* TODO: Having the following built-ins hardcoded is a bit lame. */ if (!strcmp(macro_str, "__FILE__")) { if (!mute && _out_number(context, state, 0)) { return -1; diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 5479e8a868..c4d6efaed3 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -75,6 +75,21 @@ sl_pp_process(struct sl_pp_context *context, memset(&state, 0, sizeof(state)); + if (context->line > 1) { + struct sl_pp_token_info ti; + + ti.token = SL_PP_LINE; + ti.data.line = context->line - 1; + if (sl_pp_process_out(&state, &ti)) { + return -1; + } + + ti.token = SL_PP_NEWLINE; + if (sl_pp_process_out(&state, &ti)) { + return -1; + } + } + while (!found_eof) { skip_whitespace(input, &i); if (input[i].token == SL_PP_HASH) { @@ -156,7 +171,7 @@ sl_pp_process(struct sl_pp_context *context, return -1; } } else if (!strcmp(name, "line")) { - if (sl_pp_process_line(context, input, first, last)) { + if (sl_pp_process_line(context, input, first, last, &state)) { return -1; } } else if (!strcmp(name, "pragma")) { @@ -176,6 +191,7 @@ sl_pp_process(struct sl_pp_context *context, if (sl_pp_process_out(&state, &endof)) { return -1; } + context->line++; } break; @@ -184,6 +200,7 @@ sl_pp_process(struct sl_pp_context *context, if (sl_pp_process_out(&state, &input[i])) { return -1; } + context->line++; i++; break; @@ -214,6 +231,7 @@ sl_pp_process(struct sl_pp_context *context, if (sl_pp_process_out(&state, &input[i])) { return -1; } + context->line++; i++; found_eol = 1; break; diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index 6f90fbd3e7..adc08c18ae 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -116,7 +116,8 @@ int sl_pp_process_line(struct sl_pp_context *context, const struct sl_pp_token_info *input, unsigned int first, - unsigned int last); + unsigned int last, + struct sl_pp_process_state *state); int sl_pp_process_out(struct sl_pp_process_state *state, diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h index 7b60183a04..b347e5cf7a 100644 --- a/src/glsl/pp/sl_pp_token.h +++ b/src/glsl/pp/sl_pp_token.h @@ -96,6 +96,8 @@ enum sl_pp_token { SL_PP_EXTENSION_WARN, SL_PP_EXTENSION_DISABLE, + SL_PP_LINE, + SL_PP_EOF }; @@ -105,6 +107,7 @@ union sl_pp_token_data { char other; int pragma; int extension; + unsigned int line; }; struct sl_pp_token_info { diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c index 89c3cfa1a5..80f7e97101 100644 --- a/src/glsl/pp/sl_pp_version.c +++ b/src/glsl/pp/sl_pp_version.c @@ -60,6 +60,7 @@ sl_pp_version(struct sl_pp_context *context, unsigned int *tokens_eaten) { unsigned int i = 0; + unsigned int line = context->line; /* Default values if `#version' is not present. */ *version = 110; @@ -77,8 +78,10 @@ sl_pp_version(struct sl_pp_context *context, /* Skip whitespace and newlines and seek for hash. */ while (!found_hash) { switch (input[i].token) { - case SL_PP_WHITESPACE: case SL_PP_NEWLINE: + line++; + /* pass thru */ + case SL_PP_WHITESPACE: i++; break; @@ -156,9 +159,12 @@ sl_pp_version(struct sl_pp_context *context, break; case SL_PP_NEWLINE: + line++; + /* pass thru */ case SL_PP_EOF: i++; *tokens_eaten = i; + context->line = line; found_end = 1; break; -- cgit v1.2.3