]> err.no Git - sash/blob - cmd_grep.c
Stop stripping during build. Also thanks to Helmut Grohne. Closes: #852771
[sash] / cmd_grep.c
1 /*
2  * Copyright (c) 2014 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" built-in command.
7  */
8
9 #include <ctype.h>
10
11 #include "sash.h"
12
13
14 static  BOOL    search
15         (const char * string, const char * word, BOOL ignoreCase);
16
17
18 int
19 do_grep(int argc, const char ** argv)
20 {
21         FILE *          fp;
22         const char *    word;
23         const char *    name;
24         const char *    cp;
25         BOOL            tellName;
26         BOOL            ignoreCase;
27         BOOL            tellLine;
28         long            line;
29         char            buf[BUF_SIZE];
30         int             r;
31
32         r = 1;
33         ignoreCase = FALSE;
34         tellLine = FALSE;
35
36         argc--;
37         argv++;
38
39         if (**argv == '-')
40         {
41                 argc--;
42                 cp = *argv++;
43
44                 while (*++cp) switch (*cp)
45                 {
46                         case 'i':
47                                 ignoreCase = TRUE;
48                                 break;
49
50                         case 'n':
51                                 tellLine = TRUE;
52                                 break;
53
54                         default:
55                                 fprintf(stderr, "Unknown option\n");
56
57                                 return 1;
58                 }
59         }
60
61         word = *argv++;
62         argc--;
63
64         tellName = (argc > 1);
65
66         while (argc-- > 0)
67         {
68                 name = *argv++;
69
70                 fp = fopen(name, "r");
71
72                 if (fp == NULL)
73                 {
74                         perror(name);
75                         r = 1;
76
77                         continue;
78                 }
79
80                 line = 0;
81
82                 while (fgets(buf, sizeof(buf), fp))
83                 {
84                         if (intFlag)
85                         {
86                                 fclose(fp);
87
88                                 return 1;
89                         }
90
91                         line++;
92
93                         cp = &buf[strlen(buf) - 1];
94
95                         if (*cp != '\n')
96                                 fprintf(stderr, "%s: Line too long\n", name);
97
98                         if (search(buf, word, ignoreCase))
99                         {
100                                 r = 0;
101                                 if (tellName)
102                                         printf("%s: ", name);
103
104                                 if (tellLine)
105                                         printf("%ld: ", line);
106
107                                 fputs(buf, stdout);
108                         }
109                 }
110
111                 if (ferror(fp))
112                         perror(name);
113
114                 fclose(fp);
115         }
116
117         return r;
118 }
119
120
121 /*
122  * See if the specified word is found in the specified string.
123  */
124 static BOOL
125 search(const char * string, const char * word, BOOL ignoreCase)
126 {
127         const char *    cp1;
128         const char *    cp2;
129         int             len;
130         int             lowFirst;
131         int             ch1;
132         int             ch2;
133
134         len = strlen(word);
135
136         if (!ignoreCase)
137         {
138                 while (TRUE)
139                 {
140                         string = strchr(string, word[0]);
141
142                         if (string == NULL)
143                                 return FALSE;
144
145                         if (memcmp(string, word, len) == 0)
146                                 return TRUE;
147
148                         string++;
149                 }
150         }
151
152         /*
153          * Here if we need to check case independence.
154          * Do the search by lower casing both strings.
155          */
156         lowFirst = *word;
157
158         if (isupper(lowFirst))
159                 lowFirst = tolower(lowFirst);
160
161         while (TRUE)
162         {
163                 while (*string && (*string != lowFirst) &&
164                         (!isupper(*string) || (tolower(*string) != lowFirst)))
165                 {
166                         string++;
167                 }
168
169                 if (*string == '\0')
170                         return FALSE;
171
172                 cp1 = string;
173                 cp2 = word;
174
175                 do
176                 {
177                         if (*cp2 == '\0')
178                                 return TRUE;
179
180                         ch1 = *cp1++;
181
182                         if (isupper(ch1))
183                                 ch1 = tolower(ch1);
184
185                         ch2 = *cp2++;
186
187                         if (isupper(ch2))
188                                 ch2 = tolower(ch2);
189
190                 }
191                 while (ch1 == ch2);
192
193                 string++;
194         }
195 }
196
197 /* END CODE */