diff options
author | Michal Krol <michal@vmware.com> | 2009-09-28 11:30:15 +0200 |
---|---|---|
committer | Michal Krol <michal@vmware.com> | 2009-09-28 11:30:15 +0200 |
commit | c4bd6ccde8241d6a5eb631c713ba79db51163701 (patch) | |
tree | 54ecc15e35267463fbd7f4f4ec274c4701fabe32 /src/glsl/pp | |
parent | 92e33569f39a2fa9061a0c35c233c1db33820033 (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.c | 102 |
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 a4e78861d6..d6c32a0e78 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; |