/*
 * sed.c - very minimalist version of sed
 *
 * Copyright (C) 1999,2000,2001 by Lineo, inc.
 * Written by Mark Whitley <markw@lineo.com>, <markw@codepoet.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

/*
	Supported features and commands in this version of sed:

	 - comments ('#')
	 - address matching: num|/matchstr/[,num|/matchstr/|$]command
	 - commands: (p)rint, (d)elete, (s)ubstitue (with g & I flags)
	 - edit commands: (a)ppend, (i)nsert, (c)hange
	 - file commands: (r)ead
	 - backreferences in substitution expressions (\1, \2...\9)
	 
	 (Note: Specifying an address (range) to match is *optional*; commands
	 default to the whole pattern space if no specific address match was
	 requested.)

	Unsupported features:

	 - transliteration (y/source-chars/dest-chars/) (use 'tr')
	 - no pattern space hold space storing / swapping (x, etc.)
	 - no labels / branching (: label, b, t, and friends)
	 - and lots, lots more.
*/

#include <stdio.h>
#include <unistd.h> /* for getopt() */
#include <regex.h>
#include <string.h> /* for strdup() */
#include <errno.h>
#include <ctype.h> /* for isspace() */
#include <stdlib.h>
#include "busybox.h"

/* externs */
extern void xregcomp(regex_t *preg, const char *regex, int cflags);
extern int optind; /* in unistd.h */
extern char *optarg; /* ditto */

/* options */
static int be_quiet = 0;


struct sed_cmd {


	/* GENERAL FIELDS */
	char delimiter;	    /* The delimiter used to separate regexps */

	/* address storage */
	int beg_line; /* 'sed 1p'   0 == no begining line, apply commands to all lines */
	int end_line; /* 'sed 1,3p' 0 == no end line, use only beginning. -1 == $ */
	regex_t *beg_match; /* sed -e '/match/cmd' */
	regex_t *end_match; /* sed -e '/match/,/end_match/cmd' */

	/* the command */
	char cmd; /* p,d,s (add more at your leisure :-) */


	/* SUBSTITUTION COMMAND SPECIFIC FIELDS */

	/* sed -e 's/sub_match/replace/' */
	regex_t *sub_match;
	char *replace;
	unsigned int num_backrefs:4; /* how many back references (\1..\9) */
			/* Note:  GNU/POSIX sed does not save more than nine backrefs, so
			 * we only use 4 bits to hold the number */
	unsigned int sub_g:1; /* sed -e 's/foo/bar/g' (global) */
	unsigned int sub_p:2; /* sed -e 's/foo/bar/p' (print substitution) */


	/* EDIT COMMAND (a,i,c) SPEICIFIC FIELDS */

	char *editline;


	/* FILE COMMAND (r) SPEICIFIC FIELDS */

	char *filename;
};

/* globals */
static struct sed_cmd *sed_cmds = NULL; /* growable arrary holding a sequence of sed cmds */
static int ncmds = 0; /* number of sed commands */

/*static char *cur_file = NULL;*/ /* file currently being processed XXX: do I need this? */

#ifdef BB_FEATURE_CLEAN_UP
static void destroy_cmd_strs()
{
	if (sed_cmds == NULL)
		return;

	/* destroy all the elements in the array */
	while (--ncmds >= 0) {

		if (sed_cmds[ncmds].beg_match) {
			regfree(sed_cmds[ncmds].beg_match);
			free(sed_cmds[ncmds].beg_match);
		}
		if (sed_cmds[ncmds].end_match) {
			regfree(sed_cmds[ncmds].end_match);
			free(sed_cmds[ncmds].end_match);
		}
		if (sed_cmds[ncmds].sub_match) {
			regfree(sed_cmds[ncmds].sub_match);
			free(sed_cmds[ncmds].sub_match);
		}
		if (sed_cmds[ncmds].replace)
			free(sed_cmds[ncmds].replace);
	}

	/* destroy the array */
	free(sed_cmds);
	sed_cmds = NULL;
}
#endif


/*
 * index_of_next_unescaped_regexp_delim - walks left to right through a string
 * beginning at a specified index and returns the index of the next regular
 * expression delimiter (typically a forward * slash ('/')) not preceeded by 
 * a backslash ('\').
 */
