From: Ben Pfaff Date: Sun, 4 Jul 2021 23:14:46 +0000 (-0700) Subject: Get rid of struct parse_macro_function_ctx. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f769f65caa62be6aac33c0ca60983461980de73f;p=pspp Get rid of struct parse_macro_function_ctx. --- diff --git a/src/language/lexer/macro.c b/src/language/lexer/macro.c index c35144dc3a..0d74bae00c 100644 --- a/src/language/lexer/macro.c +++ b/src/language/lexer/macro.c @@ -866,15 +866,20 @@ macro_call_add (struct macro_call *mc, const struct macro_token *mt) struct macro_expander { - const struct macro_set *macros; + /* Always available. */ + const struct macro_set *macros; /* Macros to expand recursively. */ + enum segmenter_mode segmenter_mode; /* Mode for tokenization. */ + int nesting_countdown; /* Remaining nesting levels. */ + const struct macro_expansion_stack *stack; /* Stack for error reporting. */ + bool *expand; /* May macro calls be expanded? */ + struct stringi_map *vars; /* Variables from !DO and !LET. */ + + /* Only nonnull if inside a !DO loop. */ + bool *break_; /* Set to true to break out of loop. */ + + /* Only nonnull if expanding a macro (and not, say, a macro argument). */ const struct macro *macro; struct macro_tokens **args; - enum segmenter_mode segmenter_mode; - struct stringi_map *vars; - bool *expand; - bool *break_; - int nesting_countdown; - const struct macro_expansion_stack *stack; }; /* Each argument to a macro function is one of: @@ -891,19 +896,14 @@ struct macro_expander sequence of tokens. The case where that character sequence is a single quoted string is an important special case. */ -struct parse_macro_function_ctx - { - const struct macro_token *input; - size_t n_input; - const struct macro_expander *me; - }; static void macro_expand (const struct macro_tokens *, const struct macro_expander *, struct macro_tokens *); static bool -expand_macro_function (struct parse_macro_function_ctx *ctx, +expand_macro_function (const struct macro_expander *me, + const struct macro_token *input, size_t n_input, struct string *output, size_t *input_consumed); /* Returns true if the pair of tokens starting at offset OFS within MTS are !*, @@ -918,19 +918,19 @@ is_bang_star (const struct macro_token *mts, size_t n, size_t ofs) } static size_t -parse_function_arg (struct parse_macro_function_ctx *ctx, +parse_function_arg (const struct macro_expander *me, + const struct macro_token *input, size_t n_input, size_t i, struct string *farg) { - const struct macro_token *tokens = ctx->input; - const struct token *token = &tokens[i].token; - if (token->type == T_MACRO_ID && ctx->me->macro) + const struct token *token = &input[i].token; + if (token->type == T_MACRO_ID && me->macro) { const struct macro_param *param = macro_find_parameter_by_name ( - ctx->me->macro, token->string); + me->macro, token->string); if (param) { - size_t param_idx = param - ctx->me->macro->params; - const struct macro_tokens *marg = ctx->me->args[param_idx]; + size_t param_idx = param - me->macro->params; + const struct macro_tokens *marg = me->args[param_idx]; for (size_t i = 0; i < marg->n; i++) { if (i) @@ -940,14 +940,14 @@ parse_function_arg (struct parse_macro_function_ctx *ctx, return 1; } - if (is_bang_star (ctx->input, ctx->n_input, i)) + if (is_bang_star (input, n_input, i)) { - for (size_t i = 0; i < ctx->me->macro->n_params; i++) + for (size_t i = 0; i < me->macro->n_params; i++) { - if (!ctx->me->macro->params[i].positional) + if (!me->macro->params[i].positional) break; - const struct macro_tokens *marg = ctx->me->args[i]; + const struct macro_tokens *marg = me->args[i]; for (size_t j = 0; j < marg->n; j++) { if (i || j) @@ -958,7 +958,7 @@ parse_function_arg (struct parse_macro_function_ctx *ctx, return 2; } - const char *value = stringi_map_find__ (ctx->me->vars, + const char *value = stringi_map_find__ (me->vars, token->string.string, token->string.length); if (value) @@ -967,30 +967,24 @@ parse_function_arg (struct parse_macro_function_ctx *ctx, return 1; } - struct parse_macro_function_ctx subctx = { - .input = &ctx->input[i], - .n_input = ctx->n_input - i, - .me = ctx->me, - }; size_t subinput_consumed; - if (expand_macro_function (&subctx, farg, &subinput_consumed)) + if (expand_macro_function (me, &input[i], n_input - i, + farg, &subinput_consumed)) return subinput_consumed; } - ds_put_substring (farg, tokens[i].representation); + ds_put_substring (farg, input[i].representation); return 1; } static bool -parse_macro_function (struct parse_macro_function_ctx *ctx, +parse_macro_function (const struct macro_expander *me, + const struct macro_token *tokens, size_t n_tokens, struct string_array *args, struct substring function, int min_args, int max_args, size_t *input_consumed) { - const struct macro_token *tokens = ctx->input; - size_t n_tokens = ctx->n_input; - if (!n_tokens || tokens[0].token.type != T_MACRO_ID || !ss_equals_case (tokens[0].token.string, function)) /* XXX abbrevs allowed */ @@ -998,7 +992,7 @@ parse_macro_function (struct parse_macro_function_ctx *ctx, if (n_tokens < 2 || tokens[1].token.type != T_LPAREN) { - macro_error (ctx->me->stack, n_tokens > 1 ? &tokens[1] : NULL, + macro_error (me->stack, n_tokens > 1 ? &tokens[1] : NULL, _("`(' expected following %s."), function.string); return false; } @@ -1014,7 +1008,7 @@ parse_macro_function (struct parse_macro_function_ctx *ctx, *input_consumed = i + 1; if (args->n < min_args || args->n > max_args) { - macro_error (ctx->me->stack, &tokens[i], + macro_error (me->stack, &tokens[i], _("Wrong number of arguments to macro function %s."), function.string); goto error; @@ -1023,7 +1017,7 @@ parse_macro_function (struct parse_macro_function_ctx *ctx, } struct string s = DS_EMPTY_INITIALIZER; - i += parse_function_arg (ctx, i, &s); + i += parse_function_arg (me, tokens, n_tokens, i, &s); if (i >= n_tokens) { ds_destroy (&s); @@ -1035,7 +1029,7 @@ parse_macro_function (struct parse_macro_function_ctx *ctx, i++; else if (tokens[i].token.type != T_RPAREN) { - macro_error (ctx->me->stack, &tokens[i], + macro_error (me->stack, &tokens[i], _("`,' or `)' expected in call to macro function %s."), function.string); goto error; @@ -1043,7 +1037,7 @@ parse_macro_function (struct parse_macro_function_ctx *ctx, } unexpected_end: - macro_error (ctx->me->stack, NULL, _("Missing `)' in call to macro function %s."), + macro_error (me->stack, NULL, _("Missing `)' in call to macro function %s."), function.string); /* Fall through. */ error: @@ -1102,22 +1096,21 @@ parse_integer (const char *s, int *np) } static bool -expand_macro_function (struct parse_macro_function_ctx *ctx, - struct string *output, - size_t *input_consumed) +expand_macro_function (const struct macro_expander *me, + const struct macro_token *input, size_t n_input, + struct string *output, size_t *input_consumed) { struct string_array args; - - if (parse_macro_function (ctx, &args, ss_cstr ("!LENGTH"), 1, 1, + if (parse_macro_function (me, input, n_input, &args, ss_cstr ("!LENGTH"), 1, 1, input_consumed)) ds_put_format (output, "%zu", strlen (args.strings[0])); - else if (parse_macro_function (ctx, &args, ss_cstr ("!BLANKS"), 1, 1, + else if (parse_macro_function (me, input, n_input, &args, ss_cstr ("!BLANKS"), 1, 1, input_consumed)) { int n; if (!parse_integer (args.strings[0], &n)) { - macro_error (ctx->me->stack, NULL, + macro_error (me->stack, NULL, _("Argument to !BLANKS must be non-negative integer " "(not \"%s\")."), args.strings[0]); string_array_destroy (&args); @@ -1126,39 +1119,39 @@ expand_macro_function (struct parse_macro_function_ctx *ctx, ds_put_byte_multiple (output, ' ', n); } - else if (parse_macro_function (ctx, &args, ss_cstr ("!CONCAT"), 1, INT_MAX, + else if (parse_macro_function (me, input, n_input, &args, ss_cstr ("!CONCAT"), 1, INT_MAX, input_consumed)) { for (size_t i = 0; i < args.n; i++) - if (!unquote_string (args.strings[i], ctx->me->segmenter_mode, output)) + if (!unquote_string (args.strings[i], me->segmenter_mode, output)) ds_put_cstr (output, args.strings[i]); } - else if (parse_macro_function (ctx, &args, ss_cstr ("!HEAD"), 1, 1, + else if (parse_macro_function (me, input, n_input, &args, ss_cstr ("!HEAD"), 1, 1, input_consumed)) { struct string tmp; const char *s = unquote_string_in_place (args.strings[0], - ctx->me->segmenter_mode, &tmp); + me->segmenter_mode, &tmp); struct macro_tokens mts = { .n = 0 }; - macro_tokens_from_string__ (&mts, ss_cstr (s), ctx->me->segmenter_mode, - ctx->me->stack); + macro_tokens_from_string__ (&mts, ss_cstr (s), me->segmenter_mode, + me->stack); if (mts.n > 0) ds_put_substring (output, mts.mts[0].representation); macro_tokens_uninit (&mts); ds_destroy (&tmp); } - else if (parse_macro_function (ctx, &args, ss_cstr ("!INDEX"), 2, 2, + else if (parse_macro_function (me, input, n_input, &args, ss_cstr ("!INDEX"), 2, 2, input_consumed)) { const char *haystack = args.strings[0]; const char *needle = strstr (haystack, args.strings[1]); ds_put_format (output, "%zu", needle ? needle - haystack + 1 : 0); } - else if (parse_macro_function (ctx, &args, ss_cstr ("!QUOTE"), 1, 1, + else if (parse_macro_function (me, input, n_input, &args, ss_cstr ("!QUOTE"), 1, 1, input_consumed)) { - if (unquote_string (args.strings[0], ctx->me->segmenter_mode, NULL)) + if (unquote_string (args.strings[0], me->segmenter_mode, NULL)) ds_put_cstr (output, args.strings[0]); else { @@ -1173,13 +1166,13 @@ expand_macro_function (struct parse_macro_function_ctx *ctx, ds_put_byte (output, '\''); } } - else if (parse_macro_function (ctx, &args, ss_cstr ("!SUBSTR"), 2, 3, + else if (parse_macro_function (me, input, n_input, &args, ss_cstr ("!SUBSTR"), 2, 3, input_consumed)) { int start; if (!parse_integer (args.strings[1], &start) || start < 1) { - macro_error (ctx->me->stack, NULL, + macro_error (me->stack, NULL, _("Second argument of !SUBSTR must be " "positive integer (not \"%s\")."), args.strings[1]); @@ -1190,7 +1183,7 @@ expand_macro_function (struct parse_macro_function_ctx *ctx, int count = INT_MAX; if (args.n > 2 && (!parse_integer (args.strings[2], &count) || count < 0)) { - macro_error (ctx->me->stack, NULL, + macro_error (me->stack, NULL, _("Third argument of !SUBSTR must be " "non-negative integer (not \"%s\")."), args.strings[2]); @@ -1201,16 +1194,16 @@ expand_macro_function (struct parse_macro_function_ctx *ctx, struct substring s = ss_cstr (args.strings[0]); ds_put_substring (output, ss_substr (s, start - 1, count)); } - else if (parse_macro_function (ctx, &args, ss_cstr ("!TAIL"), 1, 1, + else if (parse_macro_function (me, input, n_input, &args, ss_cstr ("!TAIL"), 1, 1, input_consumed)) { struct string tmp; const char *s = unquote_string_in_place (args.strings[0], - ctx->me->segmenter_mode, &tmp); + me->segmenter_mode, &tmp); struct macro_tokens mts = { .n = 0 }; - macro_tokens_from_string__ (&mts, ss_cstr (s), ctx->me->segmenter_mode, - ctx->me->stack); + macro_tokens_from_string__ (&mts, ss_cstr (s), me->segmenter_mode, + me->stack); if (mts.n > 1) { struct macro_tokens tail = { .mts = mts.mts + 1, .n = mts.n - 1 }; @@ -1219,35 +1212,35 @@ expand_macro_function (struct parse_macro_function_ctx *ctx, macro_tokens_uninit (&mts); ds_destroy (&tmp); } - else if (parse_macro_function (ctx, &args, ss_cstr ("!UNQUOTE"), 1, 1, + else if (parse_macro_function (me, input, n_input, &args, ss_cstr ("!UNQUOTE"), 1, 1, input_consumed)) { - if (!unquote_string (args.strings[0], ctx->me->segmenter_mode, output)) + if (!unquote_string (args.strings[0], me->segmenter_mode, output)) ds_put_cstr (output, args.strings[0]); } - else if (parse_macro_function (ctx, &args, ss_cstr ("!UPCASE"), 1, 1, + else if (parse_macro_function (me, input, n_input, &args, ss_cstr ("!UPCASE"), 1, 1, input_consumed)) { struct string tmp; const char *s = unquote_string_in_place (args.strings[0], - ctx->me->segmenter_mode, &tmp); + me->segmenter_mode, &tmp); char *upper = utf8_to_upper (s); ds_put_cstr (output, upper); free (upper); ds_destroy (&tmp); } - else if (parse_macro_function (ctx, &args, ss_cstr ("!EVAL"), 1, 1, + else if (parse_macro_function (me, input, n_input, &args, ss_cstr ("!EVAL"), 1, 1, input_consumed)) { struct macro_tokens mts = { .n = 0 }; macro_tokens_from_string__ (&mts, ss_cstr (args.strings[0]), - ctx->me->segmenter_mode, ctx->me->stack); + me->segmenter_mode, me->stack); struct macro_tokens exp = { .n = 0 }; struct macro_expansion_stack stack = { .name = "!EVAL", - .next = ctx->me->stack + .next = me->stack }; - struct macro_expander subme = *ctx->me; + struct macro_expander subme = *me; subme.break_ = NULL; subme.stack = &stack; @@ -1256,9 +1249,9 @@ expand_macro_function (struct parse_macro_function_ctx *ctx, macro_tokens_uninit (&exp); macro_tokens_uninit (&mts); } - else if (ctx->n_input > 0 - && ctx->input[0].token.type == T_MACRO_ID - && ss_equals_case (ctx->input[0].token.string, ss_cstr ("!NULL"))) + else if (n_input > 0 + && input[0].token.type == T_MACRO_ID + && ss_equals_case (input[0].token.string, ss_cstr ("!NULL"))) { *input_consumed = 1; return true; @@ -1306,13 +1299,9 @@ macro_evaluate_literal (const struct macro_expander *me, return NULL; } - struct parse_macro_function_ctx fctx = { - .input = p, - .n_input = end - p, - .me = me, - }; struct string function_output = DS_EMPTY_INITIALIZER; - size_t function_consumed = parse_function_arg (&fctx, 0, &function_output); + size_t function_consumed = parse_function_arg (me, p, end - p, + 0, &function_output); struct string unquoted = DS_EMPTY_INITIALIZER; if (unquote_string (ds_cstr (&function_output), me->segmenter_mode, &unquoted)) @@ -2048,14 +2037,10 @@ macro_expand (const struct macro_tokens *mts, } } - struct parse_macro_function_ctx ctx = { - .input = &mts->mts[i], - .n_input = mts->n - i, - .me = me, - }; struct string function_output = DS_EMPTY_INITIALIZER; size_t function_consumed; - if (expand_macro_function (&ctx, &function_output, &function_consumed)) + if (expand_macro_function (me, &mts->mts[i], mts->n - i, + &function_output, &function_consumed)) { i += function_consumed - 1;