- struct string_array args;
- 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 (me, input, n_input, &args, ss_cstr ("!BLANKS"), 1, 1,
- input_consumed))
- {
- int n;
- if (!parse_integer (args.strings[0], &n))
+ if (!n_input || input[0].token.type != T_MACRO_ID)
+ return false;
+
+ struct macro_function
+ {
+ const char *name;
+ int min_args;
+ int max_args;
+ };
+ enum macro_function_id
+ {
+ MF_BLANKS,
+ MF_CONCAT,
+ MF_EVAL,
+ MF_HEAD,
+ MF_INDEX,
+ MF_LENGTH,
+ MF_NULL,
+ MF_QUOTE,
+ MF_SUBSTR,
+ MF_TAIL,
+ MF_UNQUOTE,
+ MF_UPCASE,
+ };
+ static const struct macro_function mfs[] = {
+ [MF_BLANKS] = { "!BLANKS", 1, 1 },
+ [MF_CONCAT] = { "!CONCAT", 1, INT_MAX },
+ [MF_EVAL] = { "!EVAL", 1, 1 },
+ [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 },
+ [MF_UNQUOTE] = { "!UNQUOTE", 1, 1 },
+ [MF_UPCASE] = { "!UPCASE", 1, 1 },
+ };
+
+ /* Is this a macro function? */
+ const struct macro_function *mf;
+ for (mf = mfs; ; mf++)
+ {
+ if (mf >= mfs + sizeof mfs / sizeof *mfs)