blob: 657bb2570cf05d0f54580a4372c27ae50a57e1a1 [file] [log] [blame]
Eric Andersencc8ed391999-10-05 16:24:54 +00001/*
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"
Eric Andersencc8ed391999-10-05 16:24:54 +000014
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
24const char grep_usage[] =
Eric Andersen596e5461999-10-07 08:30:23 +000025 "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";
Eric Andersencc8ed391999-10-05 16:24:54 +000030
31
32
Eric Andersen3cf52d11999-10-12 22:26:06 +000033/*
34 * See if the specified word is found in the specified string.
35 */
36static 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}
Eric Andersencc8ed391999-10-05 16:24:54 +0000103
104
Eric Andersen596e5461999-10-07 08:30:23 +0000105extern int grep_main (int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +0000106{
Eric Andersen596e5461999-10-07 08:30:23 +0000107 FILE *fp;
108 const char *word;
109 const char *name;
110 const char *cp;
Eric Andersenf811e071999-10-09 00:25:00 +0000111 int tellName;
112 int ignoreCase;
113 int tellLine;
Eric Andersen596e5461999-10-07 08:30:23 +0000114 long line;
115 char buf[BUF_SIZE];
Eric Andersencc8ed391999-10-05 16:24:54 +0000116
Eric Andersen596e5461999-10-07 08:30:23 +0000117 ignoreCase = FALSE;
118 tellLine = FALSE;
Eric Andersencc8ed391999-10-05 16:24:54 +0000119
Eric Andersen596e5461999-10-07 08:30:23 +0000120 argc--;
121 argv++;
122 if (argc < 1) {
123 fprintf (stderr, "%s", grep_usage);
124 return 1;
125 }
126
127 if (**argv == '-') {
Eric Andersencc8ed391999-10-05 16:24:54 +0000128 argc--;
Eric Andersen596e5461999-10-07 08:30:23 +0000129 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");
Eric Andersencc8ed391999-10-05 16:24:54 +0000143 return 1;
Eric Andersen596e5461999-10-07 08:30:23 +0000144 }
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;
Eric Andersencc8ed391999-10-05 16:24:54 +0000161 }
162
Eric Andersen596e5461999-10-07 08:30:23 +0000163 line = 0;
Eric Andersencc8ed391999-10-05 16:24:54 +0000164
Eric Andersen596e5461999-10-07 08:30:23 +0000165 while (fgets (buf, sizeof (buf), fp)) {
166 line++;
Eric Andersencc8ed391999-10-05 16:24:54 +0000167
Eric Andersen596e5461999-10-07 08:30:23 +0000168 cp = &buf[strlen (buf) - 1];
Eric Andersencc8ed391999-10-05 16:24:54 +0000169
Eric Andersen596e5461999-10-07 08:30:23 +0000170 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 }
Eric Andersencc8ed391999-10-05 16:24:54 +0000182 }
183
Eric Andersen596e5461999-10-07 08:30:23 +0000184 if (ferror (fp))
185 perror (name);
Eric Andersencc8ed391999-10-05 16:24:54 +0000186
Eric Andersen596e5461999-10-07 08:30:23 +0000187 fclose (fp);
188 }
189 return 0;
Eric Andersencc8ed391999-10-05 16:24:54 +0000190}
191
192
Eric Andersencc8ed391999-10-05 16:24:54 +0000193/* END CODE */
Eric Andersen3cf52d11999-10-12 22:26:06 +0000194
195