macro_expand (const struct macro_tokens *,
int nesting_countdown, const struct macro_set *,
const struct macro_expander *, struct string_map *vars,
- bool *expand, struct macro_tokens *exp);
+ bool *expand, bool *break_, struct macro_tokens *exp);
static bool
expand_macro_function (struct parse_macro_function_ctx *ctx,
SEG_MODE_INTERACTIVE /* XXX */);
struct macro_tokens exp = { .n = 0 };
macro_expand (&mts, ctx->nesting_countdown - 1, ctx->macros, ctx->me,
- ctx->vars, ctx->expand, &exp);
+ ctx->vars, ctx->expand, NULL, &exp);
macro_tokens_to_representation (&exp, output);
macro_tokens_uninit (&exp);
macro_tokens_uninit (&mts);
macro_expand_if (const struct macro_token *tokens, size_t n_tokens,
int nesting_countdown, const struct macro_set *macros,
const struct macro_expander *me, struct string_map *vars,
- bool *expand, struct macro_tokens *exp)
+ bool *expand, bool *break_, struct macro_tokens *exp)
{
const struct macro_token *p = tokens;
const struct macro_token *end = tokens + n_tokens;
.mts = CONST_CAST (struct macro_token *, start),
.n = n,
};
- macro_expand (&mts, nesting_countdown, macros, me, vars, expand, exp);
+ macro_expand (&mts, nesting_countdown, macros, me, vars, expand,
+ break_, exp);
}
return (end_if + 1) - tokens;
}
{
string_map_replace_nocopy (vars, ss_xstrdup (var_name),
ss_xstrdup (items.mts[i].representation));
+
+ bool break_ = false;
macro_expand (&inner, nesting_countdown, macros,
- me, vars, expand, exp);
+ me, vars, expand, &break_, exp);
+ if (break_)
+ break;
}
return do_end - tokens + 1;
}
c_dtoastr (index_s, sizeof index_s, 0, 0, index);
string_map_replace_nocopy (vars, ss_xstrdup (var_name),
xstrdup (index_s));
+
+ bool break_ = false;
macro_expand (&inner, nesting_countdown, macros,
- me, vars, expand, exp);
+ me, vars, expand, &break_, exp);
+ if (break_)
+ break;
}
return do_end - tokens + 1;
macro_expand (const struct macro_tokens *mts,
int nesting_countdown, const struct macro_set *macros,
const struct macro_expander *me, struct string_map *vars,
- bool *expand, struct macro_tokens *exp)
+ bool *expand, bool *break_, struct macro_tokens *exp)
{
if (nesting_countdown <= 0)
{
struct string_map own_vars = STRING_MAP_INITIALIZER (own_vars);
if (!vars)
vars = &own_vars;
- for (size_t i = 0; i < mts->n; i++)
+
+ for (size_t i = 0; i < mts->n && (!break_ || !*break_); i++)
{
const struct macro_token *mt = &mts->mts[i];
const struct token *token = &mt->token;
//macro_tokens_print (arg, stdout);
if (*expand && param->expand_arg)
macro_expand (arg, nesting_countdown, macros, NULL, NULL,
- expand, exp);
+ expand, break_, exp);
else
for (size_t i = 0; i < arg->n; i++)
macro_tokens_add (exp, &arg->mts[i]);
const struct macro_tokens *arg = me->args[j];
if (*expand && param->expand_arg)
macro_expand (arg, nesting_countdown, macros, NULL, NULL,
- expand, exp);
+ expand, break_, exp);
else
for (size_t k = 0; k < arg->n; k++)
macro_tokens_add (exp, &arg->mts[k]);
size_t n = macro_expand_if (&mts->mts[i], mts->n - i,
nesting_countdown, macros, me, vars,
- expand, exp);
+ expand, break_, exp);
if (n > 0)
{
i += n - 1;
{
i += retval - 1;
macro_expand (&subme->macro->body, nesting_countdown - 1, macros,
- subme, NULL, expand, exp);
+ subme, NULL, expand, break_, exp);
macro_expander_destroy (subme);
continue;
}
continue;
}
+ if (ss_equals_case (token->string, ss_cstr ("!break")))
+ {
+ if (!break_)
+ printf ("!BREAK outside !DO\n");
+ else
+ {
+ *break_ = true;
+ break;
+ }
+ }
+
struct parse_macro_function_ctx ctx = {
.input = &mts->mts[i],
.n_input = mts->n - i,
bool expand = true;
macro_expand (&me->macro->body, settings_get_mnest (),
- me->macros, me, NULL, &expand, exp);
+ me->macros, me, NULL, &expand, NULL, exp);
#if 0
printf ("expansion:\n");