const struct macro_token *input, size_t n_input,
struct string *output);
-/* Returns true if the N tokens within MTS start with !*, false otherwise. */
-static bool
-is_bang_star (const struct macro_token *mts, size_t n)
-{
- return (n > 1
- && mts[0].token.type == T_MACRO_ID
- && ss_equals (mts[0].token.string, ss_cstr ("!"))
- && mts[1].token.type == T_ASTERISK);
-}
-
/* Parses one function argument from the N_INPUT tokens in INPUT
Each argument to a macro function is one of:
return 1;
}
- if (is_bang_star (input, n_input))
+ if (ss_equals (token->string, ss_cstr ("!*")))
{
for (size_t i = 0; i < me->macro->n_params; i++)
{
ds_put_byte (farg, ' ');
macro_tokens_to_syntax (me->args[i], farg, NULL, NULL);
}
- return 2;
+ return 1;
}
const char *var = stringi_map_find__ (me->vars,
macro_expand_arg (me, param - me->macro->params, exp);
return 1;
}
- else if (is_bang_star (mts, n))
+ else if (ss_equals (token->string, ss_cstr ("!*")))
{
for (size_t j = 0; j < me->macro->n_params; j++)
macro_expand_arg (me, j, exp);
- return 2;
+ return 1;
}
}
s, input, n, eof, type);
case '!':
- return segmenter_parse_id__ (s, input, n, eof, type);
+ if (n < 2)
+ {
+ if (!eof)
+ return -1;
+ *type = SEG_PUNCT;
+ return 1;
+ }
+ else if (input[1] == '*')
+ {
+ *type = SEG_MACRO_ID;
+ return 2;
+ }
+ else
+ return segmenter_parse_id__ (s, input, n, eof, type);
default:
if (lex_uc_is_space (uc))
AT_KEYWORDS([segment])
AT_DATA([input], [dnl
~ & | = >= > <= < ~= <> ( ) , - + * / [[ ]] **
-~&|=>=><=<~=<>(),-+*/[[]]**
-% : ; ? _ ` { } ~
+~&|=>=><=<~=<>(),-+*/[[]]**!*
+% : ; ? _ ` { } ~ !*
])
AT_DATA([expout-base], [dnl
punct ~ space
punct [[
punct ]]
punct **
+macro_id !*
newline \n (later)
punct % space
punct ` space
punct { space
punct } space
-punct ~
+punct ~ space
+macro_id !*
-newline \n (later)
-
end