summaryrefslogtreecommitdiffstats
path: root/src/glsl/pp
diff options
context:
space:
mode:
authorMichal Krol <[email protected]>2009-09-28 11:30:15 +0200
committerMichal Krol <[email protected]>2009-09-28 11:30:15 +0200
commitc4bd6ccde8241d6a5eb631c713ba79db51163701 (patch)
tree54ecc15e35267463fbd7f4f4ec274c4701fabe32 /src/glsl/pp
parent92e33569f39a2fa9061a0c35c233c1db33820033 (diff)
glsl/pp: Expand macro actual arguments before pasting into its body.
Diffstat (limited to 'src/glsl/pp')
-rw-r--r--src/glsl/pp/sl_pp_macro.c102
1 files changed, 53 insertions, 49 deletions
diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c
index a4e78861d69..d6c32a0e782 100644
--- a/src/glsl/pp/sl_pp_macro.c
+++ b/src/glsl/pp/sl_pp_macro.c
@@ -136,6 +136,9 @@ sl_pp_macro_expand(struct sl_pp_context *context,
macro_name = input[*pi].data.identifier;
+ /* First look for predefined macros.
+ */
+
if (macro_name == context->dict.___LINE__) {
if (!mute && _out_number(context, state, context->line)) {
return -1;
@@ -207,55 +210,73 @@ sl_pp_macro_expand(struct sl_pp_context *context,
struct sl_pp_macro **pmacro = &actual_arg;
for (j = 0; j < (unsigned int)macro->num_args; j++) {
- unsigned int body_len;
+ struct sl_pp_process_state arg_state;
unsigned int i;
int done = 0;
unsigned int paren_nesting = 0;
- unsigned int k;
-
- *pmacro = sl_pp_macro_new();
- if (!*pmacro) {
- strcpy(context->error_msg, "out of memory");
- return -1;
- }
+ struct sl_pp_token_info eof;
- (**pmacro).name = formal_arg->name;
+ memset(&arg_state, 0, sizeof(arg_state));
- body_len = 1;
- for (i = *pi; !done; i++) {
+ for (i = *pi; !done;) {
switch (input[i].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;
}
} else {
- body_len++;
+ if (sl_pp_process_out(&arg_state, &input[i])) {
+ strcpy(context->error_msg, "out of memory");
+ free(arg_state.out);
+ return -1;
+ }
+ i++;
}
break;
case SL_PP_LPAREN:
paren_nesting++;
- body_len++;
+ if (sl_pp_process_out(&arg_state, &input[i])) {
+ strcpy(context->error_msg, "out of memory");
+ free(arg_state.out);
+ return -1;
+ }
+ 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;
}
} else {
paren_nesting--;
- body_len++;
+ if (sl_pp_process_out(&arg_state, &input[i])) {
+ strcpy(context->error_msg, "out of memory");
+ free(arg_state.out);
+ return -1;
+ }
+ i++;
+ }
+ break;
+
+ case SL_PP_IDENTIFIER:
+ if (sl_pp_macro_expand(context, input, &i, local, &arg_state, 0)) {
+ free(arg_state.out);
+ return -1;
}
break;
@@ -264,50 +285,33 @@ sl_pp_macro_expand(struct sl_pp_context *context,
return -1;
default:
- body_len++;
+ if (sl_pp_process_out(&arg_state, &input[i])) {
+ strcpy(context->error_msg, "out of memory");
+ free(arg_state.out);
+ return -1;
+ }
+ i++;
}
}
- (**pmacro).body = malloc(sizeof(struct sl_pp_token_info) * body_len);
- if (!(**pmacro).body) {
+ (*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;
}
- for (done = 0, k = 0, i = *pi; !done; i++) {
- switch (input[i].token) {
- case SL_PP_WHITESPACE:
- break;
-
- case SL_PP_COMMA:
- if (!paren_nesting && j < (unsigned int)macro->num_args - 1) {
- done = 1;
- } else {
- (**pmacro).body[k++] = input[i];
- }
- break;
-
- case SL_PP_LPAREN:
- paren_nesting++;
- (**pmacro).body[k++] = input[i];
- break;
-
- case SL_PP_RPAREN:
- if (!paren_nesting && j == (unsigned int)macro->num_args - 1) {
- done = 1;
- } else {
- paren_nesting--;
- (**pmacro).body[k++] = input[i];
- }
- break;
-
- default:
- (**pmacro).body[k++] = input[i];
- }
+ *pmacro = sl_pp_macro_new();
+ if (!*pmacro) {
+ strcpy(context->error_msg, "out of memory");
+ free(arg_state.out);
+ return -1;
}
- (**pmacro).body[k++].token = SL_PP_EOF;
- (*pi) = i;
+ (**pmacro).name = formal_arg->name;
+ (**pmacro).body = arg_state.out;
formal_arg = formal_arg->next;
pmacro = &(**pmacro).next;