/*
 * sed.c - very minimalist version of sed
 *
 * Copyright (C) 1999,2000,2001 by Lineo, inc. and Mark Whitley
 * Copyright (C) 1999,2000,2001 by Mark Whitley <markw@codepoet.org>
 * Copyright (C) 2002  Matt Kraai
 * Copyright (C) 2003 by Glenn McGrath <bug1@optushome.com.au>
 *
 * 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)
	 - grouped commands: {cmd1;cmd2}
	 - transliteration (y/source-chars/dest-chars/)
	 - pattern space hold space storing / swapping (g, h, x)
	 - labels / branching (: label, b, t)

	 (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:

	 - GNU extensions
	 - and more.

	Bugs:
	
	 - lots

	Reference http://www.opengroup.org/onlinepubs/007904975/utilities/sed.html
*/

#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"

typedef struct sed_cmd_s {
	/* Order by alignment requirements */

	/* address storage */
	regex_t *beg_match;	/* sed -e '/match/cmd' */
	regex_t *end_match;	/* sed -e '/match/,/end_match/cmd' */

	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 == $ */

	/* inversion flag */
	int invert;			/* the '!' after the address */

	/* Runtime flag no not if the current command match's */
	int still_in_range;

	/* SUBSTITUTION COMMAND SPECIFIC FIELDS */

	/* sed -e 's/sub_match/replace/' */
	regex_t *sub_match;
	char *replace;

	/* EDIT COMMAND (a,i,c) SPECIFIC FIELDS */
	char *editline;

	/* FILE COMMAND (r) SPECIFIC FIELDS */
	char *filename;

	/* SUBSTITUTION COMMAND SPECIFIC FIELDS */

	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:1;	/* sed -e 's/foo/bar/p' (print substitution) */

	/* TRANSLATE COMMAND */
	char *translate;

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

	/* Branch commands */
	char *label;

	/* next command in list (sequential list of specified commands) */
	struct sed_cmd_s *next;

} sed_cmd_t;


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

/* globals */
/* options */
static int be_quiet = 0;
static const char bad_format_in_subst[] =
	"bad format in substitution expression";

/* linked list of sed commands */
static sed_cmd_t sed_cmd_head;
static sed_cmd_t *sed_cmd_tail = &sed_cmd_head;

const char *const semicolon_whitespace = "; \n\r\t\v\0";
static regex_t *previous_regex_ptr = NULL;


