changeset 983:c38c25282b88

Cleanup grep: help text, whitespace, add parentheses.
author Rob Landley <rob@landley.net>
date Thu, 01 Aug 2013 17:21:38 -0500
parents 0666d42df954
children 422696039640
files toys/pending/grep.c
diffstat 1 files changed, 76 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/toys/pending/grep.c	Thu Aug 01 15:46:45 2013 -0500
+++ b/toys/pending/grep.c	Thu Aug 01 17:21:38 2013 -0500
@@ -11,26 +11,28 @@
   bool "grep"
   default n
   help
-    usage: grep [-clq] [-EFHbhinosvw] (-e RE | -f REfile | RE) [file...]
+    usage: grep [-EFivw] [-cloqs] [-Hbhn] [-e REGEX]... [-f FILENAME] [FILE]...
 
-    modes:
-      default: print lines from each file what match regular expression RE.
-      -c:   print the number of matching lines in each file.
-      -l:   print all matching file names.
-      -q:   print nil; quit with code 0 when match found.
+    Show lines matching regular expressions. If no -e, first argument is
+    regular expression to match. With no files (or "-" filename) read stdin.
+    Returns 0 if matched, 1 if no match found.
+
+    -e  Regex to match. (May be repeated.)
+    -f  File containing regular expressions to match.
 
-    flags:
-      -E:   extended RE syntax
-      -F:   fixed RE syntax, i.e. all characters literal
-      -H:   print file name
-      -b:   print byte offset of match
-      -h:   not print file name
-      -i:   case insensitive
-      -n:   print line numbers
-      -o:   print only matching part
-      -s:   keep silent on error
-      -v:   invert match
-      -w:   match full word only
+    match type:
+    -E  extended regex syntax    -F  fixed (match literal string)
+    -i  case insensitive         -v  invert match
+    -w  whole words (implies -E)
+
+    display modes: (default: matched line)
+    -c  count of matching lines  -l  show matching filenames
+    -o  only matching part       -q  quiet (errors only)
+    -s  silent (no error msg)    
+
+    prefix modes (default: filename if checking more than 1 file)
+    -H  force filename           -b  byte offset of match
+    -h  hide filename            -n  line number of match
 */
 
 #define FOR_grep
@@ -45,7 +47,8 @@
   char mode, *re_xs;
 )
 
