/* vi: set sw=4 ts=4: */
/*
 * Mini grep implementation for busybox using libc regex.
 *
 * Copyright (C) 1999,2000,2001 by Lineo, inc. and Mark Whitley
 * Copyright (C) 1999,2000,2001 by Mark Whitley <markw@codepoet.org>
 *
 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
 */
/* BB_AUDIT SUSv3 defects - unsupported option -x.  */
/* BB_AUDIT GNU defects - always acts as -a.  */
/* http://www.opengroup.org/onlinepubs/007904975/utilities/grep.html */
/*
 * 2004,2006 (C) Vladimir Oleynik <dzo@simtreas.ru> -
 * correction "-e pattern1 -e pattern2" logic and more optimizations.
 * precompiled regex
 */
/*
 * (C) 2006 Jac Goudsmit added -o option
 */

#include "busybox.h"
#include "xregex.h"

/* options */
#define OPTSTR_GREP \
	"lnqvscFiHhe:f:Lor" \
	USE_FEATURE_GREP_CONTEXT("A:B:C:") \
	USE_FEATURE_GREP_EGREP_ALIAS("E") \
	USE_DESKTOP("w") \
	"aI"
/* ignored: -a "assume all files to be text" */
/* ignored: -I "assume binary files have no matches" */

enum {
	OPTBIT_l,
	OPTBIT_n,
	OPTBIT_q,
	OPTBIT_v,
	OPTBIT_s,
	OPTBIT_c,
	OPTBIT_F,
	OPTBIT_i,
	OPTBIT_H,
	OPTBIT_h,
	OPTBIT_e,
	OPTBIT_f,
	OPTBIT_L,
	OPTBIT_o,
	OPTBIT_r,
	USE_FEATURE_GREP_CONTEXT(OPTBIT_A ,)
	USE_FEATURE_GREP_CONTEXT(OPTBIT_B ,)
	USE_FEATURE_GREP_CONTEXT(OPTBIT_C ,)
	USE_FEATURE_GREP_CONTEXT(OPTBIT_E ,)
	USE_DESKTOP(             OPTBIT_w ,)
	OPT_l = 1 << OPTBIT_l,
	OPT_n = 1 << OPTBIT_n,
	OPT_q = 1 << OPTBIT_q,
	OPT_v = 1 << OPTBIT_v,
	OPT_s = 1 << OPTBIT_s,
	OPT_c = 1 << OPTBIT_c,
	OPT_F = 1 << OPTBIT_F,
	OPT_i = 1 << OPTBIT_i,
	OPT_H = 1 << OPTBIT_H,
	OPT_h = 1 << OPTBIT_h,
	OPT_e = 1 << OPTBIT_e,
	OPT_f = 1 << OPTBIT_f,
	OPT_L = 1 << OPTBIT_L,
	OPT_o = 1 << OPTBIT_o,
	OPT_r = 1 << OPTBIT_r,
	OPT_A = USE_FEATURE_GREP_CONTEXT((1 << OPTBIT_A)) + 0,
	OPT_B = USE_FEATURE_GREP_CONTEXT((1 << OPTBIT_B)) + 0,
	OPT_C = USE_FEATURE_GREP_CONTEXT((1 << OPTBIT_C)) + 0,
	OPT_E = USE_FEATURE_GREP_CONTEXT((1 << OPTBIT_E)) + 0,
	OPT_w = USE_DESKTOP(             (1 << OPTBIT_w)) + 0,
};

#define PRINT_FILES_WITH_MATCHES (option_mask32 & OPT_l)
#define PRINT_LINE_NUM (option_mask32 & OPT_n)
#define BE_QUIET (option_mask32 & OPT_q)
#define SUPPRESS_ERR_MSGS (option_mask32 & OPT_s)
#define PRINT_MATCH_COUNTS (option_mask32 & OPT_c)
#define FGREP_FLAG (option_mask32 & OPT_F)
#define PRINT_FILES_WITHOUT_MATCHES (option_mask32 & OPT_L)

typedef unsigned char byte_t;

static int reflags;
static byte_t invert_search;
static byte_t print_filename;
static byte_t open_errors;

#if ENABLE_FEATURE_GREP_CONTEXT
static int lines_before;
static int lines_after;
static char **before_buf;
static int last_line_printed;
#endif /* ENABLE_FEATURE_GREP_CONTEXT */

/* globals used internally */
static llist_t *pattern_head;   /* growable list of patterns to match */
static const char *cur_file;    /* the current file we are reading */

