summaryrefslogtreecommitdiff
path: root/src/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/SConscript3
-rw-r--r--src/glsl/apps/.gitignore5
-rw-r--r--src/glsl/apps/compile.c55
-rw-r--r--src/glsl/apps/process.c27
-rw-r--r--src/glsl/apps/tokenise.c4
-rw-r--r--src/glsl/apps/version.c24
-rw-r--r--src/glsl/cl/sl_cl_parse.c153
-rw-r--r--src/glsl/cl/sl_cl_parse.h1
-rw-r--r--src/glsl/pp/Makefile1
-rw-r--r--src/glsl/pp/sl_pp_context.c31
-rw-r--r--src/glsl/pp/sl_pp_context.h7
-rw-r--r--src/glsl/pp/sl_pp_define.c1
-rw-r--r--src/glsl/pp/sl_pp_error.c1
-rw-r--r--src/glsl/pp/sl_pp_extension.c1
-rw-r--r--src/glsl/pp/sl_pp_if.c79
-rw-r--r--src/glsl/pp/sl_pp_line.c26
-rw-r--r--src/glsl/pp/sl_pp_macro.c209
-rw-r--r--src/glsl/pp/sl_pp_macro.h4
-rw-r--r--src/glsl/pp/sl_pp_pragma.c1
-rw-r--r--src/glsl/pp/sl_pp_process.c245
-rw-r--r--src/glsl/pp/sl_pp_process.h15
-rw-r--r--src/glsl/pp/sl_pp_public.h17
-rw-r--r--src/glsl/pp/sl_pp_token.c11
-rw-r--r--src/glsl/pp/sl_pp_token.h6
-rw-r--r--src/glsl/pp/sl_pp_token_util.c182
-rw-r--r--src/glsl/pp/sl_pp_token_util.h103
-rw-r--r--src/glsl/pp/sl_pp_version.c63
27 files changed, 861 insertions, 414 deletions
diff --git a/src/glsl/SConscript b/src/glsl/SConscript
index 6f1f81b199..8e18626c40 100644
--- a/src/glsl/SConscript
+++ b/src/glsl/SConscript
@@ -18,11 +18,12 @@ sources = [
'pp/sl_pp_process.c',
'pp/sl_pp_purify.c',
'pp/sl_pp_token.c',
+ 'pp/sl_pp_token_util.c',
'pp/sl_pp_version.c',
'cl/sl_cl_parse.c',
]
-glsl = env.StaticLibrary(
+glsl = env.ConvenienceLibrary(
target = 'glsl',
source = sources,
)
diff --git a/src/glsl/apps/.gitignore b/src/glsl/apps/.gitignore
new file mode 100644
index 0000000000..7e011ce7a1
--- /dev/null
+++ b/src/glsl/apps/.gitignore
@@ -0,0 +1,5 @@
+compile
+process
+purify
+tokenise
+version
diff --git a/src/glsl/apps/compile.c b/src/glsl/apps/compile.c
index b1165420fb..c9a830b9f3 100644
--- a/src/glsl/apps/compile.c
+++ b/src/glsl/apps/compile.c
@@ -50,12 +50,8 @@ main(int argc,
struct sl_pp_purify_options options;
char errmsg[100] = "";
struct sl_pp_context *context;
- struct sl_pp_token_info *tokens;
unsigned int version;
- unsigned int tokens_eaten;
- struct sl_pp_token_info *outtokens;
FILE *out;
- unsigned int i, j;
unsigned char *outbytes;
unsigned int cboutbytes;
unsigned int shader_type;
@@ -118,7 +114,7 @@ main(int argc,
memset(&options, 0, sizeof(options));
- context = sl_pp_context_create();
+ context = sl_pp_context_create(inbuf, &options);
if (!context) {
fprintf(out, "$CONTEXERROR\n");
@@ -128,24 +124,12 @@ main(int argc,
return 0;
}
- if (sl_pp_tokenise(context, inbuf, &options, &tokens)) {
- fprintf(out, "$ERROR: `%s'\n", sl_pp_context_error_message(context));
-
- printf("Error: %s.\n", sl_pp_context_error_message(context));
- sl_pp_context_destroy(context);
- free(inbuf);
- fclose(out);
- return 0;
- }
-
- free(inbuf);
-
- if (sl_pp_version(context, tokens, &version, &tokens_eaten)) {
+ if (sl_pp_version(context, &version)) {
fprintf(out, "$ERROR: `%s'\n", sl_pp_context_error_message(context));
printf("Error: %s\n", sl_pp_context_error_message(context));
sl_pp_context_destroy(context);
- free(tokens);
+ free(inbuf);
fclose(out);
return 0;
}
@@ -156,39 +140,12 @@ main(int argc,
printf("Error: %s\n", sl_pp_context_error_message(context));
sl_pp_context_destroy(context);
- free(tokens);
- fclose(out);
- return 0;
- }
-
- if (sl_pp_process(context, &tokens[tokens_eaten], &outtokens)) {
- fprintf(out, "$ERROR: `%s'\n", sl_pp_context_error_message(context));
-
- printf("Error: %s\n", sl_pp_context_error_message(context));
- sl_pp_context_destroy(context);
- free(tokens);
+ free(inbuf);
fclose(out);
return 0;
}
- free(tokens);
-
- for (i = j = 0; outtokens[i].token != SL_PP_EOF; i++) {
- switch (outtokens[i].token) {
- case SL_PP_NEWLINE:
- case SL_PP_EXTENSION_REQUIRE:
- case SL_PP_EXTENSION_ENABLE:
- case SL_PP_EXTENSION_WARN:
- case SL_PP_EXTENSION_DISABLE:
- case SL_PP_LINE:
- break;
- default:
- outtokens[j++] = outtokens[i];
- }
- }
- outtokens[j] = outtokens[i];
-
- if (sl_cl_compile(context, outtokens, shader_type, 1, &outbytes, &cboutbytes, errmsg, sizeof(errmsg)) == 0) {
+ if (sl_cl_compile(context, shader_type, 1, &outbytes, &cboutbytes, errmsg, sizeof(errmsg)) == 0) {
unsigned int i;
unsigned int line = 0;
@@ -228,7 +185,7 @@ main(int argc,
}
sl_pp_context_destroy(context);
- free(outtokens);
+ free(inbuf);
fclose(out);
return 0;
}
diff --git a/src/glsl/apps/process.c b/src/glsl/apps/process.c
index d7bc16577e..569890210f 100644
--- a/src/glsl/apps/process.c
+++ b/src/glsl/apps/process.c
@@ -41,9 +41,7 @@ main(int argc,
char *inbuf;
struct sl_pp_purify_options options;
struct sl_pp_context *context;
- struct sl_pp_token_info *tokens;
unsigned int version;
- unsigned int tokens_eaten;
struct sl_pp_token_info *outtokens;
FILE *out;
unsigned int i;
@@ -90,7 +88,7 @@ main(int argc,
memset(&options, 0, sizeof(options));
- context = sl_pp_context_create();
+ context = sl_pp_context_create(inbuf, &options);
if (!context) {
fprintf(out, "$CONTEXERROR\n");
@@ -99,23 +97,12 @@ main(int argc,
return 1;
}
- if (sl_pp_tokenise(context, inbuf, &options, &tokens)) {
+ if (sl_pp_version(context, &version)) {
fprintf(out, "$ERROR: `%s'\n", sl_pp_context_error_message(context));
sl_pp_context_destroy(context);
free(inbuf);
fclose(out);
- return 1;
- }
-
- free(inbuf);
-
- if (sl_pp_version(context, tokens, &version, &tokens_eaten)) {
- fprintf(out, "$ERROR: `%s'\n", sl_pp_context_error_message(context));
-
- sl_pp_context_destroy(context);
- free(tokens);
- fclose(out);
return -1;
}
@@ -125,7 +112,7 @@ main(int argc,
printf("Error: %s\n", sl_pp_context_error_message(context));
sl_pp_context_destroy(context);
- free(tokens);
+ free(inbuf);
fclose(out);
return 0;
}
@@ -135,21 +122,21 @@ main(int argc,
printf("Error: %s\n", sl_pp_context_error_message(context));
sl_pp_context_destroy(context);
- free(tokens);
+ free(inbuf);
fclose(out);
return 0;
}
- if (sl_pp_process(context, &tokens[tokens_eaten], &outtokens)) {
+ if (sl_pp_process(context, &outtokens)) {
fprintf(out, "$ERROR: `%s'\n", sl_pp_context_error_message(context));
sl_pp_context_destroy(context);
- free(tokens);
+ free(inbuf);
fclose(out);
return -1;
}
- free(tokens);
+ free(inbuf);
for (i = 0; outtokens[i].token != SL_PP_EOF; i++) {
switch (outtokens[i].token) {
diff --git a/src/glsl/apps/tokenise.c b/src/glsl/apps/tokenise.c
index 91368c32a4..9ff73157e9 100644
--- a/src/glsl/apps/tokenise.c
+++ b/src/glsl/apps/tokenise.c
@@ -87,7 +87,7 @@ main(int argc,
memset(&options, 0, sizeof(options));
- context = sl_pp_context_create();
+ context = sl_pp_context_create(inbuf, &options);
if (!context) {
fprintf(out, "$CONTEXERROR\n");
@@ -96,7 +96,7 @@ main(int argc,
return 1;
}
- if (sl_pp_tokenise(context, inbuf, &options, &tokens)) {
+ if (sl_pp_tokenise(context, &tokens)) {
fprintf(out, "$ERROR: `%s'\n", sl_pp_context_error_message(context));
sl_pp_context_destroy(context);
diff --git a/src/glsl/apps/version.c b/src/glsl/apps/version.c
index 6f77f230ca..40a4a069c3 100644
--- a/src/glsl/apps/version.c
+++ b/src/glsl/apps/version.c
@@ -41,9 +41,7 @@ main(int argc,
char *inbuf;
struct sl_pp_purify_options options;
struct sl_pp_context *context;
- struct sl_pp_token_info *tokens;
unsigned int version;
- unsigned int tokens_eaten;
FILE *out;
if (argc != 3) {
@@ -88,7 +86,7 @@ main(int argc,
memset(&options, 0, sizeof(options));
- context = sl_pp_context_create();
+ context = sl_pp_context_create(inbuf, &options);
if (!context) {
fprintf(out, "$CONTEXERROR\n");
@@ -97,33 +95,19 @@ main(int argc,
return 1;
}
- if (sl_pp_tokenise(context, inbuf, &options, &tokens)) {
+ if (sl_pp_version(context, &version)) {
fprintf(out, "$ERROR: `%s'\n", sl_pp_context_error_message(context));
sl_pp_context_destroy(context);
free(inbuf);
fclose(out);
- return 1;
- }
-
- free(inbuf);
-
- if (sl_pp_version(context, tokens, &version, &tokens_eaten)) {
- fprintf(out, "$ERROR: `%s'\n", sl_pp_context_error_message(context));
-
- sl_pp_context_destroy(context);
- free(tokens);
- fclose(out);
return -1;
}
sl_pp_context_destroy(context);
- free(tokens);
+ free(inbuf);
- fprintf(out,
- "%u\n%u\n",
- version,
- tokens_eaten);
+ fprintf(out, "%u\n", version);
fclose(out);
diff --git a/src/glsl/cl/sl_cl_parse.c b/src/glsl/cl/sl_cl_parse.c
index a9db65c7ad..e9b3707ac1 100644
--- a/src/glsl/cl/sl_cl_parse.c
+++ b/src/glsl/cl/sl_cl_parse.c
@@ -321,10 +321,13 @@ struct parse_dict {
struct parse_context {
struct sl_pp_context *context;
- const struct sl_pp_token_info *input;
struct parse_dict dict;
+ struct sl_pp_token_info *tokens;
+ unsigned int tokens_read;
+ unsigned int tokens_cap;
+
unsigned char *out_buf;
unsigned int out_cap;
@@ -332,6 +335,7 @@ struct parse_context {
unsigned int parsing_builtin;
char error[256];
+ int process_error;
};
@@ -366,7 +370,7 @@ _update(struct parse_context *ctx,
static void
_error(struct parse_context *ctx,
- char *msg)
+ const char *msg)
{
if (ctx->error[0] == '\0') {
strcpy(ctx->error, msg);
@@ -374,12 +378,98 @@ _error(struct parse_context *ctx,
}
+static const struct sl_pp_token_info *
+_fetch_token(struct parse_context *ctx,
+ unsigned int pos)
+{
+ if (ctx->process_error) {
+ return NULL;
+ }
+
+ while (pos >= ctx->tokens_read) {
+ if (ctx->tokens_read == ctx->tokens_cap) {
+ ctx->tokens_cap += 1024;
+ ctx->tokens = realloc(ctx->tokens,
+ ctx->tokens_cap * sizeof(struct sl_pp_token_info));
+ if (!ctx->tokens) {
+ _error(ctx, "out of memory");
+ ctx->process_error = 1;
+ return NULL;
+ }
+ }
+ if (sl_pp_process_get(ctx->context, &ctx->tokens[ctx->tokens_read])) {
+ _error(ctx, sl_pp_context_error_message(ctx->context));
+ ctx->process_error = 1;
+ return NULL;
+ }
+ switch (ctx->tokens[ctx->tokens_read].token) {
+ case SL_PP_COMMA:
+ case SL_PP_SEMICOLON:
+ case SL_PP_LBRACE:
+ case SL_PP_RBRACE:
+ case SL_PP_LPAREN:
+ case SL_PP_RPAREN:
+ case SL_PP_LBRACKET:
+ case SL_PP_RBRACKET:
+ case SL_PP_DOT:
+ case SL_PP_INCREMENT:
+ case SL_PP_ADDASSIGN:
+ case SL_PP_PLUS:
+ case SL_PP_DECREMENT:
+ case SL_PP_SUBASSIGN:
+ case SL_PP_MINUS:
+ case SL_PP_BITNOT:
+ case SL_PP_NOTEQUAL:
+ case SL_PP_NOT:
+ case SL_PP_MULASSIGN:
+ case SL_PP_STAR:
+ case SL_PP_DIVASSIGN:
+ case SL_PP_SLASH:
+ case SL_PP_MODASSIGN:
+ case SL_PP_MODULO:
+ case SL_PP_LSHIFTASSIGN:
+ case SL_PP_LSHIFT:
+ case SL_PP_LESSEQUAL:
+ case SL_PP_LESS:
+ case SL_PP_RSHIFTASSIGN:
+ case SL_PP_RSHIFT:
+ case SL_PP_GREATEREQUAL:
+ case SL_PP_GREATER:
+ case SL_PP_EQUAL:
+ case SL_PP_ASSIGN:
+ case SL_PP_AND:
+ case SL_PP_BITANDASSIGN:
+ case SL_PP_BITAND:
+ case SL_PP_XOR:
+ case SL_PP_BITXORASSIGN:
+ case SL_PP_BITXOR:
+ case SL_PP_OR:
+ case SL_PP_BITORASSIGN:
+ case SL_PP_BITOR:
+ case SL_PP_QUESTION:
+ case SL_PP_COLON:
+ case SL_PP_IDENTIFIER:
+ case SL_PP_UINT:
+ case SL_PP_FLOAT:
+ case SL_PP_EOF:
+ ctx->tokens_read++;
+ break;
+ default:
+ ; /* no-op */
+ }
+ }
+ return &ctx->tokens[pos];
+}
+
+
static int
_parse_token(struct parse_context *ctx,
enum sl_pp_token token,
struct parse_state *ps)
{
- if (ctx->input[ps->in].token == token) {
+ const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in);
+
+ if (input && input->token == token) {
ps->in++;
return 0;
}
@@ -392,8 +482,9 @@ _parse_id(struct parse_context *ctx,
int id,
struct parse_state *ps)
{
- if (ctx->input[ps->in].token == SL_PP_IDENTIFIER &&
- ctx->input[ps->in].data.identifier == id) {
+ const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in);
+
+ if (input && input->token == SL_PP_IDENTIFIER && input->data.identifier == id) {
ps->in++;
return 0;
}
@@ -405,8 +496,10 @@ static int
_parse_identifier(struct parse_context *ctx,
struct parse_state *ps)
{
- if (ctx->input[ps->in].token == SL_PP_IDENTIFIER) {
- const char *cstr = sl_pp_context_cstr(ctx->context, ctx->input[ps->in].data.identifier);
+ const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in);
+
+ if (input && input->token == SL_PP_IDENTIFIER) {
+ const char *cstr = sl_pp_context_cstr(ctx->context, input->data.identifier);
do {
_emit(ctx, &ps->out, *cstr);
@@ -422,8 +515,10 @@ static int
_parse_float(struct parse_context *ctx,
struct parse_state *ps)
{
- if (ctx->input[ps->in].token == SL_PP_FLOAT) {
- const char *cstr = sl_pp_context_cstr(ctx->context, ctx->input[ps->in].data._float);
+ const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in);
+
+ if (input && input->token == SL_PP_FLOAT) {
+ const char *cstr = sl_pp_context_cstr(ctx->context, input->data._float);
_emit(ctx, &ps->out, 1);
do {
@@ -440,8 +535,10 @@ static int
_parse_uint(struct parse_context *ctx,
struct parse_state *ps)
{
- if (ctx->input[ps->in].token == SL_PP_UINT) {
- const char *cstr = sl_pp_context_cstr(ctx->context, ctx->input[ps->in].data._uint);
+ const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in);
+
+ if (input && input->token == SL_PP_UINT) {
+ const char *cstr = sl_pp_context_cstr(ctx->context, input->data._uint);
_emit(ctx, &ps->out, 1);
do {
@@ -614,13 +711,14 @@ _parse_type_qualifier(struct parse_context *ctx,
struct parse_state *ps)
{
struct parse_state p = *ps;
+ const struct sl_pp_token_info *input = _fetch_token(ctx, p.in);
unsigned int e = _emit(ctx, &p.out, 0);
int id;
- if (ctx->input[p.in].token != SL_PP_IDENTIFIER) {
+ if (!input || input->token != SL_PP_IDENTIFIER) {
return -1;
}
- id = ctx->input[p.in].data.identifier;
+ id = input->data.identifier;
if (id == ctx->dict._const) {
_update(ctx, e, TYPE_QUALIFIER_CONST);
@@ -771,6 +869,7 @@ _parse_type_specifier_nonarray(struct parse_context *ctx,
{
struct parse_state p = *ps;
unsigned int e = _emit(ctx, &p.out, 0);
+ const struct sl_pp_token_info *input;
int id;
if (_parse_struct_specifier(ctx, &p) == 0) {
@@ -779,10 +878,11 @@ _parse_type_specifier_nonarray(struct parse_context *ctx,
return 0;
}
- if (ctx->input[p.in].token != SL_PP_IDENTIFIER) {
+ input = _fetch_token(ctx, p.in);
+ if (!input || input->token != SL_PP_IDENTIFIER) {
return -1;
}
- id = ctx->input[p.in].data.identifier;
+ id = input->data.identifier;
if (id == ctx->dict._void) {
_update(ctx, e, TYPE_SPECIFIER_VOID);
@@ -1696,13 +1796,14 @@ static int
_parse_precision(struct parse_context *ctx,
struct parse_state *ps)
{
+ const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in);
int id;
unsigned int precision;
- if (ctx->input[ps->in].token != SL_PP_IDENTIFIER) {
+ if (!input || input->token != SL_PP_IDENTIFIER) {
return -1;
}
- id = ctx->input[ps->in].data.identifier;
+ id = input->data.identifier;
if (id == ctx->dict.lowp) {
precision = PRECISION_LOW;
@@ -1724,13 +1825,14 @@ static int
_parse_prectype(struct parse_context *ctx,
struct parse_state *ps)
{
+ const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in);
int id;
unsigned int type;
- if (ctx->input[ps->in].token != SL_PP_IDENTIFIER) {
+ if (!input || input->token != SL_PP_IDENTIFIER) {
return -1;
}
- id = ctx->input[ps->in].data.identifier;
+ id = input->data.identifier;
if (id == ctx->dict._int) {
type = TYPE_SPECIFIER_INT;
@@ -2607,7 +2709,6 @@ _parse_translation_unit(struct parse_context *ctx,
int
sl_cl_compile(struct sl_pp_context *context,
- const struct sl_pp_token_info *input,
unsigned int shader_type,
unsigned int parsing_builtin,
unsigned char **output,
@@ -2619,7 +2720,6 @@ sl_cl_compile(struct sl_pp_context *context,
struct parse_state ps;
ctx.context = context;
- ctx.input = input;
ADD_NAME_STR(ctx, _void, "void");
ADD_NAME_STR(ctx, _float, "float");
@@ -2699,16 +2799,27 @@ sl_cl_compile(struct sl_pp_context *context,
ctx.parsing_builtin = 1;
ctx.error[0] = '\0';
+ ctx.process_error = 0;
+
+ ctx.tokens_cap = 1024;
+ ctx.tokens_read = 0;
+ ctx.tokens = malloc(ctx.tokens_cap * sizeof(struct sl_pp_token_info));
+ if (!ctx.tokens) {
+ strncpy(error, "out of memory", cberror);
+ return -1;
+ }
ps.in = 0;
ps.out = 0;
if (_parse_translation_unit(&ctx, &ps)) {
strncpy(error, ctx.error, cberror);
+ free(ctx.tokens);
return -1;
}
*output = ctx.out_buf;
*cboutput = ps.out;
+ free(ctx.tokens);
return 0;
}
diff --git a/src/glsl/cl/sl_cl_parse.h b/src/glsl/cl/sl_cl_parse.h
index 23a0d5fee0..dd5791d590 100644
--- a/src/glsl/cl/sl_cl_parse.h
+++ b/src/glsl/cl/sl_cl_parse.h
@@ -30,7 +30,6 @@
int
sl_cl_compile(struct sl_pp_context *context,
- const struct sl_pp_token_info *input,
unsigned int shader_type,
unsigned int parsing_builtin,
unsigned char **output,
diff --git a/src/glsl/pp/Makefile b/src/glsl/pp/Makefile
index 819079f625..fda1c4202b 100644
--- a/src/glsl/pp/Makefile
+++ b/src/glsl/pp/Makefile
@@ -20,6 +20,7 @@ C_SOURCES = \
sl_pp_process.c \
sl_pp_purify.c \
sl_pp_token.c \
+ sl_pp_token_util.c \
sl_pp_version.c
include ../Makefile.template
diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c
index afc1b84d16..74a9bdddfd 100644
--- a/src/glsl/pp/sl_pp_context.c
+++ b/src/glsl/pp/sl_pp_context.c
@@ -32,7 +32,8 @@
struct sl_pp_context *
-sl_pp_context_create(void)
+sl_pp_context_create(const char *input,
+ const struct sl_pp_purify_options *options)
{
struct sl_pp_context *context;
@@ -46,19 +47,30 @@ sl_pp_context_create(void)
return NULL;
}
- context->getc_buf = malloc(64 * sizeof(char));
+ context->getc_buf_capacity = 64;
+ context->getc_buf = malloc(context->getc_buf_capacity * sizeof(char));
if (!context->getc_buf) {
sl_pp_context_destroy(context);
return NULL;
}
+ if (sl_pp_token_buffer_init(&context->tokens, context)) {
+ sl_pp_context_destroy(context);
+ return NULL;
+ }
+
context->macro_tail = &context->macro;
context->if_ptr = SL_PP_MAX_IF_NESTING;
context->if_value = 1;
memset(context->error_msg, 0, sizeof(context->error_msg));
+ context->error_line = 1;
context->line = 1;
context->file = 0;
+ sl_pp_purify_state_init(&context->pure, input, options);
+
+ memset(&context->process_state, 0, sizeof(context->process_state));
+
return context;
}
@@ -69,6 +81,8 @@ sl_pp_context_destroy(struct sl_pp_context *context)
free(context->cstr_pool);
sl_pp_macro_free(context->macro);
free(context->getc_buf);
+ sl_pp_token_buffer_destroy(&context->tokens);
+ free(context->process_state.out);
free(context);
}
}
@@ -79,6 +93,19 @@ sl_pp_context_error_message(const struct sl_pp_context *context)
return context->error_msg;
}
+void
+sl_pp_context_error_position(const struct sl_pp_context *context,
+ unsigned int *file,
+ unsigned int *line)
+{
+ if (file) {
+ *file = 0;
+ }
+ if (line) {
+ *line = context->error_line;
+ }
+}
+
int
sl_pp_context_add_predefined(struct sl_pp_context *context,
const char *name,
diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h
index d95d29e275..3eada380cd 100644
--- a/src/glsl/pp/sl_pp_context.h
+++ b/src/glsl/pp/sl_pp_context.h
@@ -30,7 +30,9 @@
#include "sl_pp_dict.h"
#include "sl_pp_macro.h"
+#include "sl_pp_process.h"
#include "sl_pp_purify.h"
+#include "sl_pp_token_util.h"
#define SL_PP_MAX_IF_NESTING 64
@@ -71,6 +73,7 @@ struct sl_pp_context {
unsigned int if_value;
char error_msg[SL_PP_MAX_ERROR_MSG];
+ unsigned int error_line;
unsigned int line;
unsigned int file;
@@ -80,6 +83,10 @@ struct sl_pp_context {
char *getc_buf;
unsigned int getc_buf_size;
unsigned int getc_buf_capacity;
+
+ struct sl_pp_token_buffer tokens;
+
+ struct sl_pp_process_state process_state;
};
#endif /* SL_PP_CONTEXT_H */
diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c
index e004c9f95b..808a6a0d4f 100644
--- a/src/glsl/pp/sl_pp_define.c
+++ b/src/glsl/pp/sl_pp_define.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
+#include "sl_pp_context.h"
#include "sl_pp_process.h"
#include "sl_pp_public.h"
diff --git a/src/glsl/pp/sl_pp_error.c b/src/glsl/pp/sl_pp_error.c
index a9eeff98ba..b628e37ce8 100644
--- a/src/glsl/pp/sl_pp_error.c
+++ b/src/glsl/pp/sl_pp_error.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
+#include "sl_pp_context.h"
#include "sl_pp_process.h"
#include "sl_pp_public.h"
diff --git a/src/glsl/pp/sl_pp_extension.c b/src/glsl/pp/sl_pp_extension.c
index 67b24404d4..8af5731e84 100644
--- a/src/glsl/pp/sl_pp_extension.c
+++ b/src/glsl/pp/sl_pp_extension.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
+#include "sl_pp_context.h"
#include "sl_pp_process.h"
#include "sl_pp_public.h"
diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c
index 6610bc69f3..f12f0f142c 100644
--- a/src/glsl/pp/sl_pp_if.c
+++ b/src/glsl/pp/sl_pp_if.c
@@ -31,55 +31,50 @@
#include "sl_pp_process.h"
-static void
-skip_whitespace(const struct sl_pp_token_info *input,
- unsigned int *pi)
-{
- while (input[*pi].token == SL_PP_WHITESPACE) {
- (*pi)++;
- }
-}
-
static int
_parse_defined(struct sl_pp_context *context,
- const struct sl_pp_token_info *input,
- unsigned int *pi,
+ struct sl_pp_token_buffer *buffer,
struct sl_pp_process_state *state)
{
+ struct sl_pp_token_info input;
int parens = 0;
int macro_name;
struct sl_pp_macro *macro;
int defined = 0;
struct sl_pp_token_info result;
- skip_whitespace(input, pi);
- if (input[*pi].token == SL_PP_LPAREN) {
- (*pi)++;
- skip_whitespace(input, pi);
+ if (sl_pp_token_buffer_skip_white(buffer, &input)) {
+ return -1;
+ }
+
+ if (input.token == SL_PP_LPAREN) {
+ if (sl_pp_token_buffer_skip_white(buffer, &input)) {
+ return -1;
+ }
parens = 1;
}
- if (input[*pi].token != SL_PP_IDENTIFIER) {
+ if (input.token != SL_PP_IDENTIFIER) {
strcpy(context->error_msg, "expected an identifier");
return -1;
}
- macro_name = input[*pi].data.identifier;
+ macro_name = input.data.identifier;
for (macro = context->macro; macro; macro = macro->next) {
if (macro->name == macro_name) {
defined = 1;
break;
}
}
- (*pi)++;
if (parens) {
- skip_whitespace(input, pi);
- if (input[*pi].token != SL_PP_RPAREN) {
+ if (sl_pp_token_buffer_skip_white(buffer, &input)) {
+ return -1;
+ }
+ if (input.token != SL_PP_RPAREN) {
strcpy(context->error_msg, "expected `)'");
return -1;
}
- (*pi)++;
}
result.token = SL_PP_UINT;
@@ -108,12 +103,10 @@ _evaluate_if_stack(struct sl_pp_context *context)
static int
_parse_if(struct sl_pp_context *context,
- const struct sl_pp_token_info *input,
- unsigned int first,
- unsigned int last)
+ struct sl_pp_token_buffer *buffer)
{
- unsigned int i;
struct sl_pp_process_state state;
+ int found_end = 0;
struct sl_pp_token_info eof;
int result;
@@ -123,34 +116,40 @@ _parse_if(struct sl_pp_context *context,
}
memset(&state, 0, sizeof(state));
- for (i = first; i < last;) {
- switch (input[i].token) {
+ while (!found_end) {
+ struct sl_pp_token_info input;
+
+ sl_pp_token_buffer_get(buffer, &input);
+ switch (input.token) {
case SL_PP_WHITESPACE:
- i++;
break;
case SL_PP_IDENTIFIER:
- if (input[i].data.identifier == context->dict.defined) {
- i++;
- if (_parse_defined(context, input, &i, &state)) {
+ if (input.data.identifier == context->dict.defined) {
+ if (_parse_defined(context, buffer, &state)) {
free(state.out);
return -1;
}
} else {
- if (sl_pp_macro_expand(context, input, &i, NULL, &state, sl_pp_macro_expand_unknown_to_0)) {
+ sl_pp_token_buffer_unget(buffer, &input);
+ if (sl_pp_macro_expand(context, buffer, NULL, &state, sl_pp_macro_expand_unknown_to_0)) {
free(state.out);
return -1;
}
}
break;
+ case SL_PP_NEWLINE:
+ case SL_PP_EOF:
+ found_end = 1;
+ break;
+
default:
- if (sl_pp_process_out(&state, &input[i])) {
+ if (sl_pp_process_out(&state, &input)) {
strcpy(context->error_msg, "out of memory");
free(state.out);
return -1;
}
- i++;
}
}
@@ -198,11 +197,9 @@ _parse_else(struct sl_pp_context *context)
int
sl_pp_process_if(struct sl_pp_context *context,
- const struct sl_pp_token_info *input,
- unsigned int first,
- unsigned int last)
+ struct sl_pp_token_buffer *buffer)
{
- return _parse_if(context, input, first, last);
+ return _parse_if(context, buffer);
}
int
@@ -301,9 +298,7 @@ sl_pp_process_ifndef(struct sl_pp_context *context,
int
sl_pp_process_elif(struct sl_pp_context *context,
- const struct sl_pp_token_info *input,
- unsigned int first,
- unsigned int last)
+ struct sl_pp_token_buffer *buffer)
{
if (_parse_else(context)) {
return -1;
@@ -311,7 +306,7 @@ sl_pp_process_elif(struct sl_pp_context *context,
if (context->if_stack[context->if_ptr] & 1) {
context->if_ptr++;
- if (_parse_if(context, input, first, last)) {
+ if (_parse_if(context, buffer)) {
return -1;
}
}
diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c
index ed5acc697c..6f7e9eb562 100644
--- a/src/glsl/pp/sl_pp_line.c
+++ b/src/glsl/pp/sl_pp_line.c
@@ -27,45 +27,51 @@
#include <stdlib.h>
#include <string.h>
+#include "sl_pp_context.h"
#include "sl_pp_public.h"
#include "sl_pp_process.h"
int
sl_pp_process_line(struct sl_pp_context *context,
- const struct sl_pp_token_info *input,
- unsigned int first,
- unsigned int last,
+ struct sl_pp_token_buffer *buffer,
struct sl_pp_process_state *pstate)
{
- unsigned int i;
struct sl_pp_process_state state;
+ int found_end = 0;
int line_number = -1;
int file_number = -1;
unsigned int line;
unsigned int file;
memset(&state, 0, sizeof(state));
- for (i = first; i < last;) {
- switch (input[i].token) {
+ while (!found_end) {
+ struct sl_pp_token_info input;
+
+ sl_pp_token_buffer_get(buffer, &input);
+ switch (input.token) {
case SL_PP_WHITESPACE:
- i++;
break;
case SL_PP_IDENTIFIER:
- if (sl_pp_macro_expand(context, input, &i, NULL, &state, sl_pp_macro_expand_normal)) {
+ sl_pp_token_buffer_unget(buffer, &input);
+ if (sl_pp_macro_expand(context, buffer, NULL, &state, sl_pp_macro_expand_normal)) {
free(state.out);
return -1;
}
break;
+ case SL_PP_NEWLINE:
+ case SL_PP_EOF:
+ found_end = 1;
+ break;
+
default:
- if (sl_pp_process_out(&state, &input[i])) {
+ if (sl_pp_process_out(&state, &input)) {
strcpy(context->error_msg, "out of memory");
free(state.out);
return -1;
}
- i++;
}
}
diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c
index 08b44c7cbe..9f520b8fc5 100644
--- a/src/glsl/pp/sl_pp_macro.c
+++ b/src/glsl/pp/sl_pp_macro.c
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include "sl_pp_context.h"
#include "sl_pp_public.h"
#include "sl_pp_macro.h"
#include "sl_pp_process.h"
@@ -88,15 +89,6 @@ sl_pp_macro_reset(struct sl_pp_macro *macro)
_macro_init(macro);
}
-static void
-skip_whitespace(const struct sl_pp_token_info *input,
- unsigned int *pi)
-{
- while (input[*pi].token == SL_PP_WHITESPACE) {
- (*pi)++;
- }
-}
-
static int
_out_number(struct sl_pp_context *context,
struct sl_pp_process_state *state,
@@ -119,24 +111,28 @@ _out_number(struct sl_pp_context *context,
int
sl_pp_macro_expand(struct sl_pp_context *context,
- const struct sl_pp_token_info *input,
- unsigned int *pi,
+ struct sl_pp_token_buffer *tokens,
struct sl_pp_macro *local,
struct sl_pp_process_state *state,
enum sl_pp_macro_expand_behaviour behaviour)
{
int mute = (behaviour == sl_pp_macro_expand_mute);
+ struct sl_pp_token_info input;
int macro_name;
struct sl_pp_macro *macro = NULL;
struct sl_pp_macro *actual_arg = NULL;
unsigned int j;
- if (input[*pi].token != SL_PP_IDENTIFIER) {
+ if (sl_pp_token_buffer_get(tokens, &input)) {
+ return -1;
+ }
+
+ if (input.token != SL_PP_IDENTIFIER) {
strcpy(context->error_msg, "expected an identifier");
return -1;
}
- macro_name = input[*pi].data.identifier;
+ macro_name = input.data.identifier;
/* First look for predefined macros.
*/
@@ -145,21 +141,18 @@ sl_pp_macro_expand(struct sl_pp_context *context,
if (!mute && _out_number(context, state, context->line)) {
return -1;
}
- (*pi)++;
return 0;
}
if (macro_name == context->dict.___FILE__) {
if (!mute && _out_number(context, state, context->file)) {
return -1;
}
- (*pi)++;
return 0;
}
if (macro_name == context->dict.___VERSION__) {
if (!mute && _out_number(context, state, 110)) {
return -1;
}
- (*pi)++;
return 0;
}
@@ -175,7 +168,6 @@ sl_pp_macro_expand(struct sl_pp_context *context,
return -1;
}
}
- (*pi)++;
return 0;
}
}
@@ -187,16 +179,10 @@ sl_pp_macro_expand(struct sl_pp_context *context,
if (!mute && _out_number(context, state, 1)) {
return -1;
}
- (*pi)++;
return 0;
}
}
- /* TODO: For FEATURE_es2_glsl, expand to 1 the following symbols.
- * GL_ES
- * GL_FRAGMENT_PRECISION_HIGH
- */
-
if (local) {
for (macro = local; macro; macro = macro->next) {
if (macro->name == macro_name) {
@@ -220,25 +206,26 @@ sl_pp_macro_expand(struct sl_pp_context *context,
return -1;
}
} else if (!mute) {
- if (sl_pp_process_out(state, &input[*pi])) {
+ if (sl_pp_process_out(state, &input)) {
strcpy(context->error_msg, "out of memory");
return -1;
}
}
- (*pi)++;
return 0;
}
- (*pi)++;
-
if (macro->num_args >= 0) {
- skip_whitespace(input, pi);
- if (input[*pi].token != SL_PP_LPAREN) {
+ if (sl_pp_token_buffer_skip_white(tokens, &input)) {
+ return -1;
+ }
+ if (input.token != SL_PP_LPAREN) {
strcpy(context->error_msg, "expected `('");
return -1;
}
- (*pi)++;
- skip_whitespace(input, pi);
+ if (sl_pp_token_buffer_skip_white(tokens, &input)) {
+ return -1;
+ }
+ sl_pp_token_buffer_unget(tokens, &input);
}
if (macro->num_args > 0) {
@@ -247,103 +234,85 @@ sl_pp_macro_expand(struct sl_pp_context *context,
for (j = 0; j < (unsigned int)macro->num_args; j++) {
struct sl_pp_process_state arg_state;
- unsigned int i;
int done = 0;
unsigned int paren_nesting = 0;
struct sl_pp_token_info eof;
memset(&arg_state, 0, sizeof(arg_state));
- for (i = *pi; !done;) {
- switch (input[i].token) {
+ while (!done) {
+ if (sl_pp_token_buffer_get(tokens, &input)) {
+ goto fail_arg;
+ }
+ switch (input.token) {
case SL_PP_WHITESPACE:
- i++;
break;
case SL_PP_COMMA:
if (!paren_nesting) {
if (j < (unsigned int)macro->num_args - 1) {
done = 1;
- i++;
} else {
strcpy(context->error_msg, "too many actual macro arguments");
- return -1;
+ goto fail_arg;
}
} else {
- if (sl_pp_process_out(&arg_state, &input[i])) {
+ if (sl_pp_process_out(&arg_state, &input)) {
strcpy(context->error_msg, "out of memory");
- free(arg_state.out);
- return -1;
+ goto fail_arg;
}
- i++;
}
break;
case SL_PP_LPAREN:
paren_nesting++;
- if (sl_pp_process_out(&arg_state, &input[i])) {
- strcpy(context->error_msg, "out of memory");
- free(arg_state.out);
- return -1;
+ if (sl_pp_process_out(&arg_state, &input)) {
+ goto oom_arg;
}
- i++;
break;
case SL_PP_RPAREN:
if (!paren_nesting) {
if (j == (unsigned int)macro->num_args - 1) {
done = 1;
- i++;
} else {
strcpy(context->error_msg, "too few actual macro arguments");
- return -1;
+ goto fail_arg;
}
} else {
paren_nesting--;
- if (sl_pp_process_out(&arg_state, &input[i])) {
- strcpy(context->error_msg, "out of memory");
- free(arg_state.out);
- return -1;
+ if (sl_pp_process_out(&arg_state, &input)) {
+ goto oom_arg;
}
- i++;
}
break;
case SL_PP_IDENTIFIER:
- if (sl_pp_macro_expand(context, input, &i, local, &arg_state, sl_pp_macro_expand_normal)) {
- free(arg_state.out);
- return -1;
+ sl_pp_token_buffer_unget(tokens, &input);
+ if (sl_pp_macro_expand(context, tokens, local, &arg_state, sl_pp_macro_expand_normal)) {
+ goto fail_arg;
}
break;
case SL_PP_EOF:
strcpy(context->error_msg, "too few actual macro arguments");
- return -1;
+ goto fail_arg;
default:
- if (sl_pp_process_out(&arg_state, &input[i])) {
- strcpy(context->error_msg, "out of memory");
- free(arg_state.out);
- return -1;
+ if (sl_pp_process_out(&arg_state, &input)) {
+ goto oom_arg;
}
- i++;
}
}
- (*pi) = i;
-
eof.token = SL_PP_EOF;
if (sl_pp_process_out(&arg_state, &eof)) {
- strcpy(context->error_msg, "out of memory");
- free(arg_state.out);
- return -1;
+ goto oom_arg;
}
*pmacro = sl_pp_macro_new();
if (!*pmacro) {
- strcpy(context->error_msg, "out of memory");
- free(arg_state.out);
- return -1;
+ goto oom_arg;
}
(**pmacro).name = formal_arg->name;
@@ -351,47 +320,95 @@ sl_pp_macro_expand(struct sl_pp_context *context,
formal_arg = formal_arg->next;
pmacro = &(**pmacro).next;
+
+ continue;
+
+oom_arg:
+ strcpy(context->error_msg, "out of memory");
+fail_arg:
+ free(arg_state.out);
+ goto fail;
}
}
/* Right paren for non-empty argument list has already been eaten. */
if (macro->num_args == 0) {
- skip_whitespace(input, pi);
- if (input[*pi].token != SL_PP_RPAREN) {
+ if (sl_pp_token_buffer_skip_white(tokens, &input)) {
+ goto fail;
+ }
+ if (input.token != SL_PP_RPAREN) {
strcpy(context->error_msg, "expected `)'");
- return -1;
+ goto fail;
}
- (*pi)++;
}
- for (j = 0;;) {
- switch (macro->body[j].token) {
- case SL_PP_NEWLINE:
- if (sl_pp_process_out(state, &macro->body[j])) {
- strcpy(context->error_msg, "out of memory");
- return -1;
- }
- j++;
- break;
+ /* XXX: This is all wrong, we should be ungetting all tokens
+ * back to the main token buffer.
+ */
+ {
+ struct sl_pp_token_buffer buffer;
- case SL_PP_IDENTIFIER:
- if (sl_pp_macro_expand(context, macro->body, &j, actual_arg, state, behaviour)) {
- return -1;
- }
- break;
+ /* Seek to the end.
+ */
+ for (j = 0; macro->body[j].token != SL_PP_EOF; j++) {
+ }
+ j++;
+
+ /* Create a context-less token buffer since we are not going to underrun
+ * its internal buffer.
+ */
+ if (sl_pp_token_buffer_init(&buffer, NULL)) {
+ strcpy(context->error_msg, "out of memory");
+ goto fail;
+ }
- case SL_PP_EOF:
- sl_pp_macro_free(actual_arg);
- return 0;
+ /* Unget the tokens in reverse order so later they will be fetched correctly.
+ */
+ for (; j > 0; j--) {
+ sl_pp_token_buffer_unget(&buffer, &macro->body[j - 1]);
+ }
- default:
- if (!mute) {
- if (sl_pp_process_out(state, &macro->body[j])) {
+ /* Expand.
+ */
+ for (;;) {
+ struct sl_pp_token_info input;
+
+ sl_pp_token_buffer_get(&buffer, &input);
+ switch (input.token) {
+ case SL_PP_NEWLINE:
+ if (sl_pp_process_out(state, &input)) {
strcpy(context->error_msg, "out of memory");
- return -1;
+ sl_pp_token_buffer_destroy(&buffer);
+ goto fail;
+ }
+ break;
+
+ case SL_PP_IDENTIFIER:
+ sl_pp_token_buffer_unget(&buffer, &input);
+ if (sl_pp_macro_expand(context, &buffer, actual_arg, state, behaviour)) {
+ sl_pp_token_buffer_destroy(&buffer);
+ goto fail;
+ }
+ break;
+
+ case SL_PP_EOF:
+ sl_pp_token_buffer_destroy(&buffer);
+ sl_pp_macro_free(actual_arg);
+ return 0;
+
+ default:
+ if (!mute) {
+ if (sl_pp_process_out(state, &input)) {
+ strcpy(context->error_msg, "out of memory");
+ sl_pp_token_buffer_destroy(&buffer);
+ goto fail;
+ }
}
}
- j++;
}
}
+
+fail:
+ sl_pp_macro_free(actual_arg);
+ return -1;
}
diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h
index 3ad3438236..1d21068109 100644
--- a/src/glsl/pp/sl_pp_macro.h
+++ b/src/glsl/pp/sl_pp_macro.h
@@ -33,6 +33,7 @@
struct sl_pp_context;
struct sl_pp_process_state;
+struct sl_pp_token_buffer;
struct sl_pp_macro_formal_arg {
int name;
@@ -64,8 +65,7 @@ enum sl_pp_macro_expand_behaviour {
int
sl_pp_macro_expand(struct sl_pp_context *context,
- const struct sl_pp_token_info *input,
- unsigned int *pi,
+ struct sl_pp_token_buffer *tokens,
struct sl_pp_macro *local,
struct sl_pp_process_state *state,
enum sl_pp_macro_expand_behaviour behaviour);
diff --git a/src/glsl/pp/sl_pp_pragma.c b/src/glsl/pp/sl_pp_pragma.c
index 489eb17b8e..caf4c63f65 100644
--- a/src/glsl/pp/sl_pp_pragma.c
+++ b/src/glsl/pp/sl_pp_pragma.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
+#include "sl_pp_context.h"
#include "sl_pp_process.h"
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;
+ }
+ }
}
diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h
index 24311bab60..fe6ff0d464 100644
--- a/src/glsl/pp/sl_pp_process.h
+++ b/src/glsl/pp/sl_pp_process.h
@@ -28,11 +28,12 @@
#ifndef SL_PP_PROCESS_H
#define SL_PP_PROCESS_H
-#include "sl_pp_context.h"
#include "sl_pp_macro.h"
#include "sl_pp_token.h"
+struct sl_pp_context;
+
struct sl_pp_process_state {
struct sl_pp_token_info *out;
unsigned int out_len;
@@ -53,9 +54,7 @@ sl_pp_process_undef(struct sl_pp_context *context,
int
sl_pp_process_if(struct sl_pp_context *context,
- const struct sl_pp_token_info *input,
- unsigned int first,
- unsigned int last);
+ struct sl_pp_token_buffer *input);
int
sl_pp_process_ifdef(struct sl_pp_context *context,
@@ -71,9 +70,7 @@ sl_pp_process_ifndef(struct sl_pp_context *context,
int
sl_pp_process_elif(struct sl_pp_context *context,
- const struct sl_pp_token_info *input,
- unsigned int first,
- unsigned int last);
+ struct sl_pp_token_buffer *buffer);
int
sl_pp_process_else(struct sl_pp_context *context,
@@ -109,9 +106,7 @@ sl_pp_process_extension(struct sl_pp_context *context,
int
sl_pp_process_line(struct sl_pp_context *context,
- const struct sl_pp_token_info *input,
- unsigned int first,
- unsigned int last,
+ struct sl_pp_token_buffer *buffer,
struct sl_pp_process_state *state);
int
diff --git a/src/glsl/pp/sl_pp_public.h b/src/glsl/pp/sl_pp_public.h
index 076903649c..12528d6f8d 100644
--- a/src/glsl/pp/sl_pp_public.h
+++ b/src/glsl/pp/sl_pp_public.h
@@ -37,7 +37,8 @@ struct sl_pp_context;
struct sl_pp_context *
-sl_pp_context_create(void);
+sl_pp_context_create(const char *input,
+ const struct sl_pp_purify_options *options);
void
sl_pp_context_destroy(struct sl_pp_context *context);
@@ -45,6 +46,11 @@ sl_pp_context_destroy(struct sl_pp_context *context);
const char *
sl_pp_context_error_message(const struct sl_pp_context *context);
+void
+sl_pp_context_error_position(const struct sl_pp_context *context,
+ unsigned int *file,
+ unsigned int *line);
+
int
sl_pp_context_add_extension(struct sl_pp_context *context,
const char *name,
@@ -65,13 +71,14 @@ sl_pp_context_cstr(const struct sl_pp_context *context,
int
sl_pp_version(struct sl_pp_context *context,
- const struct sl_pp_token_info *input,
- unsigned int *version,
- unsigned int *tokens_eaten);
+ unsigned int *version);
+
+int
+sl_pp_process_get(struct sl_pp_context *context,
+ struct sl_pp_token_info *output);
int
sl_pp_process(struct sl_pp_context *context,
- const struct sl_pp_token_info *input,
struct sl_pp_token_info **output);
#endif /* SL_PP_PUBLIC_H */
diff --git a/src/glsl/pp/sl_pp_token.c b/src/glsl/pp/sl_pp_token.c
index e9a60b6c50..a708978700 100644
--- a/src/glsl/pp/sl_pp_token.c
+++ b/src/glsl/pp/sl_pp_token.c
@@ -39,13 +39,12 @@ static int
_pure_getc(struct sl_pp_context *context)
{
char c;
- unsigned int current_line;
if (context->getc_buf_size) {
return context->getc_buf[--context->getc_buf_size];
}
- if (sl_pp_purify_getc(&context->pure, &c, &current_line, context->error_msg, sizeof(context->error_msg)) == 0) {
+ if (sl_pp_purify_getc(&context->pure, &c, &context->error_line, context->error_msg, sizeof(context->error_msg)) == 0) {
return PURE_ERROR;
}
return c;
@@ -508,7 +507,7 @@ _tokenise_number(struct sl_pp_context *context,
}
-static int
+int
sl_pp_token_get(struct sl_pp_context *context,
struct sl_pp_token_info *out)
{
@@ -810,20 +809,16 @@ sl_pp_token_get(struct sl_pp_context *context,
int
sl_pp_tokenise(struct sl_pp_context *context,
- const char *input,
- const struct sl_pp_purify_options *options,
struct sl_pp_token_info **output)
{
struct sl_pp_token_info *out = NULL;
unsigned int out_len = 0;
unsigned int out_max = 0;
- sl_pp_purify_state_init(&context->pure, input, options);
-
for (;;) {
struct sl_pp_token_info info;
- if (sl_pp_token_get(context, &info)) {
+ if (sl_pp_token_buffer_get(&context->tokens, &info)) {
free(out);
return -1;
}
diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h
index ba9834a9f2..a12b193401 100644
--- a/src/glsl/pp/sl_pp_token.h
+++ b/src/glsl/pp/sl_pp_token.h
@@ -123,9 +123,11 @@ struct sl_pp_token_info {
struct sl_pp_purify_options;
int
+sl_pp_token_get(struct sl_pp_context *context,
+ struct sl_pp_token_info *out);
+
+int
sl_pp_tokenise(struct sl_pp_context *context,
- const char *input,
- const struct sl_pp_purify_options *options,
struct sl_pp_token_info **output);
#endif /* SL_PP_TOKEN_H */
diff --git a/src/glsl/pp/sl_pp_token_util.c b/src/glsl/pp/sl_pp_token_util.c
new file mode 100644
index 0000000000..c85263d9a1
--- /dev/null
+++ b/src/glsl/pp/sl_pp_token_util.c
@@ -0,0 +1,182 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include <assert.h>
+#include <stdlib.h>
+#include "sl_pp_token_util.h"
+
+
+int
+sl_pp_token_buffer_init(struct sl_pp_token_buffer *buffer,
+ struct sl_pp_context *context)
+{
+ buffer->context = context;
+ buffer->size = 0;
+ buffer->capacity = 64;
+ buffer->tokens = malloc(buffer->capacity * sizeof(struct sl_pp_token_info));
+ if (!buffer->tokens) {
+ return -1;
+ }
+ return 0;
+}
+
+void
+sl_pp_token_buffer_destroy(struct sl_pp_token_buffer *buffer)
+{
+ free(buffer->tokens);
+}
+
+int
+sl_pp_token_buffer_get(struct sl_pp_token_buffer *buffer,
+ struct sl_pp_token_info *out)
+{
+ /* Pop from stack first if not empty. */
+ if (buffer->size) {
+ *out = buffer->tokens[--buffer->size];
+ return 0;
+ }
+
+ assert(buffer->context);
+ return sl_pp_token_get(buffer->context, out);
+}
+
+void
+sl_pp_token_buffer_unget(struct sl_pp_token_buffer *buffer,
+ const struct sl_pp_token_info *in)
+{
+ /* Resize if needed. */
+ if (buffer->size == buffer->capacity) {
+ buffer->capacity += 64;
+ buffer->tokens = realloc(buffer->tokens,
+ buffer->capacity * sizeof(struct sl_pp_token_info));
+ assert(buffer->tokens);
+ }
+
+ /* Push token on stack. */
+ buffer->tokens[buffer->size++] = *in;
+}
+
+int
+sl_pp_token_buffer_skip_white(struct sl_pp_token_buffer *buffer,
+ struct sl_pp_token_info *out)
+{
+ if (sl_pp_token_buffer_get(buffer, out)) {
+ return -1;
+ }
+
+ while (out->token == SL_PP_WHITESPACE) {
+ if (sl_pp_token_buffer_get(buffer, out)) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+
+int
+sl_pp_token_peek_init(struct sl_pp_token_peek *peek,
+ struct sl_pp_token_buffer *buffer)
+{
+ peek->buffer = buffer;
+ peek->size = 0;
+ peek->capacity = 64;
+ peek->tokens = malloc(peek->capacity * sizeof(struct sl_pp_token_info));
+ if (!peek->tokens) {
+ return -1;
+ }
+ return 0;
+}
+
+void
+sl_pp_token_peek_destroy(struct sl_pp_token_peek *peek)
+{
+ /* Abort. */
+ while (peek->size) {
+ sl_pp_token_buffer_unget(peek->buffer, &peek->tokens[--peek->size]);
+ }
+ free(peek->tokens);
+}
+
+int
+sl_pp_token_peek_get(struct sl_pp_token_peek *peek,
+ struct sl_pp_token_info *out)
+{
+ /* Get token from buffer. */
+ if (sl_pp_token_buffer_get(peek->buffer, out)) {
+ return -1;
+ }
+
+ /* Save it. */
+ if (peek->size == peek->capacity) {
+ peek->capacity += 64;
+ peek->tokens = realloc(peek->tokens,
+ peek->capacity * sizeof(struct sl_pp_token_info));
+ assert(peek->tokens);
+ }
+ peek->tokens[peek->size++] = *out;
+ return 0;
+}
+
+void
+sl_pp_token_peek_commit(struct sl_pp_token_peek *peek)
+{
+ peek->size = 0;
+}
+
+int
+sl_pp_token_peek_to_buffer(const struct sl_pp_token_peek *peek,
+ struct sl_pp_token_buffer *buffer)
+{
+ unsigned int i;
+
+ if (sl_pp_token_buffer_init(buffer, NULL)) {
+ return -1;
+ }
+ for (i = peek->size; i > 0; i--) {
+ sl_pp_token_buffer_unget(buffer, &peek->tokens[i - 1]);
+ }
+ return 0;
+}
+
+int
+sl_pp_token_peek_skip_white(struct sl_pp_token_peek *peek,
+ struct sl_pp_token_info *out)
+{
+ if (sl_pp_token_peek_get(peek, out)) {
+ return -1;
+ }
+
+ while (out->token == SL_PP_WHITESPACE) {
+ if (sl_pp_token_peek_get(peek, out)) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/glsl/pp/sl_pp_token_util.h b/src/glsl/pp/sl_pp_token_util.h
new file mode 100644
index 0000000000..2a668ad0a8
--- /dev/null
+++ b/src/glsl/pp/sl_pp_token_util.h
@@ -0,0 +1,103 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef SL_PP_TOKEN_UTIL_H
+#define SL_PP_TOKEN_UTIL_H
+
+#include <assert.h>
+#include <stdlib.h>
+#include "sl_pp_token.h"
+
+
+struct sl_pp_context;
+
+/*
+ * A token buffer allows one to get and unget a token
+ * from a preprocessor context.
+ */
+struct sl_pp_token_buffer {
+ struct sl_pp_context *context;
+ unsigned int size;
+ unsigned int capacity;
+ struct sl_pp_token_info *tokens;
+};
+
+int
+sl_pp_token_buffer_init(struct sl_pp_token_buffer *buffer,
+ struct sl_pp_context *context);
+
+void
+sl_pp_token_buffer_destroy(struct sl_pp_token_buffer *buffer);
+
+int
+sl_pp_token_buffer_get(struct sl_pp_token_buffer *buffer,
+ struct sl_pp_token_info *out);
+
+void
+sl_pp_token_buffer_unget(struct sl_pp_token_buffer *buffer,
+ const struct sl_pp_token_info *in);
+
+int
+sl_pp_token_buffer_skip_white(struct sl_pp_token_buffer *buffer,
+ struct sl_pp_token_info *out);
+
+
+/*
+ * A token peek allows one to get a number of tokens from a buffer
+ * and then either commit the operation or abort it,
+ * effectively ungetting the peeked tokens.
+ */
+struct sl_pp_token_peek {
+ struct sl_pp_token_buffer *buffer;
+ unsigned int size;
+ unsigned int capacity;
+ struct sl_pp_token_info *tokens;
+};
+
+int
+sl_pp_token_peek_init(struct sl_pp_token_peek *peek,
+ struct sl_pp_token_buffer *buffer);
+
+void
+sl_pp_token_peek_destroy(struct sl_pp_token_peek *peek);
+
+int
+sl_pp_token_peek_get(struct sl_pp_token_peek *peek,
+ struct sl_pp_token_info *out);
+
+void
+sl_pp_token_peek_commit(struct sl_pp_token_peek *peek);
+
+int
+sl_pp_token_peek_to_buffer(const struct sl_pp_token_peek *peek,
+ struct sl_pp_token_buffer *buffer);
+
+int
+sl_pp_token_peek_skip_white(struct sl_pp_token_peek *peek,
+ struct sl_pp_token_info *out);
+
+#endif /* SL_PP_TOKEN_UTIL_H */
diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c
index db06523749..3c995b7750 100644
--- a/src/glsl/pp/sl_pp_version.c
+++ b/src/glsl/pp/sl_pp_version.c
@@ -33,21 +33,23 @@
int
sl_pp_version(struct sl_pp_context *context,
- const struct sl_pp_token_info *input,
- unsigned int *version,
- unsigned int *tokens_eaten)
+ unsigned int *version)
{
- unsigned int i = 0;
+ struct sl_pp_token_peek peek;
unsigned int line = context->line;
/* Default values if `#version' is not present. */
*version = 110;
- *tokens_eaten = 0;
+
+ if (sl_pp_token_peek_init(&peek, &context->tokens)) {
+ return -1;
+ }
/* There can be multiple `#version' directives present.
* Accept the value of the last one.
*/
for (;;) {
+ struct sl_pp_token_info input;
int found_hash = 0;
int found_version = 0;
int found_number = 0;
@@ -55,82 +57,101 @@ sl_pp_version(struct sl_pp_context *context,
/* Skip whitespace and newlines and seek for hash. */
while (!found_hash) {
- 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:
line++;
- /* pass thru */
+ break;
+
case SL_PP_WHITESPACE:
- i++;
break;
case SL_PP_HASH:
- i++;
found_hash = 1;
break;
default:
+ sl_pp_token_peek_destroy(&peek);
return 0;
}
}
/* Skip whitespace and seek for `version'. */
while (!found_version) {
- 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_WHITESPACE:
- i++;
break;
case SL_PP_IDENTIFIER:
- if (input[i].data.identifier != context->dict.version) {
+ if (input.data.identifier != context->dict.version) {
+ sl_pp_token_peek_destroy(&peek);
return 0;
}
- i++;
found_version = 1;
break;
default:
+ sl_pp_token_peek_destroy(&peek);
return 0;
}
}
+ sl_pp_token_peek_commit(&peek);
+
/* Skip whitespace and seek for version number. */
while (!found_number) {
- switch (input[i].token) {
+ if (sl_pp_token_buffer_get(&context->tokens, &input)) {
+ sl_pp_token_peek_destroy(&peek);
+ return -1;
+ }
+
+ switch (input.token) {
case SL_PP_WHITESPACE:
- i++;
break;
case SL_PP_UINT:
- *version = atoi(sl_pp_context_cstr(context, input[i].data._uint));
- i++;
+ *version = atoi(sl_pp_context_cstr(context, input.data._uint));
found_number = 1;
break;
default:
strcpy(context->error_msg, "expected version number after `#version'");
+ sl_pp_token_peek_destroy(&peek);
return -1;
}
}
/* Skip whitespace and seek for either newline or eof. */
while (!found_end) {
- switch (input[i].token) {
+ if (sl_pp_token_buffer_get(&context->tokens, &input)) {
+ sl_pp_token_peek_destroy(&peek);
+ return -1;
+ }
+
+ switch (input.token) {
case SL_PP_WHITESPACE:
- i++;
break;
case SL_PP_NEWLINE:
line++;
/* pass thru */
case SL_PP_EOF:
- i++;
- *tokens_eaten = i;
context->line = line;
found_end = 1;
break;
default:
strcpy(context->error_msg, "expected end of line after version number");
+ sl_pp_token_peek_destroy(&peek);
return -1;
}
}