aboutsummaryrefslogtreecommitdiffstats
path: root/pw.c
diff options
context:
space:
mode:
Diffstat (limited to 'pw.c')
-rw-r--r--pw.c99
1 files changed, 58 insertions, 41 deletions
diff --git a/pw.c b/pw.c
index 6d7e3e9..cc3a19b 100644
--- a/pw.c
+++ b/pw.c
@@ -48,6 +48,8 @@ typedef struct grep {
char *pat;
regex_t rx;
int inv;
+ int err;
+ void (*dtor)(char *);
} grep;
#define cmdsize 256
@@ -236,6 +238,51 @@ static void usage(const char *name)
exit(EXIT_FAILURE);
}
+static int grinit(grep *gr, char *pat, int inv, void (*dtor)(char *))
+
+{
+ gr->pat = pat;
+ gr->inv = inv;
+ gr->dtor = dtor;
+ return (gr->err = regcomp(&gr->rx, pat, regex_flags | REG_NOSUB)) != 0;
+}
+
+static void grclean(grep *gr)
+{
+ if (gr->err == 0)
+ regfree(&gr->rx);
+ if (gr->dtor)
+ gr->dtor(gr->pat);
+ memset(gr, 0, sizeof *gr);
+}
+
+static int grerr(grep *gr)
+{
+ return gr->err;
+}
+
+static size_t grerrstr(grep *gr, char *buf, size_t size)
+{
+ return regerror(gr->err, &gr->rx, buf, size);
+}
+
+static grep *grnew(char *pat, int inv, void (*dtor)(char *))
+{
+ grep *gr = calloc(sizeof *gr, 1);
+ if (gr == 0)
+ panic("out of memory");
+ (void) grinit(gr, pat, inv, dtor);
+ return gr;
+}
+
+static void grfree(grep *gr)
+{
+ if (gr != 0) {
+ grclean(gr);
+ free(gr);
+ }
+}
+
static int grexec(grep *gr, const char *line)
{
int match = regexec(&gr->rx, line, 0, NULL, 0) == 0;
@@ -512,7 +559,6 @@ static void execute(char *cmd, unsigned *pstat, unsigned hist)
case 'g':
case 'v':
{
- int err;
grep *gr = &grepstack[ngrep];
if (arg[0] == 0) {
@@ -525,18 +571,12 @@ static void execute(char *cmd, unsigned *pstat, unsigned hist)
break;
}
- memset(gr, 0, sizeof *gr);
-
- if ((err = regcomp(&gr->rx, arg, regex_flags | REG_NOSUB)) != 0) {
- regerror(err, &gr->rx, cmd, cmdsize);
+ if ((grinit(gr, dsdup(arg), cmd[1] == 'v', dsdrop)) != 0) {
+ grerrstr(gr, cmd, cmdsize);
+ grclean(gr);
break;
}
- gr->pat = dsdup(arg);
-
- if (cmd[1] == 'v')
- gr->inv = 1;
-
if (ngrep++ == 0)
*pstat |= stat_grep;
}
@@ -1110,10 +1150,9 @@ int main(int argc, char **argv)
break;
}
} else if (kbd_state == kbd_trig && (int) trig < maxlines && trig < maxtrig) {
- int err;
char *rx = cmdbuf + 1;
int inv = 0;
- regex_t regex;
+ grep *gr = 0;
if (strncmp(rx, "\\!", 2) == 0) {
rx++;
@@ -1124,44 +1163,22 @@ int main(int argc, char **argv)
char *pat = dsdup(rx);
- if (*pat && (err = regcomp(&regex, pat, regex_flags | REG_NOSUB))) {
- regerror(err, &regex, cmdbuf, sizeof cmdbuf);
- if (columns < (int) sizeof cmdbuf - 1)
- cmdbuf[columns] = 0;
+ if (*pat && (gr = grnew(dsref(pat), inv, dsdrop), grerr(gr) != 0)) {
+ grerrstr(gr, cmdbuf, min(columns, (int) sizeof cmdbuf));
+ grfree(gr);
kbd_state = kbd_result;
} else {
if ((cmdbuf[0] == '/' && (stat & stat_ttmode)) ||
(cmdbuf[0] == '?' && (stat & stat_htmode)))
{
for (int i = 0; i < maxtrig; i++) {
- grep *gr = triglist[i];
- if (gr) {
- regfree(&gr->rx);
- dsdrop(gr->pat);
- free(gr);
- triglist[i] = 0;
- }
+ grfree(triglist[i]);
+ triglist[i] = 0;
}
}
- {
- grep *gr = triglist[trig];
-
- if (gr) {
- regfree(&gr->rx);
- dsdrop(gr->pat);
- }
- triglist[trig] = 0;
- }
-
- if (*pat) {
- grep *gr = malloc(sizeof *gr);
- regfree(&regex);
- regcomp(&gr->rx, pat, regex_flags | REG_NOSUB);
- gr->pat = dsref(pat);
- gr->inv = inv;
- triglist[trig] = gr;
- }
+ grfree(triglist[trig]);
+ triglist[trig] = gr;
}
dsdrop(pat);
}