summaryrefslogtreecommitdiff
path: root/grep.c
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2022-04-20 20:48:40 -0400
committerJakob Kaivo <jkk@ung.org>2022-04-20 20:48:40 -0400
commita1bd639027363be6aee545490f04a68b867d995e (patch)
treec05ec1cf837145a8bfe59ef21d76917af6f8a5cc /grep.c
parent41948b1c6511dc5c86f62129274057e5202189ac (diff)
fresh approach, implement -e and -f
Diffstat (limited to 'grep.c')
-rw-r--r--grep.c120
1 files changed, 80 insertions, 40 deletions
diff --git a/grep.c b/grep.c
index 240727d..f226d36 100644
--- a/grep.c
+++ b/grep.c
@@ -24,6 +24,7 @@
#define _POSIX_C_SOURCE 200809L
+#include <errno.h>
#include <locale.h>
#include <limits.h>
#include <regex.h>
@@ -34,6 +35,12 @@
#include <sys/types.h>
#include <unistd.h>
+struct grep_list {
+ struct grep_list *next;
+ char *string;
+ regex_t re;
+};
+
#ifndef ARG_MAX
#define ARG_MAX _POSIX_ARG_MAX
#endif
@@ -54,6 +61,7 @@
#define WHOLELINE 1 << 4
#define FILENAMES 1 << 5
+#if 0
static int grep(int patterns, char **p, int type, int display, int flags,
char *path)
{
@@ -141,68 +149,111 @@ static int grep(int patterns, char **p, int type, int display, int flags,
return count;
}
+#endif
+
+static struct grep_list * grep_add_list(struct grep_list *head, char *s)
+{
+ char *pattern = strtok(s, "\n");
+ while (pattern) {
+ struct grep_list *node = calloc(1, sizeof(*node));
+ if (node == NULL) {
+ perror("grep");
+ exit(2);
+ }
+
+ if (head == NULL) {
+ head = node;
+ } else {
+ struct grep_list *tmp = head;
+ while (tmp->next != NULL) {
+ tmp = tmp->next;
+ }
+ tmp->next = node;
+ }
+
+ node->string = strdup(pattern);
+
+ pattern = strtok(NULL, "\n");
+ }
+ return head;
+}
+
+static struct grep_list * grep_add_file(struct grep_list *head, char *path)
+{
+ FILE *f = fopen(path, "r");
+ if (f == NULL) {
+ fprintf(stderr, "grep: %s: %s\n", path, strerror(errno));
+ exit(2);
+ }
+
+ char *buf = NULL;
+ size_t len = 0;
+ while (getline(&buf, &len, f) != -1) {
+ head = grep_add_list(head, buf);
+ }
+ free(buf);
+
+ fclose(f);
+
+ return head;
+}
int main(int argc, char *argv[])
{
setlocale(LC_ALL, "");
int c;
- int type = BASIC;
- int display = NORMAL;
- int flags = 0;
- int patterns = 0;
- int pfiles = 0;
- char *p[ARG_MAX];
- int found = 0;
-
- while ((c = getopt(argc, argv, "EFclqinsvxe:f:")) != -1) {
+ int flags = REG_NOSUB;
+ struct grep_list *head = NULL;
+
+ while ((c = getopt(argc, argv, "EFce:f:ilnqsvx")) != -1) {
switch (c) {
case 'E':
- type = EXTENDED;
+ flags |= REG_EXTENDED;
break;
case 'F':
- type = FIXED; // FIXME
+ //type = FIXED; // FIXME
break;
case 'c':
- display = COUNT;
+ //display = COUNT;
break;
case 'e':
- p[patterns++] = optarg;
+ head = grep_add_list(head, optarg);
break;
case 'f':
- //pf[pfiles++] = optarg;
+ head = grep_add_file(head, optarg);
break;
case 'i':
- flags |= IGNORECASE;
+ flags |= REG_ICASE;
break;
case 'l':
- display = LIST;
+ //display = LIST;
break;
case 'n':
- flags |= LINENUMBERS;
+ //flags |= LINENUMBERS;
break;
case 'q':
- display = QUIET;
+ //display = QUIET;
break;
case 's':
- flags |= SUPPRESS;
+ //flags |= SUPPRESS;
break;
case 'v':
- flags |= INVERT;
+ //flags |= INVERT;
break;
case 'x':
- flags |= WHOLELINE;
+ //flags |= WHOLELINE;
break;
default:
@@ -210,26 +261,15 @@ int main(int argc, char *argv[])
}
}
- if (pfiles > 0) {
- // FIXME: read in the files
- }
-
- if (patterns == 0 && optind >= argc) {
- return 2;
- } else if (patterns == 0) {
- p[patterns++] = argv[optind++];
+ if (head == NULL) {
+ if (optind > argc - 1) {
+ perror("grep: missing operands\n");
+ return 2;
+ }
+ head = grep_add_list(head, argv[optind++]);
}
- if (optind >= argc) {
- found = grep(patterns, p, type, display, flags, "-");
- } else {
- if (argc - optind > 1)
- flags |= FILENAMES;
- while (optind < argc)
- found +=
- grep(patterns, p, type, display, flags,
- argv[optind++]);
+ for (struct grep_list *c = head; c != NULL; c = c->next) {
+ printf("pattern '%s'\n", c->string);
}
-
- return (found == 0 ? 1 : 0);
}