static int index_of_next_unescaped_regexp_delim(struct sed_cmd *sed_cmd, const char *str, int idx)
{
	int bracket = -1;
	int escaped = 0;

	for ( ; str[idx]; idx++) {
		if (bracket != -1) {
			if (str[idx] == ']' && !(bracket == idx - 1 ||
									 (bracket == idx - 2 && str[idx-1] == '^')))
				bracket = -1;
		} else if (escaped)
			escaped = 0;
		else if (str[idx] == '\\')
			escaped = 1;
		else if (str[idx] == '[')
			bracket = idx;
		else if (str[idx] == sed_cmd->delimiter)
			return idx;
	}

	/* if we make it to here, we've hit the end of the string */
	return -1;
}

/*
 * returns the index in the string just past where the address ends.
 */
static int get_address(struct sed_cmd *sed_cmd, const char *str, int *linenum, regex_t **regex)
{
	char *my_str = strdup(str);
	int idx = 0;
	char olddelimiter;
	olddelimiter = sed_cmd->delimiter;
	sed_cmd->delimiter = '/';

	if (isdigit(my_str[idx])) {
		do {
			idx++;
		} while (isdigit(my_str[idx]));
		my_str[idx] = 0;
		*linenum = atoi(my_str);
	}
	else if (my_str[idx] == '$') {
		*linenum = -1;
		idx++;
	}
	else if (my_str[idx] == '/') {
		idx = index_of_next_unescaped_regexp_delim(sed_cmd, my_str, ++idx);
		if (idx == -1)
			error_msg_and_die("unterminated match expression");
		my_str[idx] = '\0';
		*regex = (regex_t *)xmalloc(sizeof(regex_t));
		xregcomp(*regex, my_str+1, REG_NEWLINE);
		idx++; /* so it points to the next character after the last '/' */
	}
	else {
		error_msg("get_address: no address found in string\n"
				"\t(you probably didn't check the string you passed me)");
		idx = -1;
	}

	free(my_str);
	sed_cmd->delimiter = olddelimiter;
	return idx;
}

static int parse_subst_cmd(struct sed_cmd *sed_cmd, const char *substr)
{
	int oldidx, cflags = REG_NEWLINE;
	char *match;
	int idx = 0;
	int j;

	/*
	 * the string that gets passed to this function should look like this:
	 *    s/match/replace/gIp
	 *    ||     |        |||
	 *    mandatory       optional
	 *
	 *    (all three of the '/' slashes are mandatory)
	 */

	/* verify that the 's' is followed by something.  That something
	 * (typically a 'slash') is now our regexp delimiter... */
	if (!substr[++idx])
		error_msg_and_die("bad format in substitution expression");
	else
	    sed_cmd->delimiter=substr[idx];

	/* save the match string */
	oldidx = idx+1;
	idx = index_of_next_unescaped_regexp_delim(sed_cmd, substr, ++idx);
	if (idx == -1)
		error_msg_and_die("bad format in substitution expression");
	match = xstrndup(substr + oldidx, idx - oldidx);

	/* determine the number of back references in the match string */
	/* Note: we compute this here rather than in the do_subst_command()
	 * function to save processor time, at the expense of a little more memory
	 * (4 bits) per sed_cmd */
	
	/* sed_cmd->num_backrefs = 0; */ /* XXX: not needed? --apparently not */ 
	for (j = 0; match[j]; j++) {
		/* GNU/POSIX sed does not save more than nine backrefs */
		if (match[j] == '\\' && match[j+1] == '(' && sed_cmd->num_backrefs <= 9)
			sed_cmd->num_backrefs++;
	}

	/* save the replacement string */
	oldidx = idx+1;
	idx = index_of_next_unescaped_regexp_delim(sed_cmd, substr, ++idx);
	if (idx == -1)
		error_msg_and_die("bad format in substitution expression");
	sed_cmd->replace = xstrndup(substr + oldidx, idx - oldidx);

	/* process the flags */
	while (substr[++idx]) {
		switch (substr[idx]) {
			case 'g':
				sed_cmd->sub_g = 1;
				break;
			case 'I':
				cflags |= REG_ICASE;
				break;
			case 'p':
				sed_cmd->sub_p = 1;
				break;
			default:
				/* any whitespace or semicolon trailing after a s/// is ok */
				if (strchr("; \t\v\n\r", substr[idx]))
					goto out;
				/* else */
				error_msg_and_die("bad option in substitution expression");
		}
	}

out:	
	/* compile the match string into a regex */
	sed_cmd->sub_match = (regex_t *)xmalloc(sizeof(regex_t));
	xregcomp(sed_cmd->sub_match, match, cflags);
	free(match);

	return idx;
}