#ifdef CONFIG_FEATURE_CLEAN_UP
static void destroy_cmd_strs(void)
{
	sed_cmd_t *sed_cmd = sed_cmd_head.next;

	while (sed_cmd) {
		sed_cmd_t *sed_cmd_next = sed_cmd->next;

		if (sed_cmd->beg_match) {
			regfree(sed_cmd->beg_match);
			free(sed_cmd->beg_match);
		}
		if (sed_cmd->end_match) {
			regfree(sed_cmd->end_match);
			free(sed_cmd->end_match);
		}
		if (sed_cmd->sub_match) {
			regfree(sed_cmd->sub_match);
			free(sed_cmd->sub_match);
		}
		free(sed_cmd->replace);
		free(sed_cmd->editline);
		free(sed_cmd->filename);
		free(sed_cmd->translate);
		free(sed_cmd->label);
		free(sed_cmd);
		sed_cmd = sed_cmd_next;
	}
}
#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(const char delimiter,
	const char *str)
{
	int bracket = -1;
	int escaped = 0;
	int idx = 0;
	char ch;

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

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

/*
 *  Returns the index of the third delimiter
 */
static int parse_regex_delim(const char *cmdstr, char **match, char **replace)
{
	const char *cmdstr_ptr = cmdstr;
	char delimiter;
	int idx = 0;

	/* verify that the 's' or 'y' is followed by something.  That something
	 * (typically a 'slash') is now our regexp delimiter... */
	if (*cmdstr == '\0')
		bb_error_msg_and_die(bad_format_in_subst);
	else
		delimiter = *cmdstr_ptr;

	cmdstr_ptr++;

	/* save the match string */
	idx = index_of_next_unescaped_regexp_delim(delimiter, cmdstr_ptr);
	if (idx == -1) {
		bb_error_msg_and_die(bad_format_in_subst);
	}
	*match = bb_xstrndup(cmdstr_ptr, idx);

	/* save the replacement string */
	cmdstr_ptr += idx + 1;
	idx = index_of_next_unescaped_regexp_delim(delimiter, cmdstr_ptr);
	if (idx == -1) {
		bb_error_msg_and_die(bad_format_in_subst);
	}
	*replace = bb_xstrndup(cmdstr_ptr, idx);

	return ((cmdstr_ptr - cmdstr) + idx);
}

/*
 * returns the index in the string just past where the address ends.
 */
static int get_address(char *my_str, int *linenum, regex_t ** regex)
{
	char *pos=my_str;

	if (isdigit(*my_str)) {
		*linenum = strtol(my_str, &pos, 10);
		/* endstr shouldnt ever equal NULL */
	} else if (*my_str == '$') {
		*linenum = -1;
		pos++;
	} else if (*my_str == '/' || *my_str == '\\') {
		int next, idx_start = 1;
		char delimiter;

		delimiter = '/';
		if (*my_str == '\\') {
			idx_start++;
			delimiter = *(++pos);
		}
		next = index_of_next_unescaped_regexp_delim(delimiter, ++pos);
		if (next == -1) {
			bb_error_msg_and_die("unterminated match expression");
		}
		pos += next;
		*pos = '\0';

		*regex = (regex_t *) xmalloc(sizeof(regex_t));
		xregcomp(*regex, my_str + idx_start, REG_NEWLINE);
		pos++;			/* so it points to the next character after the last '/' */
	}
	return pos - my_str;
}

static int parse_subst_cmd(sed_cmd_t * const sed_cmd, const char *substr)
{
	int cflags = 0;
	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)
	 */
	idx = parse_regex_delim(substr, &match, &sed_cmd->replace);

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

	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++;
	}

	/* process the flags */
	while (substr[++idx]) {
		switch (substr[idx]) {
		case 'g':
			if (match[0] != '^') {
				sed_cmd->sub_g = 1;
			}
			break;
			/* Hmm, i dont see the I option mentioned in the standard */
		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(semicolon_whitespace, substr[idx]))
				goto out;
			/* else */
			bb_error_msg_and_die("bad option in substitution expression");
		}
	}

  out:
	/* compile the match string into a regex */
	if (*match != '\0') {
		/* If match is empty, we use last regex used at runtime */
		sed_cmd->sub_match = (regex_t *) xmalloc(sizeof(regex_t));
		xregcomp(sed_cmd->sub_match, match, cflags);
	}
	free(match);

	return idx;
}

static void replace_slash_n(char *string)
{
	char *dest;

	for (dest = string; *string; string++, dest++) {
		if ((string[0] == '\\') && (string[1] == 'n')) {
			*dest = '\n';
			string++;
		} else {
			*dest = *string;
		}
	}
	*dest=0;
}

static int parse_translate_cmd(sed_cmd_t * const sed_cmd, const char *cmdstr)
{
	char *match;
	char *replace;
	int idx;
	int i;

	idx = parse_regex_delim(cmdstr, &match, &replace);
	replace_slash_n(match);
	replace_slash_n(replace);
	sed_cmd->translate = xcalloc(1, (strlen(match) + 1) * 2);
	for (i = 0; (match[i] != 0) && (replace[i] != 0); i++) {
		sed_cmd->translate[i * 2] = match[i];
		sed_cmd->translate[(i * 2) + 1] = replace[i];
	}
	return (idx + 1);
}

