busybox/grep.c

198 lines
3.3 KiB
C
Raw Normal View History

1999-10-05 21:54:54 +05:30
/*
* Copyright (c) 1999 by David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
* The "grep" command, taken from sash.
* This provides basic file searching.
*
* Permission to distribute this code under the GPL has been granted.
* Modified for busybox by Erik Andersen <andersee@debian.org> <andersen@lineo.com>
*/
#include "internal.h"
#ifdef BB_GREP
#include <stdio.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <ctype.h>
const char grep_usage[] =
1999-10-07 14:00:23 +05:30
"Search the input file(s) for lines matching the given pattern.\n"
"\tI search stdin if no files are given.\n"
"\tI can't grok full regular expressions.\n"
"usage: grep [in] PATTERN [FILES]...\n"
"\ti=ignore case, n=list line numbers\n";
1999-10-05 21:54:54 +05:30
1999-10-09 05:55:00 +05:30
static int search (const char *string, const char *word, int ignoreCase);
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
extern int grep_main (int argc, char **argv)
1999-10-05 21:54:54 +05:30
{
1999-10-07 14:00:23 +05:30
FILE *fp;
const char *word;
const char *name;
const char *cp;
1999-10-09 05:55:00 +05:30
int tellName;
int ignoreCase;
int tellLine;
1999-10-07 14:00:23 +05:30
long line;
char buf[BUF_SIZE];
ignoreCase = FALSE;
tellLine = FALSE;
argc--;
argv++;
if (argc < 1) {
fprintf (stderr, "%s", grep_usage);
return 1;
}
if (**argv == '-') {
1999-10-05 21:54:54 +05:30
argc--;
1999-10-07 14:00:23 +05:30
cp = *argv++;
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
while (*++cp)
switch (*cp) {
case 'i':
ignoreCase = TRUE;
break;
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
case 'n':
tellLine = TRUE;
break;
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
default:
fprintf (stderr, "Unknown option\n");
return 1;
}
}
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
word = *argv++;
argc--;
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
tellName = (argc > 1);
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
while (argc-- > 0) {
name = *argv++;
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
fp = fopen (name, "r");
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
if (fp == NULL) {
perror (name);
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
continue;
}
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
line = 0;
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
while (fgets (buf, sizeof (buf), fp)) {
line++;
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
cp = &buf[strlen (buf) - 1];
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
if (*cp != '\n')
fprintf (stderr, "%s: Line too long\n", name);
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
if (search (buf, word, ignoreCase)) {
if (tellName)
printf ("%s: ", name);
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
if (tellLine)
printf ("%ld: ", line);
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
fputs (buf, stdout);
}
1999-10-05 21:54:54 +05:30
}
1999-10-07 14:00:23 +05:30
if (ferror (fp))
perror (name);
fclose (fp);
}
return 0;
1999-10-05 21:54:54 +05:30
}
/*
* See if the specified word is found in the specified string.
*/
1999-10-09 05:55:00 +05:30
static int search (const char *string, const char *word, int ignoreCase)
1999-10-05 21:54:54 +05:30
{
1999-10-07 14:00:23 +05:30
const char *cp1;
const char *cp2;
int len;
int lowFirst;
int ch1;
int ch2;
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
len = strlen (word);
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
if (!ignoreCase) {
while (TRUE) {
string = strchr (string, word[0]);
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
if (string == NULL)
return FALSE;
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
if (memcmp (string, word, len) == 0)
return TRUE;
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
string++;
1999-10-05 21:54:54 +05:30
}
1999-10-07 14:00:23 +05:30
}
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
/*
* Here if we need to check case independence.
* Do the search by lower casing both strings.
*/
lowFirst = *word;
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
if (isupper (lowFirst))
lowFirst = tolower (lowFirst);
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
while (TRUE) {
while (*string && (*string != lowFirst) &&
(!isupper (*string) || (tolower (*string) != lowFirst))) {
string++;
}
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
if (*string == '\0')
return FALSE;
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
cp1 = string;
cp2 = word;
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
do {
if (*cp2 == '\0')
return TRUE;
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
ch1 = *cp1++;
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
if (isupper (ch1))
ch1 = tolower (ch1);
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
ch2 = *cp2++;
1999-10-05 21:54:54 +05:30
1999-10-07 14:00:23 +05:30
if (isupper (ch2))
ch2 = tolower (ch2);
1999-10-05 21:54:54 +05:30
}
1999-10-07 14:00:23 +05:30
while (ch1 == ch2);
string++;
}
return (TRUE);
1999-10-05 21:54:54 +05:30
}
#endif
/* END CODE */