More minor fixes.
[oweals/busybox.git] / grep.c
1 /*
2  * Mini grep implementation for busybox
3  *
4  *
5  * Copyright (C) 1999 by Lineo, inc.
6  * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  *
22  */
23
24 /*
25         18-Dec-1999     Konstantin Boldyshev <konst@voshod.com>
26
27         + -q option (be quiet) 
28         + exit code depending on grep result (TRUE or FALSE)
29           (useful for scripts)
30 */
31
32 #include "internal.h"
33 #include "regexp.h"
34 #include <stdio.h>
35 #include <dirent.h>
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <signal.h>
39 #include <time.h>
40 #include <ctype.h>
41
42 static const char grep_usage[] =
43 "grep [OPTIONS]... PATTERN [FILE]...\n\n"
44 "Search for PATTERN in each FILE or standard input.\n\n"
45 "OPTIONS:\n"
46 "\t-h\tsuppress the prefixing filename on output\n"
47 "\t-i\tignore case distinctions\n"
48 "\t-n\tprint line number with output lines\n"
49 "\t-q\tbe quiet. Returns 0 if result was found, 1 otherwise\n\n"
50 #if defined BB_REGEXP
51 "This version of grep matches full regular expresions.\n";
52 #else
53 "This version of grep matches strings (not regular expresions).\n";
54 #endif
55
56 static int match = FALSE, beQuiet = FALSE;
57
58 static void do_grep(FILE *fp, char* needle, char *fileName, int tellName, int ignoreCase, int tellLine)
59 {
60     char *cp;
61     long line = 0;
62     char haystack[BUF_SIZE];
63
64     while (fgets (haystack, sizeof (haystack), fp)) {
65         line++;
66         cp = &haystack[strlen (haystack) - 1];
67
68         if (*cp != '\n')
69             fprintf (stderr, "%s: Line too long\n", fileName);
70
71         if (find_match(haystack, needle, ignoreCase) == TRUE) {
72             if (tellName==TRUE)
73                 printf ("%s:", fileName);
74
75             if (tellLine==TRUE)
76                 printf ("%ld:", line);
77
78             if (beQuiet==FALSE)
79                 fputs (haystack, stdout);
80
81             match = TRUE;
82         }
83     }
84 }
85
86
87 extern int grep_main (int argc, char **argv)
88 {
89     FILE *fp;
90     char *cp;
91     char *needle;
92     char *fileName;
93     int tellName=FALSE;
94     int ignoreCase=FALSE;
95     int tellLine=FALSE;
96
97
98     ignoreCase = FALSE;
99     tellLine = FALSE;
100
101     argc--;
102     argv++;
103     if (argc < 1) {
104         usage(grep_usage);
105     }
106
107     if (**argv == '-') {
108         argc--;
109         cp = *argv++;
110
111         while (*++cp)
112             switch (*cp) {
113             case 'i':
114                 ignoreCase = TRUE;
115                 break;
116
117             case 'h':
118                 tellName = TRUE;
119                 break;
120
121             case 'n':
122                 tellLine = TRUE;
123                 break;
124
125             case 'q':
126                 beQuiet = TRUE;
127                 break;
128
129             default:
130                 usage(grep_usage);
131             }
132     }
133
134     needle = *argv++;
135     argc--;
136
137     if (argc==0) {
138         do_grep( stdin, needle, "stdin", FALSE, ignoreCase, tellLine);
139     } else {
140         while (argc-- > 0) {
141             fileName = *argv++;
142
143             fp = fopen (fileName, "r");
144             if (fp == NULL) {
145                 perror (fileName);
146                 continue;
147             }
148
149             do_grep( fp, needle, fileName, tellName, ignoreCase, tellLine);
150
151             if (ferror (fp))
152                 perror (fileName);
153             fclose (fp);
154         }
155     }
156     exit(match);
157 }
158
159
160 /* END CODE */
161
162