aboutsummaryrefslogtreecommitdiff
path: root/vm.c
diff options
context:
space:
mode:
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/vm.c b/vm.c
index 7cfeda9..330f24f 100644
--- a/vm.c
+++ b/vm.c
@@ -16,6 +16,7 @@
//
// UTF8-compliant char iteration
//
+__attribute__((nonnull, pure))
static inline const char *next_char(file_t *f, const char *str)
{
char c = *str;
@@ -55,6 +56,7 @@ typedef struct recursive_ref_s {
// Attempt to match text against a previously captured value.
// Return the character position after the backref has matched, or NULL if no match has occurred.
//
+__attribute__((nonnull))
static const char *match_backref(const char *str, vm_op_t *op, match_t *cap, unsigned int flags)
{
check(op->type == VM_BACKREF, "Attempt to match backref against something that's not a backref");
@@ -100,7 +102,7 @@ static const char *match_backref(const char *str, vm_op_t *op, match_t *cap, uns
if (cap->end > prev) {
size_t len = (size_t)(cap->end - prev);
if ((flags & BP_IGNORECASE) ? memicmp(str, prev, len) != 0
- : memcmp(str, prev, len) != 0) {
+ : memcmp(str, prev, len) != 0) {
return NULL;
}
str += len;
@@ -115,6 +117,7 @@ static const char *match_backref(const char *str, vm_op_t *op, match_t *cap, uns
// a match struct, or NULL if no match is found.
// The returned value should be free()'d to avoid memory leaking.
//
+__attribute__((hot, nonnull(2,3,4)))
static match_t *_match(def_t *defs, file_t *f, const char *str, vm_op_t *op, unsigned int flags, recursive_ref_t *rec)
{
switch (op->type) {
@@ -474,6 +477,7 @@ static match_t *_match(def_t *defs, file_t *f, const char *str, vm_op_t *op, uns
//
// Get a specific numbered pattern capture.
//
+__attribute__((nonnull))
static match_t *get_capture_by_num(match_t *m, int *n)
{
if (*n == 0) return m;
@@ -489,6 +493,7 @@ static match_t *get_capture_by_num(match_t *m, int *n)
//
// Get a capture with a specific name.
//
+__attribute__((nonnull, pure))
static match_t *get_capture_by_name(match_t *m, const char *name)
{
if (m->op->type == VM_CAPTURE && m->op->args.capture.name
@@ -502,21 +507,22 @@ static match_t *get_capture_by_name(match_t *m, const char *name)
}
//
-// Get a capture by name.
+// Get a capture by identifier (name or number).
+// Update *id to point to after the identifier (if found).
//
-match_t *get_capture(match_t *m, const char **r)
+match_t *get_capture(match_t *m, const char **id)
{
- if (isdigit(**r)) {
- int n = (int)strtol(*r, (char**)r, 10);
+ if (isdigit(**id)) {
+ int n = (int)strtol(*id, (char**)id, 10);
return get_capture_by_num(m->child, &n);
} else {
- const char *end = after_name(*r);
- if (end == *r) return NULL;
- char *name = strndup(*r, (size_t)(end-*r));
+ const char *end = after_name(*id);
+ if (end == *id) return NULL;
+ char *name = strndup(*id, (size_t)(end-*id));
match_t *cap = get_capture_by_name(m, name);
xfree(&name);
- *r = end;
- if (**r == ';') ++(*r);
+ *id = end;
+ if (**id == ';') ++(*id);
return cap;
}
return NULL;