From e97a7b59139232bc44101c0ea7815ceb100be9de Mon Sep 17 00:00:00 2001 From: Lieuwe Rooijakkers Date: Fri, 9 Aug 2024 16:04:56 +0200 Subject: grijp: dingen --- src/grijp.c | 82 ++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 25 deletions(-) diff --git a/src/grijp.c b/src/grijp.c index 8bb285e..79b0d11 100644 --- a/src/grijp.c +++ b/src/grijp.c @@ -21,10 +21,14 @@ static bool fixed = false; static bool extended = false; static bool icase = false; static bool binary = false; +static bool list = false; +static bool invert = false; static size_t npat = 0; static void **patterns = NULL; // can hold `char*` or `regex_t*` +static size_t nfiles; + static void usage(FILE *f) { fprintf(f, "Gebruik: grijp [-hV] [PATRONEN] [BESTAND]...\n" @@ -38,7 +42,7 @@ static void usage(FILE *f) { // Returns pointer to argument array containing patterns and then the file names static char** parse_options(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "FiEUhV")) != -1) { + while ((opt = getopt(argc, argv, "FiEUlLvhV")) != -1) { switch (opt) { case 'F': fixed = true; @@ -52,6 +56,16 @@ static char** parse_options(int argc, char **argv) { case 'U': binary = true; break; + case 'l': + list = true; + break; + case 'L': + invert = true; + list = true; + break; + case 'v': + invert = true; + break; case 'h': usage(stdout); @@ -107,31 +121,28 @@ static void compile_regexps() { } } -static int process_regex(char *fname, bool isstdin) { - FILE *stream = isstdin ? stdin : fopen(fname, binary ? "rb" : "r"); - - char *line = NULL; - size_t linen = 0; - - ssize_t nread = 0; - while ((errno = 0, nread = getline(&line, &linen, stream)) != -1) { - for (size_t i = 0; i < npat; i++) { - regex_t *regexp = patterns[i]; +static void printMatch(char *fname, char *line) { + if (list) { + printf("%s\n", fname); + return; + } - regmatch_t pmatch; - if (regexec(regexp, line, 1, &pmatch, 0) == 0) { - printf("%s", line); - } - } + if (nfiles >= 2) { + printf("%s:", fname); } - free(line); - if (!isstdin) fclose(stream); - return 0; + printf("%s", line); } -static int process_fixed(char *fname, bool isstdin) { +static int process(char *fname, bool isstdin) { FILE *stream = isstdin ? stdin : fopen(fname, binary ? "rb" : "r"); + if (stream == NULL && !isstdin) { + fprintf(stderr, "grijp: %s: fout tijdens openen bestand\n", fname); + return 1; + } else if (stream == NULL && isstdin) { + fprintf(stderr, "grijp: fout tijdens lezen standaard invoer\n"); + return 1; + } char *line = NULL; size_t linen = 0; @@ -139,11 +150,25 @@ static int process_fixed(char *fname, bool isstdin) { ssize_t nread = 0; while ((errno = 0, nread = getline(&line, &linen, stream)) != -1) { for (size_t i = 0; i < npat; i++) { - char *pat = patterns[i]; - if (strstr(line, pat) == NULL) continue; - printf("%s", line); + bool matches = false; + + if (fixed) { + char *pat = patterns[i]; + matches = (strstr(line, pat) != NULL); + } else { + regex_t *regexp = patterns[i]; + regmatch_t pmatch; + matches = (regexec(regexp, line, 1, &pmatch, 0) == 0); + } + if (invert) matches = !matches; + + if (matches) { + printMatch(fname, line); + if (list) goto done; + } } } +done: free(line); if (!isstdin) fclose(stream); @@ -160,15 +185,22 @@ int entry_grijp(int argc, char **argv) { gpats = *args; args++; + // count the amount of files provided + { + char **cur = args; + while (*cur != NULL) cur++; + nfiles = cur - args; + } + parse_patterns(); int res = 0; if (fixed) { - res = loop_args(args, process_fixed); + res = loop_args(args, process); for (size_t i = 0; i < npat; i++) free(patterns[i]); } else { compile_regexps(); - res = loop_args(args, process_regex); + res = loop_args(args, process); for (size_t i = 0; i < npat; i++) regfree(patterns[i]); } free(patterns); -- cgit v1.2.3-70-g09d2