diff options
| -rw-r--r-- | definitions.c | 8 | ||||
| -rw-r--r-- | definitions.h | 8 | ||||
| -rw-r--r-- | match.c | 12 | ||||
| -rw-r--r-- | pattern.c | 42 | ||||
| -rw-r--r-- | types.h | 9 |
5 files changed, 37 insertions, 42 deletions
diff --git a/definitions.c b/definitions.c index a19d3b8..0c99f9b 100644 --- a/definitions.c +++ b/definitions.c @@ -55,10 +55,10 @@ def_t *load_grammar(def_t *defs, file_t *f) // // Look up a backreference or grammar definition by name // -def_t *lookup(def_t *defs, const char *name) +def_t *lookup(def_t *defs, size_t namelen, const char *name) { for ( ; defs; defs = defs->next) { - if (strlen(name) == defs->namelen && strncmp(defs->name, name, defs->namelen) == 0) + if (namelen == defs->namelen && strncmp(defs->name, name, namelen) == 0) return defs; } return NULL; @@ -67,13 +67,13 @@ def_t *lookup(def_t *defs, const char *name) // // Push a backreference onto the backreference stack // -def_t *with_backref(def_t *defs, file_t *f, const char *name, match_t *m) +def_t *with_backref(def_t *defs, file_t *f, size_t namelen, const char *name, match_t *m) { pat_t *backref = new_pat(f, m->start, BP_BACKREF); backref->end = m->end; backref->len = -1; // TODO: maybe calculate this? (nontrivial because of replacements) backref->args.backref = m; - return with_def(defs, strlen(name), name, backref); + return with_def(defs, namelen, name, backref); } // diff --git a/definitions.h b/definitions.h index 8c3ae87..6017b59 100644 --- a/definitions.h +++ b/definitions.h @@ -9,12 +9,12 @@ __attribute__((nonnull(3,4), returns_nonnull)) def_t *with_def(def_t *defs, size_t namelen, const char *name, pat_t *pat); -__attribute__((nonnull(2,3,4), returns_nonnull)) -def_t *with_backref(def_t *defs, file_t *f, const char *name, match_t *m); +__attribute__((nonnull(2,4,5), returns_nonnull)) +def_t *with_backref(def_t *defs, file_t *f, size_t namelen, const char *name, match_t *m); __attribute__((nonnull(2))) def_t *load_grammar(def_t *defs, file_t *f); -__attribute__((pure, nonnull(2))) -def_t *lookup(def_t *defs, const char *name); +__attribute__((pure, nonnull(3))) +def_t *lookup(def_t *defs, size_t namelen, const char *name); __attribute__((nonnull(1))) void free_defs(def_t **defs, def_t *stop); @@ -171,8 +171,8 @@ match_t *match(def_t *defs, file_t *f, const char *str, pat_t *pat, unsigned int } case BP_STRING: { if (&str[pat->len] > f->end) return NULL; - if (ignorecase ? memicmp(str, pat->args.s, (size_t)pat->len) != 0 - : memcmp(str, pat->args.s, (size_t)pat->len) != 0) + if (ignorecase ? memicmp(str, pat->args.string, (size_t)pat->len) != 0 + : memcmp(str, pat->args.string, (size_t)pat->len) != 0) return NULL; match_t *m = new_match(); m->pat = pat; @@ -347,7 +347,7 @@ match_t *match(def_t *defs, file_t *f, const char *str, pat_t *pat, unsigned int { // Push backrefs and run matching, then cleanup def_t *defs2 = defs; if (m1->pat->type == BP_CAPTURE && m1->pat->args.capture.name) - defs2 = with_backref(defs2, f, m1->pat->args.capture.name, m1); + defs2 = with_backref(defs2, f, m1->pat->args.capture.namelen, m1->pat->args.capture.name, m1); // def_t *defs2 = with_backrefs(defs, f, m1); m2 = match(defs2, f, m1->end, pat->args.multiple.second, ignorecase); free_defs(&defs2, defs); @@ -414,8 +414,8 @@ match_t *match(def_t *defs, file_t *f, const char *str, pat_t *pat, unsigned int return m; } case BP_REF: { - def_t *def = lookup(defs, pat->args.s); - check(def != NULL, "Unknown identifier: '%s'", pat->args.s); + def_t *def = lookup(defs, pat->args.name.len, pat->args.name.name); + check(def != NULL, "Unknown identifier: '%.*s'", (int)pat->args.name.len, pat->args.name.name); pat_t *ref = def->pat; pat_t rec_op = { @@ -540,7 +540,7 @@ static match_t *get_capture_by_num(match_t *m, int *n) static match_t *get_capture_by_name(match_t *m, const char *name) { if (m->pat->type == BP_CAPTURE && m->pat->args.capture.name - && streq(m->pat->args.capture.name, name)) + && strncmp(m->pat->args.capture.name, name, m->pat->args.capture.namelen) == 0) return m; for (match_t *c = m->child; c; c = c->nextsibling) { match_t *cap = get_capture_by_name(c, name); @@ -246,7 +246,7 @@ static pat_t *_bp_simplepattern(file_t *f, const char *str) pat = new_pat(f, opstart, BP_STRING); char *s = xcalloc(sizeof(char), 2); s[0] = c; - pat->args.s = s; + pat->args.string = s; } pat->len = 1; @@ -296,7 +296,7 @@ static pat_t *_bp_simplepattern(file_t *f, const char *str) esc = new_pat(f, opstart, BP_STRING); char *s = xcalloc(sizeof(char), 2); s[0] = (char)e; - esc->args.s = s; + esc->args.string = s; } esc->len = 1; esc->end = str; @@ -323,7 +323,7 @@ static pat_t *_bp_simplepattern(file_t *f, const char *str) pat_t *pat = new_pat(f, start, BP_STRING); pat->len = (ssize_t)len; - pat->args.s = literal; + pat->args.string = literal; if (!matchchar(&str, endquote)) file_err(f, start, str, "This string doesn't have a closing quote."); @@ -448,7 +448,8 @@ static pat_t *_bp_simplepattern(file_t *f, const char *str) pat_t *capture = new_pat(f, start, BP_CAPTURE); const char *a = *str == '!' ? &str[1] : after_name(str); if (a > str && after_spaces(a)[0] == '=' && after_spaces(a)[1] != '>') { - capture->args.capture.name = strndup(str, (size_t)(a-str)); + capture->args.capture.name = str; + capture->args.capture.namelen = (size_t)(a-str); str = after_spaces(a) + 1; } pat_t *captured = bp_simplepattern(f, str); @@ -461,17 +462,13 @@ static pat_t *_bp_simplepattern(file_t *f, const char *str) } // Special rules: case '_': case '^': case '$': case '|': { - const char *name = NULL; - if (matchchar(&str, c)) { // double __, ^^, $$ - if (matchchar(&str, ':')) return NULL; // Don't match definitions - char tmp[3] = {c, c, '\0'}; - name = strdup(tmp); - } else { - if (matchchar(&str, ':')) return NULL; // Don't match definitions - name = strndup(&c, 1); - } + size_t namelen = 1; + if (matchchar(&str, c)) // double __, ^^, $$ + ++namelen; + if (matchchar(&str, ':')) return NULL; // Don't match definitions pat_t *ref = new_pat(f, start, BP_REF); - ref->args.s = name; + ref->args.name.name = start; + ref->args.name.len = namelen; ref->end = str; return ref; } @@ -484,7 +481,8 @@ static pat_t *_bp_simplepattern(file_t *f, const char *str) if (matchchar(&str, ':')) // Don't match definitions return NULL; pat_t *ref = new_pat(f, start, BP_REF); - ref->args.s = strndup(refname, (size_t)(str - refname)); + ref->args.name.name = refname; + ref->args.name.len = (size_t)(str - refname); ref->end = str; return ref; } @@ -537,7 +535,7 @@ pat_t *bp_stringpattern(file_t *f, const char *str) if (len > 0) { pat_t *strop = new_pat(f, str, BP_STRING); strop->len = (ssize_t)len; - strop->args.s = literal; + strop->args.string = literal; strop->end = str; ret = chain_together(f, ret, strop); } @@ -608,16 +606,8 @@ def_t *bp_definition(def_t *defs, file_t *f, const char *str) // void destroy_pat(pat_t *pat) { - switch (pat->type) { - case BP_STRING: case BP_REF: - xfree(&pat->args.s); - break; - case BP_CAPTURE: - if (pat->args.capture.name) - xfree(&pat->args.capture.name); - break; - default: break; - } + if (pat->type == BP_STRING) + xfree(&pat->args.string); } // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1 @@ -41,7 +41,11 @@ typedef struct pat_s { // Length of the match, if constant, otherwise -1 ssize_t len; union { - const char *s; + const char *string; + struct { + const char *name; + size_t len; + } name; struct { unsigned char low, high; } range; @@ -60,7 +64,8 @@ typedef struct pat_s { } replace; struct { struct pat_s *capture_pat; - char *name; + const char *name; + size_t namelen; } capture; struct match_s *backref; struct { |
