commit ce5fd79d5a818fa0ac428426db5a2c27570d4d7f
parent ad0d991dd8b10d443519ff87996c2df6ff68a14c
Author: Jacob R. Edwards <n/a>
Date: Sun, 11 Dec 2022 20:14:34 -0600
Simplify find functions
Create a seperate matching function for each type of search. This
shortens up findnext() considerably and further isolates search
type specific stuff.
Additionally, it allows figuring out the search type implicitly
without a dedicated variable. (Or, if there were ever to be more
search types, other abstractions like defining types to numbers;
"enum { RegSearch, NumSearch, OthSearch };")
Diffstat:
M | aps/find.c | | | 68 | ++++++++++++++++++++++++++++++++++++++++++-------------------------- |
M | aps/find.h | | | 4 | +++- |
2 files changed, 45 insertions(+), 27 deletions(-)
diff --git a/aps/find.c b/aps/find.c
@@ -57,6 +57,41 @@ findnum(char *str, int *i, char **ep)
return NULL;
}
+struct item *
+matchreg(struct search *state)
+{
+ switch (regexec(&state->u.reg, state->cur->path, 0, NULL, 0)) {
+ case 0:
+ if (!state->inv)
+ return state->cur;
+ break;
+ case REG_NOMATCH:
+ if (state->inv)
+ return state->cur;
+ break;
+ default:
+ bug("Regex failed to execute");
+ }
+
+ return NULL;
+}
+
+struct item *
+matchnum(struct search *state)
+{
+ struct item *match;
+
+ match = NULL;
+ if (state->u.num.ind > state->u.num.max)
+ state->fin = 1;
+ else if (state->u.num.ind >= state->u.num.min)
+ match = state->cur;
+
+ state->u.num.ind += 1;
+
+ return match;
+}
+
void
renewsearch(struct search *state, struct item *start)
{
@@ -64,7 +99,7 @@ renewsearch(struct search *state, struct item *start)
state->end = start;
state->fin = start == NULL;
state->new = 1;
- if (!state->reg) {
+ if (state->match == matchnum) {
state->u.num.ind = 0;
if (state->u.num.min < 0) {
while (state->u.num.ind > state->u.num.min) {
@@ -108,7 +143,7 @@ prepsearch(struct search *state, struct item *start, char *pattern)
return err;
}
state->inc = (c == '/') ? nextitem : previtem;
- state->reg = 1;
+ state->match = matchreg;
} else if (pattern[0]) {
if ((ep = findnum(pattern, &state->u.num.min, &p)))
return ep;
@@ -133,7 +168,7 @@ prepsearch(struct search *state, struct item *start, char *pattern)
}
state->inv = 0;
state->inc = nextitem;
- state->reg = 0;
+ state->match = matchnum;
}
renewsearch(state, start);
@@ -143,7 +178,7 @@ prepsearch(struct search *state, struct item *start, char *pattern)
void
stopsearch(struct search *state)
{
- if (state->reg)
+ if (state->match == matchreg)
regfree(&state->u.reg);
}
@@ -157,29 +192,10 @@ findnext(struct search *state)
/* NOTE: state->inc cannot return NULL */
for (match = NULL; !match && !state->fin; state->cur = state->inc(state->cur)) {
- if (!state->new && state->cur == state->end) {
+ if (!state->new && state->cur == state->end)
state->fin = 1;
- } else if (state->reg) { /* One could do something like "match = state->match(state->cur);" instead. */
- switch (regexec(&state->u.reg, state->cur->path, 0, NULL, 0)) {
- case 0:
- if (!state->inv)
- match = state->cur;
- break;
- case REG_NOMATCH:
- if (state->inv)
- match = state->cur;
- break;
- default:
- bug("Regex failed to execute");
- }
- } else {
- if (state->u.num.ind > state->u.num.max)
- state->fin = 1;
- else if (state->u.num.ind >= state->u.num.min)
- match = state->cur;
- /* Placement determines if indexing starts from 0 or 1 */
- state->u.num.ind += 1;
- }
+ else
+ match = state->match(state);
if (state->new)
state->new = 0;
diff --git a/aps/find.h b/aps/find.h
@@ -1,10 +1,12 @@
+struct search;
+
struct search {
int fin;
int new;
- int reg;
int inv;
struct item *(*inc)(struct item *);
struct item *cur, *end;
+ struct item *(*match)(struct search *);
union {
regex_t reg;
struct {