From d44cebd1ee7b3e461e264150a28c9d49a0f69f8f Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 10 Nov 2009 20:49:45 +0100 Subject: glsl/pp: Add sl_pp_purify_getc(). --- src/glsl/pp/sl_pp_purify.c | 201 +++++++++++++++++++++++++-------------------- src/glsl/pp/sl_pp_purify.h | 19 +++++ 2 files changed, 133 insertions(+), 87 deletions(-) (limited to 'src') diff --git a/src/glsl/pp/sl_pp_purify.c b/src/glsl/pp/sl_pp_purify.c index 272da1e6ea..b50f819251 100644 --- a/src/glsl/pp/sl_pp_purify.c +++ b/src/glsl/pp/sl_pp_purify.c @@ -114,130 +114,150 @@ _purify_backslash(const char *input, } -struct out_buf { - char *out; - unsigned int len; - unsigned int capacity; - unsigned int current_line; - char *errormsg; - unsigned int cberrormsg; -}; - - static void -_report_error(struct out_buf *obuf, +_report_error(char *buf, + unsigned int cbbuf, const char *msg, ...) { va_list args; va_start(args, msg); - vsnprintf(obuf->errormsg, obuf->cberrormsg, msg, args); + vsnprintf(buf, cbbuf, msg, args); va_end(args); } -static int -_out_buf_putc(struct out_buf *obuf, - char c) +void +sl_pp_purify_state_init(struct sl_pp_purify_state *state, + const char *input, + const struct sl_pp_purify_options *options) { - if (obuf->len >= obuf->capacity) { - unsigned int new_max = obuf->capacity; + state->options = *options; + state->input = input; + state->current_line = 1; + state->inside_c_comment = 0; +} - if (new_max < 0x100) { - new_max = 0x100; - } else if (new_max < 0x10000) { - new_max *= 2; - } else { - new_max += 0x10000; - } - obuf->out = realloc(obuf->out, new_max); - if (!obuf->out) { - _report_error(obuf, "out of memory"); - return -1; +unsigned int +_purify_comment(struct sl_pp_purify_state *state, + char *output, + unsigned int *current_line, + char *errormsg, + unsigned int cberrormsg) +{ + for (;;) { + unsigned int eaten; + char next; + + eaten = _purify_backslash(state->input, &next, current_line); + state->input += eaten; + while (next == '*') { + eaten = _purify_backslash(state->input, &next, current_line); + state->input += eaten; + if (next == '/') { + *output = ' '; + state->inside_c_comment = 0; + return 1; + } + } + if (next == '\n') { + *output = '\n'; + state->inside_c_comment = 1; + return 1; + } + if (next == '\0') { + _report_error(errormsg, cberrormsg, "expected `*/' but end of translation unit found"); + return 0; } - obuf->capacity = new_max; } - - obuf->out[obuf->len++] = c; - - return 0; } -static unsigned int -_purify_comment(const char *input, - struct out_buf *obuf) +unsigned int +sl_pp_purify_getc(struct sl_pp_purify_state *state, + char *output, + unsigned int *current_line, + char *errormsg, + unsigned int cberrormsg) { unsigned int eaten; - char curr; - eaten = _purify_backslash(input, &curr, &obuf->current_line); - input += eaten; - if (curr == '/') { + if (state->inside_c_comment) { + return _purify_comment(state, output, current_line, errormsg, cberrormsg); + } + + eaten = _purify_backslash(state->input, output, current_line); + state->input += eaten; + if (*output == '/') { char next; - unsigned int next_eaten; - unsigned int next_line = obuf->current_line; + unsigned int next_line = *current_line; - next_eaten = _purify_backslash(input, &next, &next_line); + eaten = _purify_backslash(state->input, &next, &next_line); if (next == '/') { - eaten += next_eaten; - input += next_eaten; - obuf->current_line = next_line; + state->input += eaten; + *current_line = next_line; /* Replace a line comment with either a newline or nil. */ for (;;) { - next_eaten = _purify_backslash(input, &next, &obuf->current_line); - eaten += next_eaten; - input += next_eaten; + eaten = _purify_backslash(state->input, &next, current_line); + state->input += eaten; if (next == '\n' || next == '\0') { - if (_out_buf_putc(obuf, next)) { - return 0; - } + *output = next; return eaten; } } } else if (next == '*') { - eaten += next_eaten; - input += next_eaten; - obuf->current_line = next_line; + state->input += eaten; + *current_line = next_line; - /* Replace a block comment with a whitespace. */ - for (;;) { - next_eaten = _purify_backslash(input, &next, &obuf->current_line); - eaten += next_eaten; - input += next_eaten; - while (next == '*') { - next_eaten = _purify_backslash(input, &next, &obuf->current_line); - eaten += next_eaten; - input += next_eaten; - if (next == '/') { - if (_out_buf_putc(obuf, ' ')) { - return 0; - } - return eaten; - } - } - if (next == '\n') { - if (_out_buf_putc(obuf, '\n')) { - return 0; - } - } - if (next == '\0') { - _report_error(obuf, "expected `*/' but end of translation unit found"); - return 0; - } - } + return _purify_comment(state, output, current_line, errormsg, cberrormsg); } } - if (_out_buf_putc(obuf, curr)) { - return 0; - } return eaten; } +struct out_buf { + char *out; + unsigned int len; + unsigned int capacity; + unsigned int current_line; + char *errormsg; + unsigned int cberrormsg; +}; + + +static int +_out_buf_putc(struct out_buf *obuf, + char c) +{ + if (obuf->len >= obuf->capacity) { + unsigned int new_max = obuf->capacity; + + if (new_max < 0x100) { + new_max = 0x100; + } else if (new_max < 0x10000) { + new_max *= 2; + } else { + new_max += 0x10000; + } + + obuf->out = realloc(obuf->out, new_max); + if (!obuf->out) { + _report_error(obuf->errormsg, obuf->cberrormsg, "out of memory"); + return -1; + } + obuf->capacity = new_max; + } + + obuf->out[obuf->len++] = c; + + return 0; +} + + int sl_pp_purify(const char *input, const struct sl_pp_purify_options *options, @@ -247,6 +267,7 @@ sl_pp_purify(const char *input, unsigned int *errorline) { struct out_buf obuf; + struct sl_pp_purify_state state; obuf.out = NULL; obuf.len = 0; @@ -255,17 +276,23 @@ sl_pp_purify(const char *input, obuf.errormsg = errormsg; obuf.cberrormsg = cberrormsg; + sl_pp_purify_state_init(&state, input, options); + for (;;) { unsigned int eaten; + char c; - eaten = _purify_comment(input, &obuf); + eaten = sl_pp_purify_getc(&state, &c, &obuf.current_line, errormsg, cberrormsg); if (!eaten) { *errorline = obuf.current_line; return -1; } - input += eaten; + if (_out_buf_putc(&obuf, c)) { + *errorline = obuf.current_line; + return -1; + } - if (obuf.out[obuf.len - 1] == '\0') { + if (c == '\0') { break; } } diff --git a/src/glsl/pp/sl_pp_purify.h b/src/glsl/pp/sl_pp_purify.h index 88ea9c9e7a..c0f55cbfd8 100644 --- a/src/glsl/pp/sl_pp_purify.h +++ b/src/glsl/pp/sl_pp_purify.h @@ -41,4 +41,23 @@ sl_pp_purify(const char *input, unsigned int cberrormsg, unsigned int *errorline); +struct sl_pp_purify_state { + struct sl_pp_purify_options options; + const char *input; + unsigned int current_line; + unsigned int inside_c_comment:1; +}; + +void +sl_pp_purify_state_init(struct sl_pp_purify_state *state, + const char *input, + const struct sl_pp_purify_options *options); + +unsigned int +sl_pp_purify_getc(struct sl_pp_purify_state *state, + char *output, + unsigned int *current_line, + char *errormsg, + unsigned int cberrormsg); + #endif /* SL_PP_PURIFY_H */ -- cgit v1.2.3