static int parse_edit_cmd(sed_cmd_t * sed_cmd, const char *editstr)
{
	int i, j;

	/*
	 * 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 != '\\') || ((editstr[1] != '\n') && (editstr[1] != '\r'))) {
		bb_error_msg_and_die("bad format in edit expression");
	}

	/* store the edit line text */
	sed_cmd->editline = xmalloc(strlen(&editstr[2]) + 2);
	for (i = 2, j = 0;
		editstr[i] != '\0' && strchr("\r\n", editstr[i]) == NULL; i++, j++) {
		if ((editstr[i] == '\\') && strchr("\n\r", editstr[i + 1]) != NULL) {
			sed_cmd->editline[j] = '\n';
			i++;
		} else
			sed_cmd->editline[j] = editstr[i];
	}

	/* figure out if we need to add a newline */
	if (sed_cmd->editline[j - 1] != '\n')
		sed_cmd->editline[j++] = '\n';

	/* terminate string */
	sed_cmd->editline[j] = '\0';

	return i;
}


static int parse_file_cmd(sed_cmd_t * 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 legal:
	 *
	 *   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], semicolon_whitespace);
	sed_cmd->filename = xmalloc(filenamelen + 1);
	safe_strncpy(sed_cmd->filename, &filecmdstr[idx], filenamelen + 1);
	return idx + filenamelen;
}

/*
 *  Process the commands arguments
 */
static char *parse_cmd_str(sed_cmd_t * sed_cmd, char *cmdstr)
{
	/* handle (s)ubstitution command */
	if (sed_cmd->cmd == 's') {
		cmdstr += parse_subst_cmd(sed_cmd, cmdstr);
	}
	/* 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')
			bb_error_msg_and_die
				("only a beginning address can be specified for edit commands");
		cmdstr += parse_edit_cmd(sed_cmd, cmdstr);
	}
	/* handle file cmds: (r)ead */
	else if (sed_cmd->cmd == 'r') {
		if (sed_cmd->end_line || sed_cmd->end_match)
			bb_error_msg_and_die("Command only uses one address");
		cmdstr += parse_file_cmd(sed_cmd, cmdstr);
	}
	/* handle branch commands */
	else if (strchr(":bt", sed_cmd->cmd)) {
		int length;

		cmdstr += strspn(cmdstr, " ");
		length = strcspn(cmdstr, semicolon_whitespace);
		if (length) {
			sed_cmd->label = strndup(cmdstr, length);
			cmdstr += length;
		}
	}
	/* translation command */
	else if (sed_cmd->cmd == 'y') {
		cmdstr += parse_translate_cmd(sed_cmd, cmdstr);
	}
	/* if it wasnt a single-letter command that takes no arguments
	 * then it must be an invalid command.
	 */
	else if (strchr("dgGhHnNpPqx={}", sed_cmd->cmd) == 0) {
		bb_error_msg_and_die("Unsupported command %c", sed_cmd->cmd);
	}

	/* give back whatever's left over */
	return (cmdstr);
}

