Skip to content

Commit

Permalink
Merge pull request katef#500 from katef/sv/re-is-anchored
Browse files Browse the repository at this point in the history
Add re_is_anchored interface.
  • Loading branch information
katef authored Oct 12, 2024
2 parents c375229 + 92e6e82 commit 09a917a
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
16 changes: 16 additions & 0 deletions include/re/re.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,22 @@ re_comp(enum re_dialect dialect,
const struct fsm_alloc *alloc,
enum re_flags flags, struct re_err *err);

/* Parse and analyze the regex enough to determine whether it is
* anchored at the start and/or end.
*
* As long as the result is checked for RE_IS_ANCHORED_ERROR first,
* the result can be used like a bitset. */
enum re_is_anchored_res {
RE_IS_ANCHORED_NONE = 0x00,
RE_IS_ANCHORED_START = 0x01,
RE_IS_ANCHORED_END = 0x02,
RE_IS_ANCHORED_BOTH = 0x03,
RE_IS_ANCHORED_ERROR = 0xFFFF,
};
enum re_is_anchored_res
re_is_anchored(enum re_dialect dialect, re_getchar_fun *f, void *opaque,
enum re_flags flags, struct re_err *err);

/*
* Return a human-readable string describing a given error code. The string
* returned has static storage, and must not be freed.
Expand Down
1 change: 1 addition & 0 deletions src/libre/libre.syms
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ re_is_literal
re_flags
re_strerror
re_perror
re_is_anchored

ast_print
ast_print_dot
Expand Down
37 changes: 37 additions & 0 deletions src/libre/re.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,3 +335,40 @@ re_is_literal(enum re_dialect dialect, int (*getc)(void *opaque), void *opaque,
return -1;
}

enum re_is_anchored_res
re_is_anchored(enum re_dialect dialect, re_getchar_fun *getc, void *opaque,
enum re_flags flags, struct re_err *err)
{
/* FIXME: copy/pasted from above, factor out common code later. */

struct ast *ast;
const struct dialect *m;
int unsatisfiable;

assert(getc != NULL);

m = re_dialect(dialect);
if (m == NULL) {
if (err != NULL) { err->e = RE_EBADDIALECT; }
return RE_IS_ANCHORED_ERROR;
}

flags |= m->flags;

ast = re_parse(dialect, getc, opaque, flags, err, &unsatisfiable);
if (ast == NULL) {
return RE_IS_ANCHORED_ERROR;
}

/* Copy anchoring flags, ending up with NONE, START, END, or BOTH. */
enum re_is_anchored_res res = RE_IS_ANCHORED_NONE;
if (ast->expr->flags & AST_FLAG_ANCHORED_START) {
res |= RE_IS_ANCHORED_START;
}
if (ast->expr->flags & AST_FLAG_ANCHORED_END) {
res |= RE_IS_ANCHORED_END;
}

ast_free(ast);
return res;
}

0 comments on commit 09a917a

Please sign in to comment.