summaryrefslogtreecommitdiff
path: root/src/regex
diff options
context:
space:
mode:
authorSzabolcs Nagy <nsz@port70.net>2015-04-18 17:25:31 +0000
committerRich Felker <dalias@aerifal.cx>2016-01-30 20:53:29 -0500
commit03498ec22a4804ddbd8203d9ac94b6f7b6574b3c (patch)
treed6bba57747d8bf195754f3ee3a56a5834ee2978e /src/regex
parentda4cc13b9705e7d3a02216959b9711b3b30828c1 (diff)
downloadmusl-03498ec22a4804ddbd8203d9ac94b6f7b6574b3c.tar.gz
musl-03498ec22a4804ddbd8203d9ac94b6f7b6574b3c.tar.bz2
musl-03498ec22a4804ddbd8203d9ac94b6f7b6574b3c.tar.xz
musl-03498ec22a4804ddbd8203d9ac94b6f7b6574b3c.zip
regex: rewrite the repetition parsing code
The goto logic was hard to follow and modify. This is in preparation for the BRE \+ and \? support.
Diffstat (limited to 'src/regex')
-rw-r--r--src/regex/regcomp.c59
1 files changed, 29 insertions, 30 deletions
diff --git a/src/regex/regcomp.c b/src/regex/regcomp.c
index f1f06afe..ccd3755b 100644
--- a/src/regex/regcomp.c
+++ b/src/regex/regcomp.c
@@ -984,41 +984,40 @@ static reg_errcode_t tre_parse(tre_parse_ctx_t *ctx)
/* extension: repetitions are rejected after an empty node
eg. (+), |*, {2}, but assertions are not treated as empty
so ^* or $? are accepted currently. */
- switch (*s) {
- case '+':
- case '?':
- if (!ere)
+ for (;;) {
+ if (*s!='\\' && *s!='*') {
+ if (!ere)
+ break;
+ if (*s!='+' && *s!='?' && *s!='{')
+ break;
+ }
+ if (*s=='\\' && ere)
break;
- /* fallthrough */
- case '*':;
- int min=0, max=-1;
- if (*s == '+')
- min = 1;
- if (*s == '?')
- max = 1;
- s++;
- ctx->n = tre_ast_new_iter(ctx->mem, ctx->n, min, max, 0);
- if (!ctx->n)
- return REG_ESPACE;
+ if (*s=='\\' && s[1]!='{')
+ break;
+ if (*s=='\\')
+ s++;
+
/* extension: multiple consecutive *+?{,} is unspecified,
but (a+)+ has to be supported so accepting a++ makes
sense, note however that the RE_DUP_MAX limit can be
circumvented: (a{255}){255} uses a lot of memory.. */
- goto parse_iter;
- case '\\':
- if (ere || s[1] != '{')
- break;
- s++;
- goto parse_brace;
- case '{':
- if (!ere)
- break;
- parse_brace:
- err = parse_dup(ctx, s+1);
- if (err != REG_OK)
- return err;
- s = ctx->s;
- goto parse_iter;
+ if (*s=='{') {
+ err = parse_dup(ctx, s+1);
+ if (err != REG_OK)
+ return err;
+ s = ctx->s;
+ } else {
+ int min=0, max=-1;
+ if (*s == '+')
+ min = 1;
+ if (*s == '?')
+ max = 1;
+ s++;
+ ctx->n = tre_ast_new_iter(ctx->mem, ctx->n, min, max, 0);
+ if (!ctx->n)
+ return REG_ESPACE;
+ }
}
nbranch = tre_ast_new_catenation(ctx->mem, nbranch, ctx->n);