diff options
| author | Jakob Kaivo <jkk@ung.org> | 2022-04-28 11:36:53 -0400 |
|---|---|---|
| committer | Jakob Kaivo <jkk@ung.org> | 2022-04-28 11:36:53 -0400 |
| commit | b7b37e986c7e4ca819f9cbbf683033f149f74e4b (patch) | |
| tree | cc905de6977ef2941725c37454b7066b8fe0c72a /grep.c | |
| parent | 7e965cba479cd560600bbb68bd1be0c619da9541 (diff) | |
implement -Fi
Diffstat (limited to 'grep.c')
| -rw-r--r-- | grep.c | 58 |
1 files changed, 47 insertions, 11 deletions
@@ -31,11 +31,13 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <strings.h> #include <unistd.h> struct grep_list { struct grep_list *next; char *string; + size_t len; regex_t re; }; @@ -46,27 +48,55 @@ static int grep_inverse = 0; static int grep_silent = 0; static int grep_exact = 0; -static int grep_match(struct grep_list *head, const char *buf) +static int grep_match_re(struct grep_list *head, const char *buf) { for (struct grep_list *c = head; c != NULL; c = c->next) { - if (c->string) { - if (grep_exact && strcmp(buf, c->string) == 0) { - return !grep_inverse; - } - if (!grep_exact && strstr(buf, c->string)) { - return !grep_inverse; - } - continue; + if (regexec(&(c->re), buf, 0, NULL, 0) == 0) { + return !grep_inverse; } + } - if (regexec(&(c->re), buf, 0, NULL, 0) == 0) { + return grep_inverse; +} + +static int grep_match_fixed(struct grep_list *head, 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 grep_inverse; +} +static int grep_match_fixedcase(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) { + 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; @@ -144,6 +174,7 @@ static struct grep_list * grep_add_list(struct grep_list *head, char *s) } node->string = strdup(pattern); + node->len = strlen(node->string); pattern = strtok(NULL, "\n"); } @@ -176,7 +207,7 @@ int main(int argc, char *argv[]) int flags = REG_NOSUB; struct grep_list *head = NULL; - enum {REGEX, FIXED } type = REGEX; + enum { REGEX, FIXED } type = REGEX; int c; while ((c = getopt(argc, argv, "EFce:f:ilnqsvx")) != -1) { @@ -187,6 +218,7 @@ int main(int argc, char *argv[]) case 'F': type = FIXED; + grep_match = grep_match_fixed; break; case 'c': @@ -242,6 +274,10 @@ 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) { for (struct grep_list *c = head; c != NULL; c = c->next) { int e = regcomp(&(c->re), c->string, flags); |