static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr)
{
	int idx = 0;
	int slashes_eaten = 0;
	char *ptr; /* shorthand */

	/*
	 * the string that gets passed to this function should look like this:
	 *
	 *    need one of these 
	 *    |
	 *    |    this backslash (immediately following the edit command) is mandatory
	 *    |    |
	 *    [aic]\
	 *    TEXT1\
	 *    TEXT2\
	 *    TEXTN
	 *
	 * as soon as we hit a TEXT line that has no trailing '\', we're done.
	 * this means a command like:
	 *
	 * i\
	 * INSERTME
	 *
	 * is a-ok.
	 *
	 */

	if (editstr[1] != '\\' && (editstr[2] != '\n' || editstr[2] != '\r'))
		error_msg_and_die("bad format in edit expression");

	/* store the edit line text */
	/* make editline big enough to accomodate the extra '\n' we will tack on
	 * to the end */
	sed_cmd->editline = xmalloc(strlen(&editstr[3]) + 2);
	strcpy(sed_cmd->editline, &editstr[3]);
	ptr = sed_cmd->editline;

	/* now we need to go through * and: s/\\[\r\n]$/\n/g on the edit line */
	while (ptr[idx]) {
		while (ptr[idx] != '\\' || (ptr[idx+1] != '\n' && ptr[idx+1] != '\r')) {
			idx++;
			if (!ptr[idx]) {
				goto out;
			}
		}
		/* move the newline over the '\' before it (effectively eats the '\') */
		memmove(&ptr[idx], &ptr[idx+1], strlen(&ptr[idx+1]));
		ptr[strlen(ptr)-1] = 0;
		slashes_eaten++;
		/* substitue \r for \n if needed */
		if (ptr[idx] == '\r')
			ptr[idx] = '\n';
	}

out:
	/* this accounts for discrepancies between the modified string and the
	 * original string passed in to this function */
	idx += slashes_eaten;

	/* figure out if we need to add a newline */
	if (ptr[idx-1] != '\n') {
		ptr[idx] = '\n';
		idx++;
	}

	/* terminate string */
	ptr[idx]= 0;
	/* adjust for opening 2 chars [aic]\ */
	idx += 2;

	return idx;
}


static int parse_file_cmd(struct sed_cmd *sed_cmd, const char *filecmdstr)
{
	int idx = 0;
	int filenamelen = 0;

	/*
	 * the string that gets passed to this function should look like this:
	 *    '[ ]filename'
	 *      |  |
	 *      |  a filename
	 *      |
	 *     optional whitespace

	 *   re: the file to be read, the GNU manual says the following: "Note that
	 *   if filename cannot be read, it is treated as if it were an empty file,
	 *   without any error indication." Thus, all of the following commands are
	 *   perfectly leagal:
	 *
	 *   sed -e '1r noexist'
	 *   sed -e '1r ;'
	 *   sed -e '1r'
	 */

	/* the file command may be followed by whitespace; move past it. */
	while (isspace(filecmdstr[++idx]))
		{ ; }
		
	/* the first non-whitespace we get is a filename. the filename ends when we
	 * hit a normal sed command terminator or end of string */
	filenamelen = strcspn(&filecmdstr[idx], "; \n\r\t\v\0");
	sed_cmd->filename = xmalloc(filenamelen + 1);
	safe_strncpy(sed_cmd->filename, &filecmdstr[idx], filenamelen + 1);

	return idx + filenamelen;
}


static char *parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr)
{
	int idx = 0;

	/* parse the command
	 * format is: [addr][,addr]cmd
	 *            |----||-----||-|
	 *            part1 part2  part3
	 */

	/* first part (if present) is an address: either a number or a /regex/ */
	if (isdigit(cmdstr[idx]) || cmdstr[idx] == '/')
		idx = get_address(sed_cmd, cmdstr, &sed_cmd->beg_line, &sed_cmd->beg_match);

	/* second part (if present) will begin with a comma */
	if (cmdstr[idx] == ',')
		idx += get_address(sed_cmd, &cmdstr[++idx], &sed_cmd->end_line, &sed_cmd->end_match);

	/* last part (mandatory) will be a command */
	if (cmdstr[idx] == '\0')
		error_msg_and_die("missing command");
	sed_cmd->cmd = cmdstr[idx];

	/* if it was a single-letter command that takes no arguments (such as 'p'
	 * or 'd') all we need to do is increment the index past that command */
	if (strchr("pd", cmdstr[idx])) {
		idx++;
	}
	/* handle (s)ubstitution command */
	else if (sed_cmd->cmd == 's') {
		idx += parse_subst_cmd(sed_cmd, &cmdstr[idx]);
	}
	/* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */
	else if (strchr("aic", sed_cmd->cmd)) {
		if ((sed_cmd->end_line || sed_cmd->end_match) && sed_cmd->cmd != 'c')
			error_msg_and_die("only a beginning address can be specified for edit commands");
		idx += parse_edit_cmd(sed_cmd, &cmdstr[idx]);
	}
	/* handle file cmds: (r)ead */
	else if (sed_cmd->cmd == 'r') {
		if (sed_cmd->end_line || sed_cmd->end_match)
			error_msg_and_die("Command only uses one address");
		idx += parse_file_cmd(sed_cmd, &cmdstr[idx]);
	}
	else {
		error_msg_and_die("invalid command");
	}

	/* give back whatever's left over */
	return (char *)&cmdstr[idx];
}

