X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Flexer%2Fmacro.c;h=e5805f035670b33e7b6f62aea55b58a623818ad4;hb=f42cd385428298f9ee9795a3296e32363a9b0baa;hp=270cae50fabf9c586898eebad17e9adbad0e015e;hpb=72d12e896c52ce226c43dce80f683204e46e4f05;p=pspp diff --git a/src/language/lexer/macro.c b/src/language/lexer/macro.c index 270cae50fa..e5805f0356 100644 --- a/src/language/lexer/macro.c +++ b/src/language/lexer/macro.c @@ -334,6 +334,8 @@ classify_token (enum token_type type) case T_RPAREN: case T_LBRACK: case T_RBRACK: + case T_LCURLY: + case T_RCURLY: return TC_PUNCT; case T_PLUS: @@ -341,6 +343,7 @@ classify_token (enum token_type type) case T_ASTERISK: case T_SLASH: case T_EQUALS: + case T_COLON: case T_AND: case T_OR: case T_NOT: @@ -359,6 +362,7 @@ classify_token (enum token_type type) return TC_BINOP; case T_COMMA: + case T_SEMICOLON: return TC_COMMA; } @@ -498,9 +502,6 @@ macro_set_add (struct macro_set *set, struct macro *m) enum mc_state { - /* Error state. */ - MC_ERROR, - /* Accumulating tokens in mc->params toward the end of any type of argument. */ MC_ARG, @@ -696,22 +697,22 @@ mc_expected (struct macro_call *mc, const struct macro_token *actual, mc->param->name, mc->macro->name); free (expected_s); - mc->state = MC_ERROR; - return -1; + return mc_finished (mc); } static int mc_enclose (struct macro_call *mc, const struct macro_token *mt, const struct msg_location *loc) { - mc->n_tokens++; - const struct token *token = &mt->token; const struct macro_param *p = mc->param; if (token_equal (&p->start, token)) { + mc->n_tokens++; + struct macro_tokens **argp = &mc->args[p - mc->macro->params]; - *argp = xzalloc (sizeof **argp); + if (!*argp) + *argp = xzalloc (sizeof **argp); mc->state = MC_ARG; return 0; } @@ -754,13 +755,9 @@ mc_keyword (struct macro_call *mc, const struct macro_token *mt, { struct macro_tokens **argp = &mc->args[p - mc->macro->params]; if (*argp) - { - mc_error (mc, loc, - _("Argument %s multiply specified in call to macro %s."), - p->name, mc->macro->name); - mc->state = MC_ERROR; - return -1; - } + mc_error (mc, loc, + _("Argument %s multiply specified in call to macro %s."), + p->name, mc->macro->name); *argp = xzalloc (sizeof **argp); mc->param = p; @@ -776,11 +773,9 @@ static int mc_equals (struct macro_call *mc, const struct macro_token *mt, const struct msg_location *loc) { - const struct token *token = &mt->token; - mc->n_tokens++; - - if (token->type == T_EQUALS) + if (mt->token.type == T_EQUALS) { + mc->n_tokens++; mc->state = mc->param->arg_type == ARG_ENCLOSE ? MC_ENCLOSE : MC_ARG; return 0; } @@ -879,9 +874,6 @@ macro_call_add (struct macro_call *mc, const struct macro_token *mt, { switch (mc->state) { - case MC_ERROR: - return -1; - case MC_ARG: return mc_add_arg (mc, mt, loc); @@ -999,12 +991,7 @@ parse_function_args (const struct macro_expander *me, const char *function, struct string_array *args) { - if (n < 2 || mts[1].token.type != T_LPAREN) - { - macro_error (me->stack, n > 1 ? &mts[1] : NULL, - _("`(' expected following %s."), function); - return 0; - } + assert (n >= 2 && mts[1].token.type == T_LPAREN); for (size_t i = 2; i < n; ) { @@ -1056,7 +1043,8 @@ unquote_string (const char *s, enum segmenter_mode segmenter_mode, return false; } - ds_put_substring (content, token1.string); + if (content) + ds_put_substring (content, token1.string); token_uninit (&token1); return true; } @@ -1103,7 +1091,6 @@ expand_macro_function (const struct macro_expander *me, MF_HEAD, MF_INDEX, MF_LENGTH, - MF_NULL, MF_QUOTE, MF_SUBSTR, MF_TAIL, @@ -1117,7 +1104,6 @@ expand_macro_function (const struct macro_expander *me, [MF_HEAD] = { "!HEAD", 1, 1 }, [MF_INDEX] = { "!INDEX", 2, 2 }, [MF_LENGTH] = { "!LENGTH", 1, 1 }, - [MF_NULL] = { "!NULL", 0, 0 }, [MF_QUOTE] = { "!QUOTE", 1, 1 }, [MF_SUBSTR] = { "!SUBSTR", 2, 3 }, [MF_TAIL] = { "!TAIL", 1, 1 }, @@ -1125,7 +1111,16 @@ expand_macro_function (const struct macro_expander *me, [MF_UPCASE] = { "!UPCASE", 1, 1 }, }; - /* Is this a macro function? */ + if (lex_id_match_n (ss_cstr ("!NULL"), input[0].token.string, 4)) + return 1; + + if (n_input < 2 || input[1].token.type != T_LPAREN) + { + /* Only consider macro functions when the name is followed by '('. */ + return 0; + } + + /* Is this a macro function name? */ const struct macro_function *mf; for (mf = mfs; ; mf++) { @@ -1140,13 +1135,14 @@ expand_macro_function (const struct macro_expander *me, } enum macro_function_id id = mf - mfs; - if (id == MF_NULL) - return 1; struct string_array args = STRING_ARRAY_INITIALIZER; size_t n_consumed = parse_function_args (me, input, n_input, mf->name, &args); if (!n_consumed) - return 0; + { + string_array_destroy (&args); + return 0; + } if (args.n < mf->min_args || args.n > mf->max_args) { @@ -1169,6 +1165,7 @@ expand_macro_function (const struct macro_expander *me, mf->name); else NOT_REACHED (); + string_array_destroy (&args); return 0; } @@ -1847,6 +1844,7 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens, macro_expand (p, do_end - p, &subme, exp); } + macro_tokens_uninit (&items); return do_end - tokens + 1; } else if (p < end && p->token.type == T_EQUALS)