diff options
author | Michal Krol <michal@vmware.com> | 2009-11-10 20:49:45 +0100 |
---|---|---|
committer | Michal Krol <michal@vmware.com> | 2009-11-10 20:49:45 +0100 |
commit | d44cebd1ee7b3e461e264150a28c9d49a0f69f8f (patch) | |
tree | 8d850a088a2610fbd8ac2c5cef61f74d2fe7277d /src/glsl/pp/sl_pp_purify.c | |
parent | 4703d7d3f8d50a0ff00dd043e999b0b8b11d45e6 (diff) |
glsl/pp: Add sl_pp_purify_getc().
Diffstat (limited to 'src/glsl/pp/sl_pp_purify.c')
-rw-r--r-- | src/glsl/pp/sl_pp_purify.c | 201 |
1 files changed, 114 insertions, 87 deletions
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; } } |