static void add_cmd_str(const char *cmdstr)
{
	char *mystr = (char *)cmdstr;

	do {

		/* trim leading whitespace and semicolons */
		memmove(mystr, &mystr[strspn(mystr, "; \n\r\t\v")], strlen(mystr));
		/* if we ate the whole thing, that means there was just trailing
		 * whitespace or a final / no-op semicolon. either way, get out */
		if (strlen(mystr) == 0)
			return;
		/* if this is a comment, jump past it and keep going */
		if (mystr[0] == '#') {
			mystr = strpbrk(mystr, ";\n\r");
			continue;
		}
		/* grow the array */
		sed_cmds = xrealloc(sed_cmds, sizeof(struct sed_cmd) * (++ncmds));
		/* zero new element */
		memset(&sed_cmds[ncmds-1], 0, sizeof(struct sed_cmd));
		/* load command string into new array element, get remainder */
		mystr = parse_cmd_str(&sed_cmds[ncmds-1], mystr);

	} while (mystr && strlen(mystr));
}


static void load_cmd_file(char *filename)
{
	FILE *cmdfile;
	char *line;
	char *nextline;

	cmdfile = xfopen(filename, "r");

	while ((line = get_line_from_file(cmdfile)) != NULL) {
		/* if a line ends with '\' it needs the next line appended to it */
		while (line[strlen(line)-2] == '\\' &&
				(nextline = get_line_from_file(cmdfile)) != NULL) {
			line = xrealloc(line, strlen(line) + strlen(nextline) + 1);
			strcat(line, nextline);
			free(nextline);
		}
		/* eat trailing newline (if any) --if I don't do this, edit commands
		 * (aic) will print an extra newline */
		chomp(line);
		add_cmd_str(line);
		free(line);
	}
}

#define PIPE_MAGIC 0x7f
#define PIPE_GROW 64  
#define pipeputc(c) \
{ if (pipeline[pipeline_idx] == PIPE_MAGIC) { \
	pipeline = xrealloc(pipeline, pipeline_len+PIPE_GROW); \
	memset(pipeline+pipeline_len, 0, PIPE_GROW); \
	pipeline_len += PIPE_GROW; \
	pipeline[pipeline_len-1] = PIPE_MAGIC; } \
	pipeline[pipeline_idx++] = (c); }

static void print_subst_w_backrefs(const char *line, const char *replace, 
	regmatch_t *regmatch, char **pipeline_p, int *pipeline_idx_p, 
	int *pipeline_len_p, int matches)
{
	char *pipeline = *pipeline_p;
	int pipeline_idx = *pipeline_idx_p;
	int pipeline_len = *pipeline_len_p;
	int i;

	/* go through the replacement string */
	for (i = 0; replace[i]; i++) {
		/* if we find a backreference (\1, \2, etc.) print the backref'ed * text */
		if (replace[i] == '\\' && isdigit(replace[i+1])) {
			int j;
			char tmpstr[2];
			int backref;
			++i; /* i now indexes the backref number, instead of the leading slash */
			tmpstr[0] = replace[i];
			tmpstr[1] = 0;
			backref = atoi(tmpstr);
			/* print out the text held in regmatch[backref] */
			if (backref <= matches && regmatch[backref].rm_so != -1)
				for (j = regmatch[backref].rm_so; j < regmatch[backref].rm_eo; j++)
					pipeputc(line[j]);
		}

		/* if we find a backslash escaped character, print the character */
		else if (replace[i] == '\\') {
			++i;
			pipeputc(replace[i]);
		}

		/* if we find an unescaped '&' print out the whole matched text.
		 * fortunately, regmatch[0] contains the indicies to the whole matched
		 * expression (kinda seems like it was designed for just such a
		 * purpose...) */
		else if (replace[i] == '&' && replace[i-1] != '\\') {
			int j;
			for (j = regmatch[0].rm_so; j < regmatch[0].rm_eo; j++)
				pipeputc(line[j]);
		}
		/* nothing special, just print this char of the replacement string to stdout */
		else
			pipeputc(replace[i]);
	}
	*pipeline_p = pipeline;
	*pipeline_idx_p = pipeline_idx;
	*pipeline_len_p = pipeline_len;
}

