#include #include #include #include #include #include #include #include #include #include "util/debug.h" #include "util/error.h" #include "util/loop_args.h" #include "util/versie.h" #include "io/read_file.h" char *gpats; bool fixed = false; bool extended = false; bool icase = false; static void usage(FILE *f) { fprintf(f, "Gebruik: grijp [-hV] [PATRONEN] [BESTAND]...\n" "\n" "TODO\n" "\n" " -h Toon deze hulptekst\n" " -V Toon versienummer\n"); } // 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, "FiEhV")) != -1) { switch (opt) { case 'F': fixed = true; break; case 'i': icase = true; break; case 'E': extended = true; break; case 'h': usage(stdout); exit(0); case 'V': drukkedoos_print_versie(stdout); exit(0); case '?': fprintf(stderr, "grijp: Ongeldige optie: -%c\n", optopt); usage(stderr); exit(1); } } return argv + optind; } static char **get_patterns(size_t *_npat) { char **patterns; size_t npat = 0; { size_t cappat = 1 << 4; patterns = calloc(sizeof(char*), cappat); char *s = gpats; char *pat = NULL; while ((pat = strtok(s, "\n")) != NULL) { s = NULL; if (npat == cappat) { cappat *= 2; patterns = realloc(patterns, sizeof(char*)*cappat); } patterns[npat] = strdup(pat); npat++; } } *_npat = npat; return patterns; } static int process_regex(char *fname, bool isstdin) { FILE *stream = isstdin ? stdin : fopen(fname, "rb"); size_t npat = 0; char **patterns = get_patterns(&npat); regex_t **regexps = calloc(sizeof(regex_t*), npat); for (size_t i = 0; i < npat; i++) { regex_t *regexp = calloc(1, sizeof(regex_t)); int flags = 0; if (extended) flags |= REG_EXTENDED; if (icase) flags |= REG_ICASE; if (regcomp(regexp, patterns[i], flags) != 0) { fprintf(stderr, "grijp: fout tijdens compileren van reguliere expressie\n"); return 1; } free(patterns[i]); regexps[i] = regexp; } free(patterns); 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 = regexps[i]; regmatch_t pmatch; if (regexec(regexp, line, 1, &pmatch, 0) == 0) { printf("%s", line); } } } free(line); for (size_t i = 0; i < npat; i++) regfree(regexps[i]); free(regexps); if (!isstdin) fclose(stream); return 0; } static int process_fixed(char *fname, bool isstdin) { FILE *stream = isstdin ? stdin : fopen(fname, "rb"); size_t npat = 0; char **patterns = get_patterns(&npat); 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++) { char *pat = patterns[i]; if (strstr(line, pat) == NULL) continue; printf("%s", line); } } free(line); for (size_t i = 0; i < npat; i++) free(patterns[i]); free(patterns); if (!isstdin) fclose(stream); return 0; } int entry_grijp(int argc, char **argv) { char **args = parse_options(argc, argv); if (*args == NULL) { fprintf(stderr, "grijp: geen patroon gegeven\n"); return 1; } gpats = *args; args++; if (fixed) { return loop_args(args, process_fixed); } else { return loop_args(args, process_regex); } }