typedef struct grep_list_data_t {
	char *pattern;
	regex_t preg;
#define PATTERN_MEM_A 1
#define COMPILED 2
	int flg_mem_alocated_compiled;
} grep_list_data_t;

static void print_line(const char *line, int linenum, char decoration)
{
#if ENABLE_FEATURE_GREP_CONTEXT
	/* possibly print the little '--' separator */
	if ((lines_before || lines_after) && last_line_printed &&
			last_line_printed < linenum - 1) {
		puts("--");
	}
	last_line_printed = linenum;
#endif
	if (print_filename)
		printf("%s%c", cur_file, decoration);
	if (PRINT_LINE_NUM)
		printf("%i%c", linenum, decoration);
	/* Emulate weird GNU grep behavior with -ov */
	if ((option_mask32 & (OPT_v+OPT_o)) != (OPT_v+OPT_o))
		puts(line);
}

static int grep_file(FILE *file)
{
	char *line;
	byte_t ret;
	int linenum = 0;
	int nmatches = 0;
	regmatch_t regmatch;
#if ENABLE_FEATURE_GREP_CONTEXT
	int print_n_lines_after = 0;
	int curpos = 0; /* track where we are in the circular 'before' buffer */
	int idx = 0; /* used for iteration through the circular buffer */
#endif /* ENABLE_FEATURE_GREP_CONTEXT */

	while ((line = xmalloc_getline(file)) != NULL) {
		llist_t *pattern_ptr = pattern_head;
		grep_list_data_t * gl;

		linenum++;
		ret = 0;
		while (pattern_ptr) {
			gl = (grep_list_data_t *)pattern_ptr->data;
			if (FGREP_FLAG) {
				ret = strstr(line, gl->pattern) != NULL;
			} else {
				/*
				 * test for a postitive-assertion match (regexec returns success (0)
				 * and the user did not specify invert search), or a negative-assertion
				 * match (regexec returns failure (REG_NOMATCH) and the user specified
				 * invert search)
				 */
				if (!(gl->flg_mem_alocated_compiled & COMPILED)) {
					gl->flg_mem_alocated_compiled |= COMPILED;
					xregcomp(&(gl->preg), gl->pattern, reflags);
				}
				regmatch.rm_so = 0;
				regmatch.rm_eo = 0;
				if (regexec(&(gl->preg), line, 1, &regmatch, 0) == 0) {
					if (!(option_mask32 & OPT_w))
						ret = 1;
					else {
						char c = ' ';
						if (regmatch.rm_so)
							c = line[regmatch.rm_so - 1];
						if (!isalnum(c) && c != '_') {
							c = line[regmatch.rm_eo];
							if (!c || (!isalnum(c) && c != '_'))
								ret = 1;
						}
					}
				}
			}
			pattern_ptr = pattern_ptr->link;
		} /* while (pattern_ptr) */

		if (ret ^ invert_search) {
			if (PRINT_FILES_WITH_MATCHES || BE_QUIET)
				free(line);

			/* if we found a match but were told to be quiet, stop here */
			if (BE_QUIET || PRINT_FILES_WITHOUT_MATCHES)
				return -1;

			/* keep track of matches */
			nmatches++;

			/* if we're just printing filenames, we stop after the first match */
			if (PRINT_FILES_WITH_MATCHES)
				break;

			/* print the matched line */
			if (PRINT_MATCH_COUNTS == 0) {
#if ENABLE_FEATURE_GREP_CONTEXT
				int prevpos = (curpos == 0) ? lines_before - 1 : curpos - 1;

				/* if we were told to print 'before' lines and there is at least
				 * one line in the circular buffer, print them */
				if (lines_before && before_buf[prevpos] != NULL) {
					int first_buf_entry_line_num = linenum - lines_before;

					/* advance to the first entry in the circular buffer, and
					 * figure out the line number is of the first line in the
					 * buffer */
					idx = curpos;
					while (before_buf[idx] == NULL) {
						idx = (idx + 1) % lines_before;
						first_buf_entry_line_num++;
					}

					/* now print each line in the buffer, clearing them as we go */
					while (before_buf[idx] != NULL) {
						print_line(before_buf[idx], first_buf_entry_line_num, '-');
						free(before_buf[idx]);
						before_buf[idx] = NULL;
						idx = (idx + 1) % lines_before;
						first_buf_entry_line_num++;
					}
				}

				/* make a note that we need to print 'after' lines */
				print_n_lines_after = lines_after;
#endif
				if (option_mask32 & OPT_o) {
					line[regmatch.rm_eo] = '\0';
					print_line(line + regmatch.rm_so, linenum, ':');
				} else {
					print_line(line, linenum, ':');
				}
			}
		}
#if ENABLE_FEATURE_GREP_CONTEXT
		else { /* no match */
			/* Add the line to the circular 'before' buffer */
			if (lines_before) {
				free(before_buf[curpos]);
				before_buf[curpos] = xstrdup(line);
				curpos = (curpos + 1) % lines_before;
			}
		}

		/* if we need to print some context lines after the last match, do so */
		if (print_n_lines_after && (last_line_printed != linenum)) {
			print_line(line, linenum, '-');
			print_n_lines_after--;
		}
#endif /* ENABLE_FEATURE_GREP_CONTEXT */
		free(line);
	}

	/* special-case file post-processing for options where we don't print line
	 * matches, just filenames and possibly match counts */

	/* grep -c: print [filename:]count, even if count is zero */
	if (PRINT_MATCH_COUNTS) {
		if (print_filename)
			printf("%s:", cur_file);
		printf("%d\n", nmatches);
	}

	/* grep -l: print just the filename, but only if we grepped the line in the file  */
	if (PRINT_FILES_WITH_MATCHES && nmatches > 0) {
		puts(cur_file);
	}

	/* grep -L: print just the filename, but only if we didn't grep the line in the file  */
	if (PRINT_FILES_WITHOUT_MATCHES && nmatches == 0) {
		puts(cur_file);
	}

	return nmatches;
}