static char *add_cmd(char *cmdstr)
{
	sed_cmd_t *sed_cmd;

	/* Skip over leading whitespace and semicolons */
	cmdstr += strspn(cmdstr, semicolon_whitespace);

	/* if we ate the whole thing, that means there was just trailing
	 * whitespace or a final / no-op semicolon. either way, get out */
	if (*cmdstr == '\0') {
		return (NULL);
	}

	/* if this is a comment, jump past it and keep going */
	if (*cmdstr == '#') {
		/* "#n" is the same as using -n on the command line */
		if (cmdstr[1] == 'n') {
			be_quiet++;
		}
		return (strpbrk(cmdstr, "\n\r"));
	}

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

	sed_cmd = xcalloc(1, sizeof(sed_cmd_t));

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

	/* second part (if present) will begin with a comma */
	if (*cmdstr == ',') {
		int idx;

		cmdstr++;
		idx = get_address(cmdstr, &sed_cmd->end_line, &sed_cmd->end_match);
		if (idx == 0) {
			bb_error_msg_and_die("get_address: no address found in string\n"
				"\t(you probably didn't check the string you passed me)");
		}
		cmdstr += idx;
	}

	/* skip whitespace before the command */
	while (isspace(*cmdstr)) {
		cmdstr++;
	}

	/* there my be the inversion flag between part2 and part3 */
	if (*cmdstr == '!') {
		sed_cmd->invert = 1;
		cmdstr++;

#ifdef SED_FEATURE_STRICT_CHECKING
		/* According to the spec
		 * It is unspecified whether <blank>s can follow a '!' character,
		 * and conforming applications shall not follow a '!' character
		 * with <blank>s.
		 */
		if (isblank(cmdstr[idx]) {
			bb_error_msg_and_die("blank follows '!'");}
#else
		/* skip whitespace before the command */
		while (isspace(*cmdstr)) {
			cmdstr++;
		}
#endif
	}

	/* last part (mandatory) will be a command */
	if (*cmdstr == '\0')
		bb_error_msg_and_die("missing command");

	sed_cmd->cmd = *cmdstr;
	cmdstr++;

	cmdstr = parse_cmd_str(sed_cmd, cmdstr);

	/* Add the command to the command array */
	sed_cmd_tail->next = sed_cmd;
	sed_cmd_tail = sed_cmd_tail->next;

	return (cmdstr);
}

static void add_cmd_str(char *cmdstr)
{
#ifdef CONFIG_FEATURE_SED_EMBEDED_NEWLINE
	char *cmdstr_ptr = cmdstr;

	/* HACK: convert "\n" to match tranlated '\n' string */
	while ((cmdstr_ptr = strstr(cmdstr_ptr, "\\n")) != NULL) {
		cmdstr = xrealloc(cmdstr, strlen(cmdstr) + 2);
		cmdstr_ptr = strstr(cmdstr, "\\n");
		memmove(cmdstr_ptr + 1, cmdstr_ptr, strlen(cmdstr_ptr) + 1);
		cmdstr_ptr[0] = '\\';
		cmdstr_ptr += 3;
	}
#endif
	do {
		cmdstr = add_cmd(cmdstr);
	} while (cmdstr && strlen(cmdstr));
}


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

	cmdfile = bb_xfopen(filename, "r");

	while ((line = bb_get_line_from_file(cmdfile)) != NULL) {
		/* if a line ends with '\' it needs the next line appended to it */
		while (((e = last_char_is(line, '\n')) != NULL)
			&& (e > line) && (e[-1] == '\\')
			&& ((nextline = bb_get_line_from_file(cmdfile)) != NULL)) {
			line = xrealloc(line, (e - line) + 1 + 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);
	}
}

struct pipeline {
	char *buf;
	int idx;
	int len;
};

#define PIPE_MAGIC 0x7f
#define PIPE_GROW 64

void pipe_putc(struct pipeline *const pipeline, char c)
{
	if (pipeline->buf[pipeline->idx] == PIPE_MAGIC) {
		pipeline->buf = xrealloc(pipeline->buf, pipeline->len + PIPE_GROW);
		memset(pipeline->buf + pipeline->len, 0, PIPE_GROW);
		pipeline->len += PIPE_GROW;
		pipeline->buf[pipeline->len - 1] = PIPE_MAGIC;
	}
	pipeline->buf[pipeline->idx++] = (c);
}

#define pipeputc(c) 	pipe_putc(pipeline, c)

static void print_subst_w_backrefs(const char *line, const char *replace,
	regmatch_t * regmatch, struct pipeline *const pipeline, int matches)
{
	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] == '&') {
			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]);
	}
}