static int do_subst_command(const struct sed_cmd *sed_cmd, char **line)
{
	char *hackline = *line;
	char *pipeline = 0;
	int pipeline_idx = 0;
	int pipeline_len = 0;
	int altered = 0;
	regmatch_t *regmatch = NULL;

	/* we only proceed if the substitution 'search' expression matches */
	if (regexec(sed_cmd->sub_match, hackline, 0, NULL, 0) == REG_NOMATCH)
		return 0;

	/* whaddaya know, it matched. get the number of back references */
	regmatch = xmalloc(sizeof(regmatch_t) * (sed_cmd->num_backrefs+1));

	/* allocate more PIPE_GROW bytes
	   if replaced string is larger than original */
	pipeline_len = strlen(hackline)+PIPE_GROW;
	pipeline = xmalloc(pipeline_len);
	memset(pipeline, 0, pipeline_len);
	/* buffer magic */
	pipeline[pipeline_len-1] = PIPE_MAGIC;

	/* and now, as long as we've got a line to try matching and if we can match
	 * the search string, we make substitutions */
	while (*hackline && (regexec(sed_cmd->sub_match, hackline,
					sed_cmd->num_backrefs+1, regmatch, 0) == 0) ) {
		int i;

		/* print everything before the match */
		for (i = 0; i < regmatch[0].rm_so; i++)
			pipeputc(hackline[i]);

		/* then print the substitution string */
		print_subst_w_backrefs(hackline, sed_cmd->replace, regmatch, 
				&pipeline, &pipeline_idx, &pipeline_len,
				sed_cmd->num_backrefs);

		/* advance past the match */
		hackline += regmatch[0].rm_eo;
		/* flag that something has changed */
		altered++;

		/* if we're not doing this globally, get out now */
		if (!sed_cmd->sub_g)
			break;
	}

	for (; *hackline; hackline++) pipeputc(*hackline);
	if (pipeline[pipeline_idx] == PIPE_MAGIC) pipeline[pipeline_idx] = 0;

	/* cleanup */
	free(regmatch);

	free(*line);
	*line = pipeline;
	return altered;
}


