/*
 * 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"

#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[] =
    "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";



/*
 * See if the specified word is found in the specified string.
 */
static int search (const char *string, const char *word, int ignoreCase)
{
    const char *cp1;
    const char *cp2;
    int len;
    int lowFirst;
    int ch1;
    int ch2;

    len = strlen (word);

    if (!ignoreCase) {
	while (TRUE) {
	    string = strchr (string, word[0]);

	    if (string == NULL)
		return FALSE;

	    if (memcmp (string, word, len) == 0)
		return TRUE;

	    string++;
	}
    }

    /* 
     * Here if we need to check case independence.
     * Do the search by lower casing both strings.
     */
    lowFirst = *word;

    if (isupper (lowFirst))
	lowFirst = tolower (lowFirst);

    while (TRUE) {
	while (*string && (*string != lowFirst) &&
	       (!isupper (*string) || (tolower (*string) != lowFirst))) {
	    string++;
	}

	if (*string == '\0')
	    return FALSE;

	cp1 = string;
	cp2 = word;

	do {
	    if (*cp2 == '\0')
		return TRUE;

	    ch1 = *cp1++;

	    if (isupper (ch1))
		ch1 = tolower (ch1);

	    ch2 = *cp2++;

	    if (isupper (ch2))
		ch2 = tolower (ch2);

	}
	while (ch1 == ch2);

	string++;
    }
    return (TRUE);
}


extern int grep_main (int argc, char **argv)
{
    FILE *fp;
    const char *word;
    const char *name;
    const char *cp;
    int tellName;
    int ignoreCase;
    int tellLine;
    long line;
    char buf[BUF_SIZE];

    ignoreCase = FALSE;
    tellLine = FALSE;

    argc--;
    argv++;
    if (argc < 1) {
	fprintf (stderr, "%s", grep_usage);
	return 1;
    }

    if (**argv == '-') {
	argc--;
	cp = *argv++;

	while (*++cp)
	    switch (*cp) {
	    case 'i':
		ignoreCase = TRUE;
		break;

	    case 'n':
		tellLine = TRUE;
		break;

	    default:
		fprintf (stderr, "Unknown option\n");
		return 1;
	    }
    }

    word = *argv++;
    argc--;

    tellName = (argc > 1);

    while (argc-- > 0) {
	name = *argv++;

	fp = fopen (name, "r");

	if (fp == NULL) {
	    perror (name);

	    continue;
	}

	line = 0;

	while (fgets (buf, sizeof (buf), fp)) {
	    line++;

	    cp = &buf[strlen (buf) - 1];

	    if (*cp != '\n')
		fprintf (stderr, "%s: Line too long\n", name);

	    if (search (buf, word, ignoreCase)) {
		if (tellName)
		    printf ("%s: ", name);

		if (tellLine)
		    printf ("%ld: ", line);

		fputs (buf, stdout);
	    }
	}

	if (ferror (fp))
	    perror (name);

	fclose (fp);
    }
    return 0;
}


/* END CODE */


