commit 6866bcdec8d8fc7c42e18ebc7e0bd350db91e4f0
Author: sin <[email protected]>
Date:   Thu Nov 20 14:35:23 2014 +0000

    Implement grep -F

diff --git a/grep.1 b/grep.1
index 9971fb2..7eef257 100644
--- a/grep.1
+++ b/grep.1
@@ -3,7 +3,7 @@
 grep \- search files for a pattern
 .SH SYNOPSIS
 .B grep
-.RB [ \-EHchilnqsv ]
+.RB [ \-EFHchilnqsv ]
 .RB [ \-e
 .I pattern ]
 .I pattern
@@ -22,14 +22,18 @@ status code is 2.
 .SH OPTIONS
 .TP
 .B \-E
-matches using extended regex.
+Matches using extended regex.
+.TP
+.B \-F
+Match using fixed strings.  Treat each pattern specified as a string instead 
of a regular
+expression.
 .TP
 .B \-H
-prefixes each matching line with its filename in the output. This is the
+Prefixes each matching line with its filename in the output. This is the
 default when there is more than one file specified.
 .TP
 .B \-c
-prints only a count of matching lines.
+Prints only a count of matching lines.
 .TP
 .B \-e pattern
 Specify a pattern used during the search of the input: an input
@@ -39,26 +43,26 @@ specify multiple patterns, or when a pattern begins with a 
dash
 (`-').
 .TP
 .B \-h
-do not prefix each line with 'filename:' prefix.
+Do not prefix each line with 'filename:' prefix.
 .TP
 .B \-i
-matches lines case insensitively.
+Matches lines case insensitively.
 .TP
 .B \-l
-prints only the names of files with matching lines.
+Prints only the names of files with matching lines.
 .TP
 .B \-n
-prefixes each matching line with its line number in the input.
+Prefixes each matching line with its line number in the input.
 .TP
 .B \-q
-prints nothing, only returns status.
+Prints nothing, only returns status.
 .TP
 .B \-s
 Suppress the error messages ordinarily written for nonexistent or unreadable 
files.
 .TP
 .B \-v
-selects lines which do
+Selects lines which do
 .B not
-match the pattern.
+Match the pattern.
 .SH SEE ALSO
 .IR regex (7)
diff --git a/grep.c b/grep.c
index 8c4ea7d..d147642 100644
--- a/grep.c
+++ b/grep.c
@@ -14,6 +14,7 @@ enum { Match = 0, NoMatch = 1, Error = 2 };
 static void addpattern(const char *);
 static int grep(FILE *, const char *);
 
+static int Fflag;
 static int Hflag;
 static int eflag;
 static int hflag;
@@ -33,7 +34,7 @@ static SLIST_HEAD(phead, pattern) phead;
 static void
 usage(void)
 {
-       enprintf(Error, "usage: %s [-EHcilnqsv] [-e pattern] pattern 
[files...]\n", argv0);
+       enprintf(Error, "usage: %s [-EFHcilnqsv] [-e pattern] pattern 
[files...]\n", argv0);
 }
 
 int
@@ -49,6 +50,9 @@ main(int argc, char *argv[])
        case 'E':
                flags |= REG_EXTENDED;
                break;
+       case 'F':
+               Fflag = 1;
+               break;
        case 'H':
                Hflag = 1;
                break;
@@ -88,9 +92,10 @@ main(int argc, char *argv[])
                argv++;
        }
 
-       /* Compile regex for all search patterns */
-       SLIST_FOREACH(pnode, &phead, entry)
-               enregcomp(Error, &pnode->preg, pnode->pattern, flags);
+       if (!Fflag)
+               /* Compile regex for all search patterns */
+               SLIST_FOREACH(pnode, &phead, entry)
+                       enregcomp(Error, &pnode->preg, pnode->pattern, flags);
        many = (argc > 1);
        if (argc == 0) {
                match = grep(stdin, "<stdin>");
@@ -111,7 +116,8 @@ main(int argc, char *argv[])
        while (!SLIST_EMPTY(&phead)) {
                pnode = SLIST_FIRST(&phead);
                SLIST_REMOVE_HEAD(&phead, entry);
-               regfree(&pnode->preg);
+               if (!Fflag)
+                       regfree(&pnode->preg);
                free(pnode->pattern);
                free(pnode);
        }
@@ -142,8 +148,15 @@ grep(FILE *fp, const char *str)
                if (len && buf[len - 1] == '\n')
                        buf[len - 1] = '\0';
                SLIST_FOREACH(pnode, &phead, entry) {
-                       if (regexec(&pnode->preg, buf, 0, NULL, 0) ^ vflag)
-                               continue;
+                       if (!Fflag) {
+                               if (regexec(&pnode->preg, buf, 0, NULL, 0) ^ 
vflag)
+                                       continue;
+                       } else {
+                               match = strstr(buf, pnode->pattern) ? Match : 
NoMatch;
+                               match ^= vflag;
+                               if (match)
+                                       continue;
+                       }
                        switch (mode) {
                        case 'c':
                                c++;


Reply via email to