[hackers] [sbase] Implement -e support for grep || sin

From: <git_AT_suckless.org>
Date: Sat, 05 Oct 2013 16:29:34 +0200

commit f526ad099f35bd6a17af6ac23e2844bfb3fe4372
Author: sin <sin_AT_2f30.org>
Date: Fri Sep 27 16:26:22 2013 +0100

    Implement -e support for grep

diff --git a/grep.1 b/grep.1
index b64573e..f6c4d54 100644
--- a/grep.1
+++ b/grep.1
_AT_@ -4,6 +4,8 @@ grep \- search files for a pattern
 .SH SYNOPSIS
 .B grep
 .RB [ \-Ecilnqv ]
+.RB [ \-e
+.I pattern ]
 .I pattern
 .RI [ file ...]
 .SH DESCRIPTION
_AT_@ -25,6 +27,13 @@ matches using extended regex.
 .B \-c
 prints only a count of matching lines.
 .TP
+.B \-e pattern
+Specify a pattern used during the search of the input: an input
+line is selected if it matches any of the specified patterns.
+This option is most useful when multiple -e options are used to
+specify multiple patterns, or when a pattern begins with a dash
+(`-').
+.TP
 .B \-i
 matches lines case insensitively.
 .TP
diff --git a/grep.c b/grep.c
index 9716328..e8f6e79 100644
--- a/grep.c
+++ b/grep.c
_AT_@ -10,19 +10,27 @@
 
 enum { Match = 0, NoMatch = 1, Error = 2 };
 
-static void grep(FILE *, const char *, regex_t *);
+static void addpattern(const char *);
+static bool grep(FILE *, const char *);
 static void usage(void);
 
+static bool eflag = false;
 static bool vflag = false;
 static bool many;
-static bool match = false;
 static char mode = 0;
 
+static struct plist {
+ char *pattern;
+ regex_t preg;
+ struct plist *next;
+} *phead;
+
 int
 main(int argc, char *argv[])
 {
+ bool match = false;
+ struct plist *pnode, *tmp;
         int i, n, flags = REG_NOSUB;
- regex_t preg;
         FILE *fp;
 
         ARGBEGIN {
_AT_@ -30,6 +38,10 @@ main(int argc, char *argv[])
                 flags |= REG_EXTENDED;
                 break;
         case 'c':
+ case 'e':
+ addpattern(EARGF(usage()));
+ eflag = true;
+ break;
         case 'l':
         case 'n':
         case 'q':
_AT_@ -45,57 +57,97 @@ main(int argc, char *argv[])
                 usage();
         } ARGEND;
 
- if(argc == 0)
+ if(argc == 0 && !eflag)
                 usage(); /* no pattern */
 
- if((n = regcomp(&preg, argv[0], flags)) != 0) {
- char buf[BUFSIZ];
+ /* If -e is not specified treat it as if it were */
+ if(!eflag) {
+ addpattern(argv[0]);
+ argc--;
+ argv++;
+ }
+
+ /* Compile regex for all search patterns */
+ for(pnode = phead; pnode; pnode = pnode->next) {
+ if((n = regcomp(&pnode->preg, pnode->pattern, flags)) != 0) {
+ char buf[BUFSIZ];
 
- regerror(n, &preg, buf, sizeof buf);
- enprintf(Error, "invalid pattern: %s
", buf);
+ regerror(n, &pnode->preg, buf, sizeof buf);
+ enprintf(Error, "invalid pattern: %s
", buf);
+ }
         }
         many = (argc > 1);
- if(argc == 1)
- grep(stdin, "<stdin>", &preg);
- else for(i = 1; i < argc; i++) {
- if(!(fp = fopen(argv[i], "r")))
- enprintf(Error, "fopen %s:", argv[i]);
- grep(fp, argv[i], &preg);
- fclose(fp);
+ if(argc == 0) {
+ match = grep(stdin, "<stdin>");
+ } else {
+ for(i = 0; i < argc; i++) {
+ if(!(fp = fopen(argv[i], "r")))
+ enprintf(Error, "fopen %s:", argv[i]);
+ if(grep(fp, argv[i]))
+ match = true;
+ fclose(fp);
+ }
+ }
+ pnode = phead;
+ while(pnode) {
+ tmp = pnode->next;
+ regfree(&pnode->preg);
+ free(pnode->pattern);
+ free(pnode);
+ pnode = tmp;
         }
         return match ? Match : NoMatch;
 }
 
 void
-grep(FILE *fp, const char *str, regex_t *preg)
+addpattern(const char *pattern)
+{
+ struct plist *pnode;
+
+ pnode = malloc(sizeof(*pnode));
+ if(!pnode)
+ eprintf("malloc:");
+ pnode->pattern = strdup(pattern);
+ if(!pnode->pattern)
+ eprintf("strdup:");
+ pnode->next = phead;
+ phead = pnode;
+}
+
+bool
+grep(FILE *fp, const char *str)
 {
         char *buf = NULL;
         long n, c = 0;
         size_t size = 0, len;
+ struct plist *pnode;
+ bool match = false;
 
         for(n = 1; afgets(&buf, &size, fp); n++) {
- if(buf[(len = strlen(buf))-1] == '
')
- buf[--len] = '
Received on Sat Oct 05 2013 - 16:29:34 CEST

This archive was generated by hypermail 2.3.0 : Sat Oct 05 2013 - 16:36:43 CEST