static int do_subst_command(sed_cmd_t * sed_cmd, char **line)
{
	char *hackline = *line;
	struct pipeline thepipe = { NULL, 0, 0 };
	struct pipeline *const pipeline = &thepipe;
	int altered = 0;
	int result;
	regmatch_t *regmatch = NULL;
	regex_t *current_regex;

	if (sed_cmd->sub_match == NULL) {
		current_regex = previous_regex_ptr;
	} else {
		previous_regex_ptr = current_regex = sed_cmd->sub_match;
	}
	result = regexec(current_regex, hackline, 0, NULL, 0);

	/* we only proceed if the substitution 'search' expression matches */
	if (result == 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 */
	thepipe.len = strlen(hackline) + PIPE_GROW;
	thepipe.buf = xcalloc(1, thepipe.len);
	/* buffer magic */
	thepipe.buf[thepipe.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 || !altered)
		&& (regexec(current_regex, hackline, sed_cmd->num_backrefs + 1,
				regmatch, 0) != REG_NOMATCH)) {
		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,
			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 (thepipe.buf[thepipe.idx] == PIPE_MAGIC)
		thepipe.buf[thepipe.idx] = 0;

	/* cleanup */
	free(regmatch);

	free(*line);
	*line = thepipe.buf;
	return altered;
}

static sed_cmd_t *branch_to(const char *label)
{
	sed_cmd_t *sed_cmd;

	for (sed_cmd = sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) {
		if ((sed_cmd->cmd == ':') && (sed_cmd->label) && (strcmp(sed_cmd->label, label) == 0)) {
			return (sed_cmd);
		}
	}
	bb_error_msg_and_die("Can't find label for jump to `%s'", label);
}

static void process_file(FILE * file)
{
	char *pattern_space;	/* Posix requires it be able to hold at least 8192 bytes */
	char *hold_space = NULL;	/* Posix requires it be able to hold at least 8192 bytes */
	static int linenum = 0;	/* GNU sed does not restart counting lines at EOF */
	int altered;
	int force_print;

	pattern_space = bb_get_chomped_line_from_file(file);
	if (pattern_space == NULL) {
		return;
	}
 
	/* go through every line in the file */
	do {
		char *next_line;
		sed_cmd_t *sed_cmd;
		int substituted = 0;
		/* This enables whole blocks of commands to be mask'ed out if the lead address doesnt match */
		int block_mask = 1;

		/* Read one line in advance so we can act on the last line, the '$' address */
		next_line = bb_get_chomped_line_from_file(file);
		linenum++;
		altered = 0;
		force_print = 0;

		/* for every line, go through all the commands */
		for (sed_cmd = sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) {
			int deleted = 0;

			/*
			 * entry point into sedding...
			 */
			int matched = (
				/* no range necessary */
				(sed_cmd->beg_line == 0 && sed_cmd->end_line == 0
					&& sed_cmd->beg_match == NULL
					&& sed_cmd->end_match == NULL) ||
				/* this line number is the first address we're looking for */
				(sed_cmd->beg_line > 0 && (sed_cmd->beg_line == linenum)) ||
				/* this line matches our first address regex */
				(sed_cmd->beg_match
					&& (regexec(sed_cmd->beg_match, pattern_space, 0, NULL,
							0) == 0)) ||
				/* we are currently within the beginning & ending address range */
				sed_cmd->still_in_range || ((sed_cmd->beg_line == -1)
					&& (next_line == NULL))
				);
			if (sed_cmd->cmd == '{') {
				block_mask = block_mask & matched;
			}
//			matched &= block_mask;

			if (sed_cmd->invert ^ (matched & block_mask)) {
				/* Update last used regex incase a blank substitute BRE is found */
				if (sed_cmd->beg_match) {
					previous_regex_ptr = sed_cmd->beg_match;
				}

				/*
				 * actual sedding
				 */
				switch (sed_cmd->cmd) {
				case '=':
					printf("%d\n", linenum);
					break;
				case 'P':{
					/* Write the current pattern space upto the first newline */
					char *tmp = strchr(pattern_space, '\n');

					if (tmp) {
						*tmp = '\0';
					}
				}
				case 'p':	/* Write the current pattern space to output */
					puts(pattern_space);
					break;
				case 'd':
					altered++;
					deleted = 1;
					force_print = 0;
					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 pattern_space is going to be printed anyway (pattern_space
					 *    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.
					 */

#ifdef CONFIG_FEATURE_SED_EMBEDED_NEWLINE
					/* HACK: escape newlines twice so regex can match them */
				{
					int offset = 0;

					while (strchr(pattern_space + offset, '\n') != NULL) {
						char *tmp;

						pattern_space =
							xrealloc(pattern_space,
							strlen(pattern_space) + 2);
						tmp = strchr(pattern_space + offset, '\n');
						memmove(tmp + 1, tmp, strlen(tmp) + 1);
						tmp[0] = '\\';
						tmp[1] = 'n';
						offset = tmp - pattern_space + 2;
					}
				}
#endif
					/* we print the pattern_space once, unless we were told to be quiet */
					substituted |= do_subst_command(sed_cmd, &pattern_space);

#ifdef CONFIG_FEATURE_SED_EMBEDED_NEWLINE
					/* undo HACK: escape newlines twice so regex can match them */
					{
						char *tmp = pattern_space;

						while ((tmp = strstr(tmp, "\\n")) != NULL) {
							memmove(tmp, tmp + 1, strlen(tmp + 1) + 1);
							tmp[0] = '\n';
						}
					}
#endif
					if (!be_quiet && substituted && ((sed_cmd->next == NULL)
							|| (sed_cmd->next->cmd != 's'))) {
						force_print = 1;
					}

					/* we also print the line if we were given the 'p' flag
					 * (this is quite possibly the second printing) */
					if ((sed_cmd->sub_p) && altered) {
						puts(pattern_space);
					}
					break;
				case 'a':
					puts(pattern_space);
					fputs(sed_cmd->editline, stdout);
					altered++;
					break;

				case 'i':
					fputs(sed_cmd->editline, stdout);
					break;

				case 'c':
					/* single-address case */
					if ((sed_cmd->end_match == NULL && sed_cmd->end_line == 0)
						/* multi-address case */
						/* - matching text */
						|| (sed_cmd->end_match
							&& (regexec(sed_cmd->end_match, pattern_space, 0,
									NULL, 0) == 0))
						/* - matching line numbers */
						|| (sed_cmd->end_line > 0
							&& sed_cmd->end_line == linenum)) {
						fputs(sed_cmd->editline, stdout);
					}
					altered++;

					break;

				case 'r':{
					FILE *outfile;

					outfile = fopen(sed_cmd->filename, "r");
					if (outfile) {
						char *line;

						while ((line =
								bb_get_chomped_line_from_file(outfile)) !=
							NULL) {
							pattern_space =
								xrealloc(pattern_space,
								strlen(line) + strlen(pattern_space) + 2);
							strcat(pattern_space, "\n");
							strcat(pattern_space, line);
						}
						bb_xprint_and_close_file(outfile);
					}

				}
					break;
				case 'q':	/* Branch to end of script and quit */
					deleted = 1;
					/* Exit the outer while loop */
					free(next_line);
					next_line = NULL;
					break;
				case 'n':	/* Read next line from input */
					if (!be_quiet) {
						puts(pattern_space);
					}
					if (next_line) {
						free(pattern_space);
						pattern_space = next_line;
						next_line = bb_get_chomped_line_from_file(file);
						linenum++;
					} else {
						/* Jump to end of script and exist */
						deleted = 1;
						free(next_line);
						next_line = NULL;
					}
					break;
				case 'N':	/* Append the next line to the current line */
					if (next_line) {
						pattern_space =
							realloc(pattern_space,
							strlen(pattern_space) + strlen(next_line) + 2);
						strcat(pattern_space, "\n");
						strcat(pattern_space, next_line);
						next_line = bb_get_chomped_line_from_file(file);
						linenum++;
					} else {
						/* Jump to end of script and exist */
						deleted = 1;
						free(next_line);
						next_line = NULL;
					}
					break;
				case 't':
					if (substituted)
						/* Fall through */
				case 'b':
					{
						if (sed_cmd->label == NULL) {
							/* Jump to end of script */
							deleted = 1;
						} else {
							sed_cmd = branch_to(sed_cmd->label);
						}
						/* Reset the substitution flag */
						substituted = 0;
					}
					break;
				case 'y':{
					int i;

					for (i = 0; pattern_space[i] != 0; i++) {
						int j;

						for (j = 0; sed_cmd->translate[j]; j += 2) {
							if (pattern_space[i] == sed_cmd->translate[j]) {
								pattern_space[i] = sed_cmd->translate[j + 1];
							}
						}
					}
				}
					break;
				case 'g':	/* Replace pattern space with hold space */
					free(pattern_space);
					if (hold_space) {
						pattern_space = strdup(hold_space);
					}
					break;
				case 'G': {	/* Append newline and hold space to pattern space */
					int pattern_space_size = 2;
					int hold_space_size = 0;

					if (pattern_space) {
						pattern_space_size += strlen(pattern_space);
					}
					if (hold_space) {
						hold_space_size = strlen(hold_space);
					}
					pattern_space = xrealloc(pattern_space, pattern_space_size + hold_space_size);
					if (pattern_space_size == 2) {
						strcat(pattern_space, "\n");
					} else {
						strcpy(pattern_space, "\n");
					}
					if (hold_space) {
						strcat(pattern_space, hold_space);
					}
					break;
				}
				case 'h':	/* Replace hold space with pattern space */
					free(hold_space);
					hold_space = strdup(pattern_space);
					break;
				case 'H': {	/* Append newline and pattern space to hold space */
					int hold_space_size = 2;
					int pattern_space_size = 0;

					if (hold_space) {
						hold_space_size += strlen(hold_space);
					}
					if (pattern_space) {
						pattern_space_size = strlen(pattern_space);
					}
					hold_space = xrealloc(hold_space, hold_space_size + pattern_space_size);

					if (hold_space_size == 2) {
						strcpy(hold_space, "\n");
					} else {
						strcat(hold_space, "\n");
					}
					if (pattern_space) {
						strcat(hold_space, pattern_space);
					}
					break;
				}
				case 'x':{
					/* Swap hold and pattern space */
					char *tmp = pattern_space;
					pattern_space = hold_space;
					hold_space = tmp;
					break;
				}
				}
			}

			/*
			 * exit point from sedding...
			 */
			if (matched) {
				if (
					/* this is a single-address command or... */
					(sed_cmd->end_line == 0 && sed_cmd->end_match == NULL)
					/* If only one address */
					/* we were in the middle of our address range (this
					 * isn't the first time through) and.. */
					|| ((sed_cmd->still_in_range == 1)
						/* this line number is the last address we're looking for or... */
						&& ((sed_cmd->end_line > 0
								&& (sed_cmd->end_line == linenum))
							/* this line matches our last address regex */
							|| (sed_cmd->end_match
								&& (regexec(sed_cmd->end_match, pattern_space,
										0, NULL, 0) == 0))))) {
					/* we're out of our address range */
					sed_cmd->still_in_range = 0;
				} else {
					/* didn't hit the exit? then we're still in the middle of an address range */
					sed_cmd->still_in_range = 1;
				}
			}

			if (sed_cmd->cmd == '}') {
				block_mask = 1;
			}

			if (deleted)
				break;

		}

		/* 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 && !substituted) || force_print) {
			puts(pattern_space);
		}
		free(pattern_space);
		pattern_space = next_line;
	} while (pattern_space);
}

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

#if 0 /* This doesnt seem to be working */
#ifdef CONFIG_FEATURE_CLEAN_UP
	/* destroy command strings on exit */
	if (atexit(destroy_cmd_strs) == -1)
		bb_perror_msg_and_die("atexit");
#endif
#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:
			bb_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 (sed_cmd_head.next == NULL) {
		if (argv[optind] == NULL)
			bb_show_usage();
		else
			add_cmd_str(argv[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) {
		process_file(stdin);
	} else {
		int i;
		FILE *file;

		for (i = optind; i < argc; i++) {
			if(!strcmp(argv[i], "-")) {
				process_file(stdin);
			} else {
				file = bb_wfopen(argv[i], "r");
				if (file) {
					process_file(file);
					fclose(file);
				} else {
					status = EXIT_FAILURE;
				}
			}
		}
	}

#ifdef CONFIG_FEATURE_CLEAN_UP
	destroy_cmd_strs();
#endif	
	return status;
}
