diff options
author | Jakob Kaivo <jkk@ung.org> | 2022-04-29 16:47:52 -0400 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2022-04-29 16:47:52 -0400 |
commit | 60e6ef8f7dfacfb93d5cb76d037d8ebea02c4a53 (patch) | |
tree | c14210e4df400318422d4b004157107f01a1124f | |
parent | 9985e226228bc34b23700f57a8cd78394ae3b1e5 (diff) |
-rw-r--r-- | grep.c | 92 |
1 files changed, 50 insertions, 42 deletions
@@ -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] = '$'; |