summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2022-04-29 16:47:52 -0400
committerJakob Kaivo <jkk@ung.org>2022-04-29 16:47:52 -0400
commit60e6ef8f7dfacfb93d5cb76d037d8ebea02c4a53 (patch)
treec14210e4df400318422d4b004157107f01a1124f
parent9985e226228bc34b23700f57a8cd78394ae3b1e5 (diff)
make more strategic use of specialized matching functionsHEADmaster
-rw-r--r--grep.c92
1 files changed, 50 insertions, 42 deletions
diff --git a/grep.c b/grep.c
index b508c77..c729d9d 100644
--- a/grep.c
+++ b/grep.c
@@ -46,57 +46,59 @@ static int grep_filenames = 0;
static int grep_linenumbers = 0;
static int grep_inverse = 0;
static int grep_silent = 0;
-static int grep_exact = 0;
-static int grep_match_re(struct grep_list *head, const char *buf)
+static int grep_match_re(struct grep_list *node, const char *buf)
{
- for (struct grep_list *c = head; c != NULL; c = c->next) {
- if (regexec(&(c->re), buf, 0, NULL, 0) == 0) {
- return !grep_inverse;
- }
- }
+ return (regexec(&(node->re), buf, 0, NULL, 0) == 0);
+}
- return grep_inverse;
+static int grep_match_F(struct grep_list *node, const char *buf)
+{
+ return (strstr(buf, node->string) != NULL);
}
-static int grep_match_fixed(struct grep_list *head, const char *buf)
+static int grep_match_Fx(struct grep_list *node, const char *buf)
{
- for (struct grep_list *c = head; c != NULL; c = c->next) {
- if (grep_exact && strcmp(buf, c->string) == 0) {
- return !grep_inverse;
- }
- if (!grep_exact && strstr(buf, c->string)) {
- return !grep_inverse;
+ return (strcmp(buf, node->string) == 0);
+}
+
+static int grep_match_Fix(struct grep_list *node, const char *buf)
+{
+ return (strcasecmp(buf, node->string) == 0);
+}
+
+static int grep_match_Fi(struct grep_list *node, const char *buf)
+{
+ if (grep_match_Fix(node, buf)) {
+ return 1;
+ }
+
+ size_t blen = strlen(buf);
+ if (blen < node->len) {
+ return 0;
+ }
+
+ for (size_t i = 0; i < (blen - node->len); i++) {
+ if (strncasecmp(buf + i, node->string, node->len) == 0) {
+ return 1;
}
}
- return grep_inverse;
+
+ return 0;
}
-static int grep_match_fixedcase(struct grep_list *head, const char *buf)
+static int (*grep_match)(struct grep_list *, const char *) = grep_match_re;
+
+static int grep_matches(struct grep_list *head, const char *buf)
{
- size_t blen = strlen(buf);
for (struct grep_list *c = head; c != NULL; c = c->next) {
- if (grep_exact && strcasecmp(buf, c->string) == 0) {
+ if (grep_match(c, buf)) {
return !grep_inverse;
}
- if (grep_exact) {
- continue;
- }
- if (blen <= c->len) {
- continue;
- }
-
- for (size_t i = 0; i < (blen - c->len); i++) {
- if (strncasecmp(buf + i, c->string, c->len) == 0) {
- return !grep_inverse;
- }
- }
}
return grep_inverse;
}
-static int (*grep_match)(struct grep_list *head, const char *buf) = grep_match_re;
-
static uintmax_t grep(struct grep_list *head, const char *path)
{
FILE *f = stdin;
@@ -125,7 +127,7 @@ static uintmax_t grep(struct grep_list *head, const char *path)
if (nl) {
*nl = '\0';
}
- if (grep_match(head, buf)) {
+ if (grep_matches(head, buf)) {
if (grep_display == NORMAL) {
if (grep_filenames) {
printf("%s:", path);
@@ -216,6 +218,7 @@ int main(int argc, char *argv[])
int flags = REG_NOSUB;
struct grep_list *head = NULL;
enum { REGEX, FIXED } type = REGEX;
+ int exact = 0;
int c;
while ((c = getopt(argc, argv, "EFce:f:ilnqsvx")) != -1) {
@@ -226,7 +229,6 @@ int main(int argc, char *argv[])
case 'F':
type = FIXED;
- grep_match = grep_match_fixed;
break;
case 'c':
@@ -266,7 +268,7 @@ int main(int argc, char *argv[])
break;
case 'x':
- grep_exact = 1;
+ exact = 1;
break;
default:
@@ -282,13 +284,19 @@ int main(int argc, char *argv[])
head = grep_add_list(head, argv[optind++]);
}
- if (type == FIXED && (flags & REG_ICASE)) {
- grep_match = grep_match_fixedcase;
- }
-
- if (type != FIXED) {
+ if (type == FIXED) {
+ if ((flags & REG_ICASE) && (exact)) {
+ grep_match = grep_match_Fix;
+ } else if (flags & REG_ICASE) {
+ grep_match = grep_match_Fi;
+ } else if (exact) {
+ grep_match = grep_match_Fx;
+ } else {
+ grep_match = grep_match_F;
+ }
+ } else {
for (struct grep_list *c = head; c != NULL; c = c->next) {
- if (grep_exact) {
+ if (exact) {
memmove(c->string + 1, c->string, c->len);
c->string[0] = '^';
c->string[c->len + 1] = '$';