blob: 0e495ff87e19648c674941a47e80cd144839a568 [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
Eric Andersencc8ed391999-10-05 16:24:54 +00002/*
Eric Andersen3e0fbae1999-10-19 06:02:44 +00003 * Mini grep implementation for busybox
Eric Andersencc8ed391999-10-05 16:24:54 +00004 *
Eric Andersenc4996011999-10-20 22:08:37 +00005 *
Erik Andersen61677fe2000-04-13 01:18:56 +00006 * Copyright (C) 1999,2000 by Lineo, inc.
Eric Andersenc4996011999-10-20 22:08:37 +00007 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
Eric Andersencc8ed391999-10-05 16:24:54 +00008 *
Eric Andersen3e0fbae1999-10-19 06:02:44 +00009 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
Eric Andersencc8ed391999-10-05 16:24:54 +000023 */
24
Erik Andersen3fe2ecf1999-12-21 08:52:04 +000025/*
26 18-Dec-1999 Konstantin Boldyshev <konst@voshod.com>
27
28 + -q option (be quiet)
29 + exit code depending on grep result (TRUE or FALSE)
30 (useful for scripts)
31*/
32
Eric Andersencc8ed391999-10-05 16:24:54 +000033#include "internal.h"
Eric Andersenaa0765e1999-10-22 04:30:20 +000034#include "regexp.h"
Eric Andersencc8ed391999-10-05 16:24:54 +000035#include <stdio.h>
36#include <dirent.h>
37#include <errno.h>
38#include <fcntl.h>
39#include <signal.h>
40#include <time.h>
41#include <ctype.h>
Eric Andersen053b1462000-06-13 06:24:53 +000042#define BB_DECLARE_EXTERN
43#define bb_need_too_few_args
44#include "messages.c"
Eric Andersencc8ed391999-10-05 16:24:54 +000045
Eric Andersene77ae3a1999-10-19 20:03:34 +000046static const char grep_usage[] =
Erik Andersen7ab9c7e2000-05-12 19:41:47 +000047 "grep [OPTIONS]... PATTERN [FILE]...\n"
48#ifndef BB_FEATURE_TRIVIAL_HELP
49 "\nSearch for PATTERN in each FILE or standard input.\n\n"
Erik Andersene49d5ec2000-02-08 19:58:47 +000050 "OPTIONS:\n"
51 "\t-h\tsuppress the prefixing filename on output\n"
52 "\t-i\tignore case distinctions\n"
53 "\t-n\tprint line number with output lines\n"
John Beppuf93a95d2000-04-24 18:07:30 +000054 "\t-q\tbe quiet. Returns 0 if result was found, 1 otherwise\n"
55 "\t-v\tselect non-matching lines\n\n"
Eric Andersenaa0765e1999-10-22 04:30:20 +000056#if defined BB_REGEXP
Eric Andersen74c66ad2000-06-16 19:57:44 +000057 "This version of grep matches full regular expressions.\n";
Eric Andersenaa0765e1999-10-22 04:30:20 +000058#else
Eric Andersen74c66ad2000-06-16 19:57:44 +000059 "This version of grep matches strings (not regular expressions).\n"
Eric Andersenaa0765e1999-10-22 04:30:20 +000060#endif
Erik Andersen7ab9c7e2000-05-12 19:41:47 +000061#endif
62 ;
Eric Andersencc8ed391999-10-05 16:24:54 +000063
Erik Andersen3fe2ecf1999-12-21 08:52:04 +000064static int match = FALSE, beQuiet = FALSE;
Eric Andersenfbb39c81999-11-08 17:00:52 +000065
Erik Andersene49d5ec2000-02-08 19:58:47 +000066static void do_grep(FILE * fp, char *needle, char *fileName, int tellName,
John Beppuf93a95d2000-04-24 18:07:30 +000067 int ignoreCase, int tellLine, int invertSearch)
Eric Andersenfbb39c81999-11-08 17:00:52 +000068{
Erik Andersene49d5ec2000-02-08 19:58:47 +000069 long line = 0;
John Beppuc7ccfc92000-06-12 23:39:04 +000070 char *haystack;
John Beppuf93a95d2000-04-24 18:07:30 +000071 int truth = !invertSearch;
Eric Andersenfbb39c81999-11-08 17:00:52 +000072
John Beppuc7ccfc92000-06-12 23:39:04 +000073 while ((haystack = cstring_lineFromFile(fp))) {
Erik Andersene49d5ec2000-02-08 19:58:47 +000074 line++;
John Beppuf93a95d2000-04-24 18:07:30 +000075 if (find_match(haystack, needle, ignoreCase) == truth) {
Erik Andersene49d5ec2000-02-08 19:58:47 +000076 if (tellName == TRUE)
77 printf("%s:", fileName);
Eric Andersenfbb39c81999-11-08 17:00:52 +000078
Erik Andersene49d5ec2000-02-08 19:58:47 +000079 if (tellLine == TRUE)
80 printf("%ld:", line);
Eric Andersenfbb39c81999-11-08 17:00:52 +000081
Erik Andersene49d5ec2000-02-08 19:58:47 +000082 if (beQuiet == FALSE)
83 fputs(haystack, stdout);
Erik Andersen3fe2ecf1999-12-21 08:52:04 +000084
Erik Andersene49d5ec2000-02-08 19:58:47 +000085 match = TRUE;
86 }
John Beppuc7ccfc92000-06-12 23:39:04 +000087 free(haystack);
Eric Andersenfbb39c81999-11-08 17:00:52 +000088 }
89}
90
Eric Andersencc8ed391999-10-05 16:24:54 +000091
Erik Andersene49d5ec2000-02-08 19:58:47 +000092extern int grep_main(int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +000093{
Erik Andersene49d5ec2000-02-08 19:58:47 +000094 FILE *fp;
Erik Andersene49d5ec2000-02-08 19:58:47 +000095 char *needle;
96 char *fileName;
John Beppuf93a95d2000-04-24 18:07:30 +000097 int tellName = TRUE;
98 int ignoreCase = FALSE;
99 int tellLine = FALSE;
100 int invertSearch = FALSE;
Eric Andersencc8ed391999-10-05 16:24:54 +0000101
Erik Andersene49d5ec2000-02-08 19:58:47 +0000102 if (argc < 1) {
Eric Andersen3e0fbae1999-10-19 06:02:44 +0000103 usage(grep_usage);
Eric Andersenfbb39c81999-11-08 17:00:52 +0000104 }
Eric Andersen053b1462000-06-13 06:24:53 +0000105 argv++;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000106
Eric Andersen053b1462000-06-13 06:24:53 +0000107 while (--argc >= 0 && *argv && (**argv == '-')) {
108 while (*++(*argv)) {
109 switch (**argv) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000110 case 'i':
111 ignoreCase = TRUE;
112 break;
113
114 case 'h':
115 tellName = FALSE;
116 break;
117
118 case 'n':
119 tellLine = TRUE;
120 break;
121
122 case 'q':
123 beQuiet = TRUE;
124 break;
125
John Beppuf93a95d2000-04-24 18:07:30 +0000126 case 'v':
127 invertSearch = TRUE;
128 break;
129
Erik Andersene49d5ec2000-02-08 19:58:47 +0000130 default:
131 usage(grep_usage);
132 }
Eric Andersen053b1462000-06-13 06:24:53 +0000133 }
134 argv++;
135 }
136
137 if (argc == 0 || *argv == NULL) {
138 fatalError(too_few_args, "grep");
Erik Andersene49d5ec2000-02-08 19:58:47 +0000139 }
140
141 needle = *argv++;
142 argc--;
143
144 if (argc == 0) {
John Beppuf93a95d2000-04-24 18:07:30 +0000145 do_grep(stdin, needle, "stdin", FALSE, ignoreCase, tellLine, invertSearch);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000146 } else {
147 /* Never print the filename for just one file */
148 if (argc == 1)
149 tellName = FALSE;
150 while (argc-- > 0) {
151 fileName = *argv++;
152
153 fp = fopen(fileName, "r");
154 if (fp == NULL) {
155 perror(fileName);
156 continue;
157 }
158
John Beppuf93a95d2000-04-24 18:07:30 +0000159 do_grep(fp, needle, fileName, tellName, ignoreCase, tellLine, invertSearch);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000160
161 if (ferror(fp))
162 perror(fileName);
163 fclose(fp);
164 }
165 }
Eric Andersenb6106152000-06-19 17:25:40 +0000166 return(match);
Eric Andersencc8ed391999-10-05 16:24:54 +0000167}
168
169
Eric Andersencc8ed391999-10-05 16:24:54 +0000170/* END CODE */