summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/grijp.c82
1 files 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);