-static void do_grep (int fd, char *name) {
+static void do_grep(int fd, char *name)
+{
   int n = 0, nMatch = 0, which = toys.optflags & FLAG_w ? 2 : 0;
 
   for (;;) {
@@ -53,112 +56,124 @@
     regmatch_t matches[3];
     int atBOL = 1;
 
-    x = get_rawline (fd, 0, '\n');
+    x = get_rawline(fd, 0, '\n');
     if (!x) break;
     y = x;
     n++; /* start at 1 */
 
-    while (regexec (&re, y, 3, matches, atBOL ? 0 : REG_NOTBOL) == 0) {
+    while (regexec (&re, y, 3, matches, atBOL ? 0 : REG_NOTBOL) == 0)
+    {
       if (atBOL) nMatch++;
       toys.exitval = 0;
       atBOL = 0;
       switch (TT.mode) {
       case 'q':
-        xexit ();
+        xexit();
       case 'l':
-        if (!(toys.optflags & FLAG_h)) printf ("%s\n", name);
-        free (x);
+        if (!(toys.optflags & FLAG_h)) printf("%s\n", name);
+        free(x);
         return;
       case 'c':
         break;
       default:
-        if (!(toys.optflags & FLAG_h)) printf ("%s:", name);
-        if ( (toys.optflags & FLAG_n)) printf ("%d:", n);
-        if ( (toys.optflags & FLAG_b)) printf ("%ld:", lseek (0, 0, SEEK_CUR) - strlen (y) +
-                                                       (toys.optflags & FLAG_o ? matches[which].rm_so : 0));
-        if (!(toys.optflags & FLAG_o)) fputs (x, stdout);
+        if (!(toys.optflags & FLAG_h)) printf("%s:", name);
+        if ((toys.optflags & FLAG_n)) printf("%d:", n);
+        if ((toys.optflags & FLAG_b))
+          printf("%ld:", lseek (0, 0, SEEK_CUR) - strlen (y) +
+                 (toys.optflags & FLAG_o ? matches[which].rm_so : 0));
+        if (!(toys.optflags & FLAG_o)) fputs(x, stdout);
         else {
           y += matches[which].rm_so;
-          printf ("%.*s\n", matches[which].rm_eo - matches[which].rm_so, y++);
+          printf("%.*s\n", matches[which].rm_eo - matches[which].rm_so, y++);
         }
       }
       if (!(toys.optflags & FLAG_o)) break;
     }
 
-    free (x);
+    free(x);
 
     if ((toys.optflags & FLAG_m) && nMatch >= TT.mArgu) break;
   }
 
-  if (TT.mode == 'c') printf ("%s:%d\n", name, nMatch);
+  if (TT.mode == 'c') printf("%s:%d\n", name, nMatch);
 }
 
-char *regfix (char *re_xs) {
+char *regfix(char *re_xs)
+{
   char *re_ys;
   int ii, jj = 0;
-  re_ys = xmalloc (2*strlen (re_xs) + 1);
+
+  re_ys = xmalloc(2*strlen (re_xs) + 1);
   for (ii = 0; re_xs[ii]; ii++) {
-    if (strchr ("^.[]$()|*+?{}\\", re_xs[ii])) re_ys[jj++] = '\\';
+    if (strchr("^.[]$()|*+?{}\\", re_xs[ii])) re_ys[jj++] = '\\';
     re_ys[jj++] = re_xs[ii];
   }
   re_ys[jj] = 0;
+
   return re_ys;
 }
 
-void addRE (char *x) {
-  if (toys.optflags & FLAG_F) x = regfix (x);
-  if (TT.re_xs) TT.re_xs = xastrcat (TT.re_xs, "|");
-  TT.re_xs = xastrcat (TT.re_xs, x);
-  if (toys.optflags & FLAG_F) free (x);
+void addRE(char *x)
+{
+  if (toys.optflags & FLAG_F) x = regfix(x);
+  if (TT.re_xs) TT.re_xs = xastrcat(TT.re_xs, "|");
+  TT.re_xs = xastrcat(TT.re_xs, x);
+  if (toys.optflags & FLAG_F) free(x);
 }
 
-void buildRE (void) {
-  for (; TT.eArgu; TT.eArgu = TT.eArgu -> next) addRE (TT.eArgu -> arg);
+void buildRE(void)
+{
+  for (; TT.eArgu; TT.eArgu = TT.eArgu -> next) addRE(TT.eArgu -> arg);
   for (; TT.fArgu; TT.fArgu = TT.fArgu -> next) {
     FILE *f;
     char *x, *y;
     size_t l;
 
-    f = xfopen (TT.fArgu -> arg, "r");
+    f = xfopen(TT.fArgu -> arg, "r");
     x = 0;
     for (;;) {
       if (getline (&x, &l, f) < 0) {
-        if (feof (f)) break;
+        if (feof(f)) break;
         toys.exitval = 2;
-        perror_exit ("failed to read");
+        perror_exit("failed to read");
       }
-      y = x + strlen (x) - 1;
+      y = x + strlen(x) - 1;
       if (y[0] == '\n') y[0] = 0;
 
-      addRE (x);
+      addRE(x);
     }
-    free (x);
-    fclose (f);
+    free(x);
+    fclose(f);
   }
 
   if (!TT.re_xs) {
     if (toys.optc < 1) {
       toys.exitval = 2;
-      error_exit ("no RE");
+      error_exit("no RE");
     }
-    TT.re_xs = toys.optflags & FLAG_F ? regfix (toys.optargs[0]) : toys.optargs[0];
+    TT.re_xs = (toys.optflags & FLAG_F) ? regfix(toys.optargs[0])
+        : toys.optargs[0];
     toys.optc--; toys.optargs++;
   }
 
-  TT.re_xs = xmsprintf (toys.optflags & FLAG_w ? "(^|[^_[:alnum:]])(%s)($|[^_[:alnum:]])" : "%s", TT.re_xs);
+  TT.re_xs = xmsprintf((toys.optflags & FLAG_w)
+      ? "(^|[^_[:alnum:]])(%s)($|[^_[:alnum:]])" : "%s", TT.re_xs);
 
-  if (regcomp (&re, TT.re_xs,
-               (toys.optflags & (FLAG_E | FLAG_F) ? REG_EXTENDED : 0) |
-               (toys.optflags &  FLAG_i           ? REG_ICASE    : 0)) != 0) {
+  if (regcomp(&re, TT.re_xs,
+               ((toys.optflags & (FLAG_E | FLAG_F)) ? REG_EXTENDED : 0) |
+               ((toys.optflags &  FLAG_i)           ? REG_ICASE    : 0)) != 0) {
     toys.exitval = 2;
-    error_exit ("bad RE");
+    error_exit("bad RE");
   }
 }
 
-void grep_main (void) {
-  if (toys.optflags & FLAG_w && !(toys.optflags & FLAG_E || toys.optflags & FLAG_F)) error_exit ("must not use -w sans -E");
+void grep_main(void)
+{
+  if ((toys.optflags & FLAG_w)
+    && !(toys.optflags & FLAG_E || toys.optflags & FLAG_F))
+      error_exit ("must not use -w sans -E");
 
-  buildRE ();
+  buildRE();
 
   if (toys.optflags & FLAG_c) TT.mode = 'c';
   if (toys.optflags & FLAG_l) TT.mode = 'l';
@@ -167,6 +182,6 @@
   if (!(toys.optflags & FLAG_H) && (toys.optc < 2)) toys.optflags |= FLAG_h;
 
   toys.exitval = 1;
-  loopfiles_rw (toys.optargs, O_RDONLY, 0, toys.optflags & FLAG_s, do_grep);
-  xexit ();
+  loopfiles_rw(toys.optargs, O_RDONLY, 0, toys.optflags & FLAG_s, do_grep);
+  xexit();
 }