More stuff...
[oweals/busybox.git] / findutils / grep.c
1 /*
2  * Copyright (c) 1999 by David I. Bell
3  * Permission is granted to use, distribute, or modify this source,
4  * provided that this copyright notice remains intact.
5  *
6  * The "grep" command, taken from sash.
7  * This provides basic file searching.
8  *
9  * Permission to distribute this code under the GPL has been granted.
10  * Modified for busybox by Erik Andersen <andersee@debian.org> <andersen@lineo.com>
11  */
12
13 #include "internal.h"
14
15 #include <stdio.h>
16 #include <dirent.h>
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <signal.h>
20 #include <time.h>
21 #include <ctype.h>
22
23
24 const char grep_usage[] =
25     "Search the input file(s) for lines matching the given pattern.\n"
26     "\tI search stdin if no files are given.\n"
27     "\tI can't grok full regular expressions.\n"
28     "usage: grep [in] PATTERN [FILES]...\n"
29     "\ti=ignore case, n=list line numbers\n";
30
31
32
33 /*
34  * See if the specified word is found in the specified string.
35  */
36 static int search (const char *string, const char *word, int ignoreCase)
37 {
38     const char *cp1;
39     const char *cp2;
40     int len;
41     int lowFirst;
42     int ch1;
43     int ch2;
44
45     len = strlen (word);
46
47     if (!ignoreCase) {
48         while (TRUE) {
49             string = strchr (string, word[0]);
50
51             if (string == NULL)
52                 return FALSE;
53
54             if (memcmp (string, word, len) == 0)
55                 return TRUE;
56
57             string++;
58         }
59     }
60
61     /* 
62      * Here if we need to check case independence.
63      * Do the search by lower casing both strings.
64      */
65     lowFirst = *word;
66
67     if (isupper (lowFirst))
68         lowFirst = tolower (lowFirst);
69
70     while (TRUE) {
71         while (*string && (*string != lowFirst) &&
72                (!isupper (*string) || (tolower (*string) != lowFirst))) {
73             string++;
74         }
75
76         if (*string == '\0')
77             return FALSE;
78
79         cp1 = string;
80         cp2 = word;
81
82         do {
83             if (*cp2 == '\0')
84                 return TRUE;
85
86             ch1 = *cp1++;
87
88             if (isupper (ch1))
89                 ch1 = tolower (ch1);
90
91             ch2 = *cp2++;
92
93             if (isupper (ch2))
94                 ch2 = tolower (ch2);
95
96         }
97         while (ch1 == ch2);
98
99         string++;
100     }
101     return (TRUE);
102 }
103
104
105 extern int grep_main (int argc, char **argv)
106 {
107     FILE *fp;
108     const char *word;
109     const char *name;
110     const char *cp;
111     int tellName;
112     int ignoreCase;
113     int tellLine;
114     long line;
115     char buf[BUF_SIZE];
116
117     ignoreCase = FALSE;
118     tellLine = FALSE;
119
120     argc--;
121     argv++;
122     if (argc < 1) {
123         fprintf (stderr, "%s", grep_usage);
124         return 1;
125     }
126
127     if (**argv == '-') {
128         argc--;
129         cp = *argv++;
130
131         while (*++cp)
132             switch (*cp) {
133             case 'i':
134                 ignoreCase = TRUE;
135                 break;
136
137             case 'n':
138                 tellLine = TRUE;
139                 break;
140
141             default:
142                 fprintf (stderr, "Unknown option\n");
143                 return 1;
144             }
145     }
146
147     word = *argv++;
148     argc--;
149
150     tellName = (argc > 1);
151
152     while (argc-- > 0) {
153         name = *argv++;
154
155         fp = fopen (name, "r");
156
157         if (fp == NULL) {
158             perror (name);
159
160             continue;
161         }
162
163         line = 0;
164
165         while (fgets (buf, sizeof (buf), fp)) {
166             line++;
167
168             cp = &buf[strlen (buf) - 1];
169
170             if (*cp != '\n')
171                 fprintf (stderr, "%s: Line too long\n", name);
172
173             if (search (buf, word, ignoreCase)) {
174                 if (tellName)
175                     printf ("%s: ", name);
176
177                 if (tellLine)
178                     printf ("%ld: ", line);
179
180                 fputs (buf, stdout);
181             }
182         }
183
184         if (ferror (fp))
185             perror (name);
186
187         fclose (fp);
188     }
189     return 0;
190 }
191
192
193 /* END CODE */
194
195