Skip to content

Commit 09a917a

Browse files
authored
Merge pull request #500 from katef/sv/re-is-anchored
Add re_is_anchored interface.
2 parents c375229 + 92e6e82 commit 09a917a

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

include/re/re.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,22 @@ re_comp(enum re_dialect dialect,
136136
const struct fsm_alloc *alloc,
137137
enum re_flags flags, struct re_err *err);
138138

139+
/* Parse and analyze the regex enough to determine whether it is
140+
* anchored at the start and/or end.
141+
*
142+
* As long as the result is checked for RE_IS_ANCHORED_ERROR first,
143+
* the result can be used like a bitset. */
144+
enum re_is_anchored_res {
145+
RE_IS_ANCHORED_NONE = 0x00,
146+
RE_IS_ANCHORED_START = 0x01,
147+
RE_IS_ANCHORED_END = 0x02,
148+
RE_IS_ANCHORED_BOTH = 0x03,
149+
RE_IS_ANCHORED_ERROR = 0xFFFF,
150+
};
151+
enum re_is_anchored_res
152+
re_is_anchored(enum re_dialect dialect, re_getchar_fun *f, void *opaque,
153+
enum re_flags flags, struct re_err *err);
154+
139155
/*
140156
* Return a human-readable string describing a given error code. The string
141157
* returned has static storage, and must not be freed.

src/libre/libre.syms

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ re_is_literal
33
re_flags
44
re_strerror
55
re_perror
6+
re_is_anchored
67

78
ast_print
89
ast_print_dot

src/libre/re.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,3 +335,40 @@ re_is_literal(enum re_dialect dialect, int (*getc)(void *opaque), void *opaque,
335335
return -1;
336336
}
337337

338+
enum re_is_anchored_res
339+
re_is_anchored(enum re_dialect dialect, re_getchar_fun *getc, void *opaque,
340+
enum re_flags flags, struct re_err *err)
341+
{
342+
/* FIXME: copy/pasted from above, factor out common code later. */
343+
344+
struct ast *ast;
345+
const struct dialect *m;
346+
int unsatisfiable;
347+
348+
assert(getc != NULL);
349+
350+
m = re_dialect(dialect);
351+
if (m == NULL) {
352+
if (err != NULL) { err->e = RE_EBADDIALECT; }
353+
return RE_IS_ANCHORED_ERROR;
354+
}
355+
356+
flags |= m->flags;
357+
358+
ast = re_parse(dialect, getc, opaque, flags, err, &unsatisfiable);
359+
if (ast == NULL) {
360+
return RE_IS_ANCHORED_ERROR;
361+
}
362+
363+
/* Copy anchoring flags, ending up with NONE, START, END, or BOTH. */
364+
enum re_is_anchored_res res = RE_IS_ANCHORED_NONE;
365+
if (ast->expr->flags & AST_FLAG_ANCHORED_START) {
366+
res |= RE_IS_ANCHORED_START;
367+
}
368+
if (ast->expr->flags & AST_FLAG_ANCHORED_END) {
369+
res |= RE_IS_ANCHORED_END;
370+
}
371+
372+
ast_free(ast);
373+
return res;
374+
}

0 commit comments

Comments
 (0)