#if ENABLE_FEATURE_CLEAN_UP
#define new_grep_list_data(p, m) add_grep_list_data(p, m)
static char * add_grep_list_data(char *pattern, int flg_used_mem)
#else
#define new_grep_list_data(p, m) add_grep_list_data(p)
static char * add_grep_list_data(char *pattern)
#endif
{
	grep_list_data_t *gl = xmalloc(sizeof(grep_list_data_t));
	gl->pattern = pattern;
#if ENABLE_FEATURE_CLEAN_UP
	gl->flg_mem_alocated_compiled = flg_used_mem;
#else
	gl->flg_mem_alocated_compiled = 0;
#endif
	return (char *)gl;
}


static void load_regexes_from_file(llist_t *fopt)
{
	char *line;
	FILE *f;

	while (fopt) {
		llist_t *cur = fopt;
		char *ffile = cur->data;

		fopt = cur->link;
		free(cur);
		f = xfopen(ffile, "r");
		while ((line = xmalloc_getline(f)) != NULL) {
			llist_add_to(&pattern_head,
				new_grep_list_data(line, PATTERN_MEM_A));
		}
	}
}

static int file_action_grep(const char *filename, struct stat *statbuf, void* matched, int depth)
{
	FILE *file = fopen(filename, "r");
	if (file == NULL) {
		if (!SUPPRESS_ERR_MSGS)
			bb_perror_msg("%s", cur_file);
		open_errors = 1;
		return 0;
	}
	cur_file = filename;
	*(int*)matched += grep_file(file);
	fclose(file);
	return 1;
}

static int grep_dir(const char *dir)
{
	int matched = 0;
	recursive_action(dir,
		/* recurse= */ 1,
		/* followLinks= */ 0,
		/* depthFirst= */ 1,
		/* fileAction= */ file_action_grep,
		/* dirAction= */ NULL,
		/* userData= */ &matched,
		/* depth= */ 0);
	return matched;
}

