glsl: Allow for preprocessor macro redefinition.

This commit is contained in:
Michal Krol 2009-06-26 12:26:05 +02:00
parent 153b179862
commit a294715612
7 changed files with 65 additions and 29 deletions

View file

@ -33,6 +33,7 @@ void
sl_pp_context_init(struct sl_pp_context *context)
{
memset(context, 0, sizeof(struct sl_pp_context));
context->macro_tail = &context->macro;
context->if_ptr = SL_PP_MAX_IF_NESTING;
context->if_value = 1;
}

View file

@ -39,6 +39,7 @@ struct sl_pp_context {
unsigned int cstr_pool_len;
struct sl_pp_macro *macro;
struct sl_pp_macro **macro_tail;
unsigned int if_stack[SL_PP_MAX_IF_NESTING];
unsigned int if_ptr;

View file

@ -105,22 +105,42 @@ int
sl_pp_process_define(struct sl_pp_context *context,
const struct sl_pp_token_info *input,
unsigned int first,
unsigned int last,
struct sl_pp_macro *macro)
unsigned int last)
{
int macro_name = -1;
struct sl_pp_macro *macro;
unsigned int i;
unsigned int body_len;
unsigned int j;
if (first < last && input[first].token == SL_PP_IDENTIFIER) {
macro->name = input[first].data.identifier;
macro_name = input[first].data.identifier;
first++;
}
if (macro->name == -1) {
if (macro_name == -1) {
return -1;
}
for (macro = context->macro; macro; macro = macro->next) {
if (macro->name == macro_name) {
break;
}
}
if (!macro) {
macro = sl_pp_macro_new();
if (!macro) {
return -1;
}
*context->macro_tail = macro;
context->macro_tail = &macro->next;
} else {
sl_pp_macro_reset(macro);
}
macro->name = macro_name;
/*
* If there is no whitespace between macro name and left paren, a macro
* formal argument list follows. This is the only place where the presence

View file

@ -30,6 +30,15 @@
#include "sl_pp_process.h"
static void
_macro_init(struct sl_pp_macro *macro)
{
macro->name = -1;
macro->num_args = -1;
macro->arg = NULL;
macro->body = NULL;
}
struct sl_pp_macro *
sl_pp_macro_new(void)
{
@ -37,33 +46,45 @@ sl_pp_macro_new(void)
macro = calloc(1, sizeof(struct sl_pp_macro));
if (macro) {
macro->name = -1;
macro->num_args = -1;
_macro_init(macro);
}
return macro;
}
static void
_macro_destroy(struct sl_pp_macro *macro)
{
struct sl_pp_macro_formal_arg *arg = macro->arg;
while (arg) {
struct sl_pp_macro_formal_arg *next_arg = arg->next;
free(arg);
arg = next_arg;
}
free(macro->body);
}
void
sl_pp_macro_free(struct sl_pp_macro *macro)
{
while (macro) {
struct sl_pp_macro *next_macro = macro->next;
struct sl_pp_macro_formal_arg *arg = macro->arg;
while (arg) {
struct sl_pp_macro_formal_arg *next_arg = arg->next;
free(arg);
arg = next_arg;
}
free(macro->body);
_macro_destroy(macro);
free(macro);
macro = next_macro;
}
}
void
sl_pp_macro_reset(struct sl_pp_macro *macro)
{
_macro_destroy(macro);
_macro_init(macro);
}
static void
skip_whitespace(const struct sl_pp_token_info *input,
unsigned int *pi)

View file

@ -50,6 +50,9 @@ sl_pp_macro_new(void);
void
sl_pp_macro_free(struct sl_pp_macro *macro);
void
sl_pp_macro_reset(struct sl_pp_macro *macro);
int
sl_pp_macro_expand(struct sl_pp_context *context,
const struct sl_pp_token_info *input,

View file

@ -71,10 +71,8 @@ sl_pp_process(struct sl_pp_context *context,
{
unsigned int i = 0;
int found_eof = 0;
struct sl_pp_macro **macro;
struct sl_pp_process_state state;
macro = &context->macro;
memset(&state, 0, sizeof(state));
while (!found_eof) {
@ -126,16 +124,9 @@ sl_pp_process(struct sl_pp_context *context,
if (!strcmp(name, "define")) {
if (context->if_value) {
*macro = sl_pp_macro_new();
if (!*macro) {
if (sl_pp_process_define(context, input, first, last)) {
return -1;
}
if (sl_pp_process_define(context, input, first, last, *macro)) {
return -1;
}
macro = &(**macro).next;
}
} else if (!strcmp(name, "if")) {
if (sl_pp_process_if(context, input, first, last)) {

View file

@ -48,8 +48,7 @@ int
sl_pp_process_define(struct sl_pp_context *context,
const struct sl_pp_token_info *input,
unsigned int first,
unsigned int last,
struct sl_pp_macro *macro);
unsigned int last);
int
sl_pp_process_if(struct sl_pp_context *context,