diff --git a/b2/SUBST b/b2/SUBST index 92d3253..3d7dc28 100644 --- a/b2/SUBST +++ b/b2/SUBST @@ -2,6 +2,16 @@ FN=DNP { ignore } FN=X(*) { $=$1 } +/* iteration demo */ +FOO=abcde +BAR=x /* BAR= wouldn't be syntactically correct. We need a non-empty value */ +FOO=(*)(?) { + BAR=$BAR$2 + FOO=$1 + again FOO +} +BAR=x(*) { $=$1 } /* remove the "x" */ + REF=R[0-9]* { T=R VAL=(#R) { R=$1 } diff --git a/b2/subex.c b/b2/subex.c index 76971db..bb4005f 100644 --- a/b2/subex.c +++ b/b2/subex.c @@ -183,7 +183,8 @@ static int do_match(const char **var, const regex_t *re, static const struct subst *recurse_sub(const struct subst *sub, const struct param *in, const char *matched_var, const char *matched_val, - const regmatch_t *match, const char *units, struct param **out) + const regmatch_t *match, const char *units, struct param **out, + enum subst_type *cause) { const struct subst *jump; regmatch_t m_tmp[NMATCH]; @@ -200,9 +201,13 @@ static const struct subst *recurse_sub(const struct subst *sub, in, *out, &val, m_tmp)) break; jump = recurse_sub(sub->u.match.block, in, - var, val, m_tmp, sub->u.match.units, out); - if (jump && jump != sub) - return jump; + var, val, m_tmp, sub->u.match.units, out, cause); + if (jump) { + if (jump != sub) + return jump; + if (*cause == st_again) + continue; + } break; case st_assign: tmp = compose(sub->u.assign.pat, in, *out, matched_val, @@ -217,11 +222,9 @@ static const struct subst *recurse_sub(const struct subst *sub, case st_ignore: return &jump_ignore; case st_break: - sub = sub->u.jump->next; - continue; case st_again: - sub = sub->u.jump->u.match.block; - continue; + *cause = sub->type; + return sub->u.jump; default: abort(); } @@ -236,6 +239,7 @@ int substitute(const struct subst *sub, const struct param *in, { int i; char tmp[4]; + enum subst_type cause = 0; if (!fn) { fn = unique("FN"); @@ -245,6 +249,6 @@ int substitute(const struct subst *sub, const struct param *in, } } *out = NULL; - return recurse_sub(sub, in, NULL, NULL, NULL, NULL, out) + return recurse_sub(sub, in, NULL, NULL, NULL, NULL, out, &cause) != &jump_ignore; }