int grep_main(int argc, char **argv);
int grep_main(int argc, char **argv)
{
	FILE *file;
	int matched;
	llist_t *fopt = NULL;

	/* do normal option parsing */
#if ENABLE_FEATURE_GREP_CONTEXT
	char *slines_after;
	char *slines_before;
	char *Copt;

	opt_complementary = "H-h:e::f::C-AB";
	getopt32(argc, argv,
		OPTSTR_GREP,
		&pattern_head, &fopt,
		&slines_after, &slines_before, &Copt);

	if (option_mask32 & OPT_C) {
		/* -C unsets prev -A and -B, but following -A or -B
		   may override it */
		if (!(option_mask32 & OPT_A)) /* not overridden */
			slines_after = Copt;
		if (!(option_mask32 & OPT_B)) /* not overridden */
			slines_before = Copt;
		option_mask32 |= OPT_A|OPT_B; /* for parser */
	}
	if (option_mask32 & OPT_A) {
		lines_after = xatoi_u(slines_after);
	}
	if (option_mask32 & OPT_B) {
		lines_before = xatoi_u(slines_before);
	}
	/* sanity checks */
	if (option_mask32 & (OPT_c|OPT_q|OPT_l|OPT_L)) {
		option_mask32 &= ~OPT_n;
		lines_before = 0;
		lines_after = 0;
	} else if (lines_before > 0)
		before_buf = xzalloc(lines_before * sizeof(char *));
#else
	/* with auto sanity checks */
	opt_complementary = "H-h:e::f::c-n:q-n:l-n";
	getopt32(argc, argv, OPTSTR_GREP,
		&pattern_head, &fopt);
#endif
	invert_search = ((option_mask32 & OPT_v) != 0); /* 0 | 1 */

	if (pattern_head != NULL) {
		/* convert char *argv[] to grep_list_data_t */
		llist_t *cur;

		for (cur = pattern_head; cur; cur = cur->link)
			cur->data = new_grep_list_data(cur->data, 0);
	}
	if (option_mask32 & OPT_f)
		load_regexes_from_file(fopt);

	if (ENABLE_FEATURE_GREP_FGREP_ALIAS && applet_name[0] == 'f')
		option_mask32 |= OPT_F;

	if (!(option_mask32 & (OPT_o | OPT_w)))
		reflags = REG_NOSUB;

	if (ENABLE_FEATURE_GREP_EGREP_ALIAS &&
			(applet_name[0] == 'e' || (option_mask32 & OPT_E)))
		reflags |= REG_EXTENDED;

	if (option_mask32 & OPT_i)
		reflags |= REG_ICASE;

	argv += optind;
	argc -= optind;

	/* if we didn't get a pattern from a -e and no command file was specified,
	 * argv[optind] should be the pattern. no pattern, no worky */
	if (pattern_head == NULL) {
		char *pattern;
		if (*argv == NULL)
			bb_show_usage();
		pattern = new_grep_list_data(*argv++, 0);
		llist_add_to(&pattern_head, pattern);
		argc--;
	}

	/* argv[(optind)..(argc-1)] should be names of file to grep through. If
	 * there is more than one file to grep, we will print the filenames. */
	if (argc > 1)
		print_filename = 1;
	/* -H / -h of course override */
	if (option_mask32 & OPT_H)
		print_filename = 1;
	if (option_mask32 & OPT_h)
		print_filename = 0;

	/* If no files were specified, or '-' was specified, take input from
	 * stdin. Otherwise, we grep through all the files specified. */
	if (argc == 0)
		argc++;
	matched = 0;
	while (argc--) {
		cur_file = *argv++;
		file = stdin;
		if (!cur_file || (*cur_file == '-' && !cur_file[1])) {
			cur_file = "(standard input)";
		} else {
			if (option_mask32 & OPT_r) {
				struct stat st;
				if (stat(cur_file, &st) == 0 && S_ISDIR(st.st_mode)) {
					if (!(option_mask32 & OPT_h))
						print_filename = 1;
					matched += grep_dir(cur_file);
					goto grep_done;
				}
			}
			/* else: fopen(dir) will succeed, but reading won't */
			file = fopen(cur_file, "r");
			if (file == NULL) {
				if (!SUPPRESS_ERR_MSGS)
					bb_perror_msg("%s", cur_file);
				open_errors = 1;
				continue;
			}
		}
		matched += grep_file(file);
		fclose_if_not_stdin(file);
 grep_done:
		if (matched < 0) {
			/* we found a match but were told to be quiet, stop here and
			* return success */
			break;
		}
	}

	/* destroy all the elments in the pattern list */
	if (ENABLE_FEATURE_CLEAN_UP) {
		while (pattern_head) {
			llist_t *pattern_head_ptr = pattern_head;
			grep_list_data_t *gl =
				(grep_list_data_t *)pattern_head_ptr->data;

			pattern_head = pattern_head->link;
			if ((gl->flg_mem_alocated_compiled & PATTERN_MEM_A))
				free(gl->pattern);
			if ((gl->flg_mem_alocated_compiled & COMPILED))
				regfree(&(gl->preg));
			free(pattern_head_ptr);
		}
	}
	/* 0 = success, 1 = failed, 2 = error */
	/* If the -q option is specified, the exit status shall be zero
	 * if an input line is selected, even if an error was detected.  */
	if (BE_QUIET && matched)
		return 0;
	if (open_errors)
		return 2;
	return !matched; /* invert return value 0 = success, 1 = failed */
}