static void process_file(FILE *file)
{
	char *line = NULL;
	static int linenum = 0; /* GNU sed does not restart counting lines at EOF */
	unsigned int still_in_range = 0;
	int altered;
	int i;

	/* go through every line in the file */
	while ((line = get_line_from_file(file)) != NULL) {

		chomp(line);
		linenum++;
		altered = 0;

		/* for every line, go through all the commands */
		for (i = 0; i < ncmds; i++) {


			/*
			 * entry point into sedding...
			 */
			if (
					/* no range necessary */
					(sed_cmds[i].beg_line == 0 && sed_cmds[i].end_line == 0 &&
					 sed_cmds[i].beg_match == NULL &&
					 sed_cmds[i].end_match == NULL) ||
					/* this line number is the first address we're looking for */
					(sed_cmds[i].beg_line && (sed_cmds[i].beg_line == linenum)) ||
					/* this line matches our first address regex */
					(sed_cmds[i].beg_match && (regexec(sed_cmds[i].beg_match, line, 0, NULL, 0) == 0)) ||
					/* we are currently within the beginning & ending address range */
					still_in_range
			   ) {

				/*
				 * actual sedding
				 */
				switch (sed_cmds[i].cmd) {

					case 'p':
						puts(line);
						break;

					case 'd':
						altered++;
						break;

					case 's':

						/*
						 * Some special cases for 's' printing to make it compliant with
						 * GNU sed printing behavior (aka "The -n | s///p Matrix"):
						 *
						 *    -n ONLY = never print anything regardless of any successful
						 *    substitution
						 *
						 *    s///p ONLY = always print successful substitutions, even if
						 *    the line is going to be printed anyway (line will be printed
						 *    twice).
						 *
						 *    -n AND s///p = print ONLY a successful substitution ONE TIME;
						 *    no other lines are printed - this is the reason why the 'p'
						 *    flag exists in the first place.
						 */

						/* if the user specified that they didn't want anything printed (i.e., a -n
						 * flag and no 'p' flag after the s///), then there's really no point doing
						 * anything here. */
						if (be_quiet && !sed_cmds[i].sub_p)
							break;

						/* we print the line once, unless we were told to be quiet */
						if (!be_quiet)
							altered |= do_subst_command(&sed_cmds[i], &line);

						/* we also print the line if we were given the 'p' flag
						 * (this is quite possibly the second printing) */
						if (sed_cmds[i].sub_p)
							altered |= do_subst_command(&sed_cmds[i], &line);
						if (altered && (i+1 >= ncmds || sed_cmds[i+1].cmd != 's'))
							puts(line);

						break;

					case 'a':
						puts(line);
						fputs(sed_cmds[i].editline, stdout);
						altered++;
						break;

					case 'i':
						fputs(sed_cmds[i].editline, stdout);
						break;

					case 'c':
						/* single-address case */
						if (sed_cmds[i].end_match == NULL && sed_cmds[i].end_line == 0) {
							fputs(sed_cmds[i].editline, stdout);
						}
						/* multi-address case */
						else {
							/* matching text */
							if (sed_cmds[i].end_match && (regexec(sed_cmds[i].end_match, line, 0, NULL, 0) == 0))
								fputs(sed_cmds[i].editline, stdout);
							/* matching line numbers */
							if (sed_cmds[i].end_line > 0 && sed_cmds[i].end_line == linenum)
								fputs(sed_cmds[i].editline, stdout);
						}
						altered++;

						break;

					case 'r': {
								  FILE *outfile;
								  puts(line);
								  outfile = fopen(sed_cmds[i].filename, "r");
								  if (outfile)
									  print_file(outfile);
								  /* else if we couldn't open the output file,
								   * no biggie, just don't print anything */
								  altered++;
							  }
							  break;
				}

				/*
				 * exit point from sedding...
				 */
				if (
					/* this is a single-address command or... */
					(sed_cmds[i].end_line == 0 && sed_cmds[i].end_match == NULL) || (
						/* we were in the middle of our address range (this
						 * isn't the first time through) and.. */
						(still_in_range == 1) && (
							/* this line number is the last address we're looking for or... */
							(sed_cmds[i].end_line && (sed_cmds[i].end_line == linenum)) ||
							/* this line matches our last address regex */
							(sed_cmds[i].end_match && (regexec(sed_cmds[i].end_match, line, 0, NULL, 0) == 0))
						)
					)
				) {
					/* we're out of our address range */
					still_in_range = 0;
				}

				/* didn't hit the exit? then we're still in the middle of an address range */
				else {
					still_in_range = 1;
				}
			}
		}

		/* we will print the line unless we were told to be quiet or if the
		 * line was altered (via a 'd'elete or 's'ubstitution), in which case
		 * the altered line was already printed */
		if (!be_quiet && !altered)
			puts(line);

		free(line);
	}
}

extern int sed_main(int argc, char **argv)
{
	int opt;

#ifdef BB_FEATURE_CLEAN_UP
	/* destroy command strings on exit */
	if (atexit(destroy_cmd_strs) == -1)
		perror_msg_and_die("atexit");
#endif

	/* do normal option parsing */
	while ((opt = getopt(argc, argv, "ne:f:")) > 0) {
		switch (opt) {
			case 'n':
				be_quiet++;
				break;
			case 'e':
				add_cmd_str(optarg);
				break;
			case 'f': 
				load_cmd_file(optarg);
				break;
			default:
				show_usage();
		}
	}

	/* 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 (ncmds == 0) {
		if (argv[optind] == NULL)
			show_usage();
		else {
			add_cmd_str(argv[optind]);
			optind++;
		}
	}


	/* argv[(optind)..(argc-1)] should be names of file to process. If no
	 * files were specified or '-' was specified, take input from stdin.
	 * Otherwise, we process all the files specified. */
	if (argv[optind] == NULL || (strcmp(argv[optind], "-") == 0)) {
		process_file(stdin);
	}
	else {
		int i;
		FILE *file;
		for (i = optind; i < argc; i++) {
			file = fopen(argv[i], "r");
			if (file == NULL) {
				perror_msg("%s", argv[i]);
			} else {
				process_file(file);
				fclose(file);
			}
		}
	}
	
	return 0;
}
