/* vi: set sw=4 ts=4: */
/*
 * Copyright (c) 2002 by David I. Bell
 * Permission is granted to use, distribute, or modify this source,
 * provided that this copyright notice remains intact.
 *
 * The "ed" built-in command (much simplified)
 */

#include "libbb.h"

typedef struct LINE {
	struct LINE *next;
	struct LINE *prev;
	int len;
	char data[1];
} LINE;


#define searchString bb_common_bufsiz1

enum {
	USERSIZE = sizeof(searchString) > 1024 ? 1024
	         : sizeof(searchString) - 1, /* max line length typed in by user */
	INITBUF_SIZE = 1024, /* initial buffer size */
};

struct globals {
	int curNum;
	int lastNum;
	int bufUsed;
	int bufSize;
	LINE *curLine;
	char *bufBase;
	char *bufPtr;
	char *fileName;
	LINE lines;
	smallint dirty;
	int marks[26];
};
#define G (*ptr_to_globals)
#define curLine            (G.curLine           )
#define bufBase            (G.bufBase           )
#define bufPtr             (G.bufPtr            )
#define fileName           (G.fileName          )
#define curNum             (G.curNum            )
#define lastNum            (G.lastNum           )
#define bufUsed            (G.bufUsed           )
#define bufSize            (G.bufSize           )
#define dirty              (G.dirty             )
#define lines              (G.lines             )
#define marks              (G.marks             )
#define INIT_G() do { \
	SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
} while (0)


static void doCommands(void);
static void subCommand(const char *cmd, int num1, int num2);
static int getNum(const char **retcp, smallint *retHaveNum, int *retNum);
static int setCurNum(int num);
static void addLines(int num);
static int insertLine(int num, const char *data, int len);
static void deleteLines(int num1, int num2);
static int printLines(int num1, int num2, int expandFlag);
static int writeLines(const char *file, int num1, int num2);
static int readLines(const char *file, int num);
static int searchLines(const char *str, int num1, int num2);
static LINE *findLine(int num);
static int findString(const LINE *lp, const char * str, int len, int offset);


static int bad_nums(int num1, int num2, const char *for_what)
{
	if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) {
		bb_error_msg("bad line range for %s", for_what);
		return 1;
	}
	return 0;
}


static char *skip_blank(const char *cp)
{
	while (isblank(*cp))
		cp++;
	return (char *)cp;
}


int ed_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int ed_main(int argc UNUSED_PARAM, char **argv)
{
	INIT_G();

	bufSize = INITBUF_SIZE;
	bufBase = xmalloc(bufSize);
	bufPtr = bufBase;
	lines.next = &lines;
	lines.prev = &lines;

	if (argv[1]) {
		fileName = xstrdup(argv[1]);
		if (!readLines(fileName, 1)) {
			return EXIT_SUCCESS;
		}
		if (lastNum)
			setCurNum(1);
		dirty = FALSE;
	}

	doCommands();
	return EXIT_SUCCESS;
}

/*
 * Read commands until we are told to stop.
 */
static void doCommands(void)
{
	const char *cp;
	char *endbuf, buf[USERSIZE];
	int len, num1, num2;
	smallint have1, have2;

	while (TRUE) {
		/* Returns:
		 * -1 on read errors or EOF, or on bare Ctrl-D.
		 * 0  on ctrl-C,
		 * >0 length of input string, including terminating '\n'
		 */
		len = read_line_input(": ", buf, sizeof(buf), NULL);
		if (len <= 0)
			return;
		endbuf = &buf[len - 1];
		while ((endbuf > buf) && isblank(endbuf[-1]))
			endbuf--;
		*endbuf = '\0';

		cp = skip_blank(buf);
		have1 = FALSE;
		have2 = FALSE;

		if ((curNum == 0) && (lastNum > 0)) {
			curNum = 1;
			curLine = lines.next;
		}

		if (!getNum(&cp, &have1, &num1))
			continue;

		cp = skip_blank(cp);

		if (*cp == ',') {
			cp++;
			if (!getNum(&cp, &have2, &num2))
				continue;
			if (!have1)
				num1 = 1;
			if (!have2)
				num2 = lastNum;
			have1 = TRUE;
			have2 = TRUE;
		}
		if (!have1)
			num1 = curNum;
		if (!have2)
			num2 = num1;

		switch (*cp++) {
		case 'a':
			addLines(num1 + 1);
			break;

		case 'c':
			deleteLines(num1, num2);
			addLines(num1);
			break;

		case 'd':
			deleteLines(num1, num2);
			break;

		case 'f':
			if (*cp && !isblank(*cp)) {
				bb_error_msg("bad file command");
				break;
			}
			cp = skip_blank(cp);
			if (*cp == '\0') {
				if (fileName)
					printf("\"%s\"\n", fileName);
				else
					printf("No file name\n");
				break;
			}
			free(fileName);
			fileName = xstrdup(cp);
			break;

		case 'i':
			addLines(num1);
			break;

		case 'k':
			cp = skip_blank(cp);
			if ((*cp < 'a') || (*cp > 'z') || cp[1]) {
				bb_error_msg("bad mark name");
				break;
			}
			marks[*cp - 'a'] = num2;
			break;

		case 'l':
			printLines(num1, num2, TRUE);
			break;

		case 'p':
			printLines(num1, num2, FALSE);
			break;

		case 'q':
			cp = skip_blank(cp);
			if (have1 || *cp) {
				bb_error_msg("bad quit command");
				break;
			}
			if (!dirty)
				return;
			len = read_line_input("Really quit? ", buf, 16, NULL);
			/* read error/EOF - no way to continue */
			if (len < 0)
				return;
			cp = skip_blank(buf);
			if ((*cp | 0x20) == 'y') /* Y or y */
				return;
			break;

		case 'r':
			if (*cp && !isblank(*cp)) {
				bb_error_msg("bad read command");
				break;
			}
			cp = skip_blank(cp);
			if (*cp == '\0') {
				bb_error_msg("no file name");
				break;
			}
			if (!have1)
				num1 = lastNum;
			if (readLines(cp, num1 + 1))
				break;
			if (fileName == NULL)
				fileName = xstrdup(cp);
			break;

		case 's':
			subCommand(cp, num1, num2);
			break;

		case 'w':
			if (*cp && !isblank(*cp)) {
				bb_error_msg("bad write command");
				break;
			}
			cp = skip_blank(cp);
			if (!have1) {
				num1 = 1;
				num2 = lastNum;
			}
			if (*cp == '\0')
				cp = fileName;
			if (cp == NULL) {
				bb_error_msg("no file name specified");
				break;
			}
			writeLines(cp, num1, num2);
			break;

		case 'z':
			switch (*cp) {
			case '-':
				printLines(curNum - 21, curNum, FALSE);
				break;
			case '.':
				printLines(curNum - 11, curNum + 10, FALSE);
				break;
			default:
				printLines(curNum, curNum + 21, FALSE);
				break;
			}
			break;

		case '.':
			if (have1) {
				bb_error_msg("no arguments allowed");
				break;
			}
			printLines(curNum, curNum, FALSE);
			break;

		case '-':
			if (setCurNum(curNum - 1))
				printLines(curNum, curNum, FALSE);
			break;

		case '=':
			printf("%d\n", num1);
			break;
		case '\0':
			if (have1) {
				printLines(num2, num2, FALSE);
				break;
			}
			if (setCurNum(curNum + 1))
				printLines(curNum, curNum, FALSE);
			break;

		default:
			bb_error_msg("unimplemented command");
			break;
		}
	}
}


/*
 * Do the substitute command.
 * The current line is set to the last substitution done.
 */
static void subCommand(const char *cmd, int num1, int num2)
{
	char *cp, *oldStr, *newStr, buf[USERSIZE];
	int delim, oldLen, newLen, deltaLen, offset;
	LINE *lp, *nlp;
	int globalFlag, printFlag, didSub, needPrint;

	if (bad_nums(num1, num2, "substitute"))
		return;

	globalFlag = FALSE;
	printFlag = FALSE;
	didSub = FALSE;
	needPrint = FALSE;

	/*
	 * Copy the command so we can modify it.
	 */
	strcpy(buf, cmd);
	cp = buf;

	if (isblank(*cp) || (*cp == '\0')) {
		bb_error_msg("bad delimiter for substitute");
		return;
	}

	delim = *cp++;
	oldStr = cp;

	cp = strchr(cp, delim);
	if (cp == NULL) {
		bb_error_msg("missing 2nd delimiter for substitute");
		return;
	}

	*cp++ = '\0';

	newStr = cp;
	cp = strchr(cp, delim);

	if (cp)
		*cp++ = '\0';
	else
		cp = (char*)"";

	while (*cp) switch (*cp++) {
		case 'g':
			globalFlag = TRUE;
			break;
		case 'p':
			printFlag = TRUE;
			break;
		default:
			bb_error_msg("unknown option for substitute");
			return;
	}

	if (*oldStr == '\0') {
		if (searchString[0] == '\0') {
			bb_error_msg("no previous search string");
			return;
		}
		oldStr = searchString;
	}

	if (oldStr != searchString)
		strcpy(searchString, oldStr);

	lp = findLine(num1);
	if (lp == NULL)
		return;

	oldLen = strlen(oldStr);
	newLen = strlen(newStr);
	deltaLen = newLen - oldLen;
	offset = 0;
	nlp = NULL;

	while (num1 <= num2) {
		offset = findString(lp, oldStr, oldLen, offset);

		if (offset < 0) {
			if (needPrint) {
				printLines(num1, num1, FALSE);
				needPrint = FALSE;
			}
			offset = 0;
			lp = lp->next;
			num1++;
			continue;
		}

		needPrint = printFlag;
		didSub = TRUE;
		dirty = TRUE;

		/*
		 * If the replacement string is the same size or shorter
		 * than the old string, then the substitution is easy.
		 */
		if (deltaLen <= 0) {
			memcpy(&lp->data[offset], newStr, newLen);
			if (deltaLen) {
				memcpy(&lp->data[offset + newLen],
					&lp->data[offset + oldLen],
					lp->len - offset - oldLen);

				lp->len += deltaLen;
			}
			offset += newLen;
			if (globalFlag)
				continue;
			if (needPrint) {
				printLines(num1, num1, FALSE);
				needPrint = FALSE;
			}
			lp = lp->next;
			num1++;
			continue;
		}

		/*
		 * The new string is larger, so allocate a new line
		 * structure and use that.  Link it in in place of
		 * the old line structure.
		 */
		nlp = malloc(sizeof(LINE) + lp->len + deltaLen);
		if (nlp == NULL) {
			bb_error_msg("cannot get memory for line");
			return;
		}

		nlp->len = lp->len + deltaLen;

		memcpy(nlp->data, lp->data, offset);
		memcpy(&nlp->data[offset], newStr, newLen);
		memcpy(&nlp->data[offset + newLen],
			&lp->data[offset + oldLen],
			lp->len - offset - oldLen);

		nlp->next = lp->next;
		nlp->prev = lp->prev;
		nlp->prev->next = nlp;
		nlp->next->prev = nlp;

		if (curLine == lp)
			curLine = nlp;

		free(lp);
		lp = nlp;

		offset += newLen;

		if (globalFlag)
			continue;

		if (needPrint) {
			printLines(num1, num1, FALSE);
			needPrint = FALSE;
		}

		lp = lp->next;
		num1++;
	}

	if (!didSub)
		bb_error_msg("no substitutions found for \"%s\"", oldStr);
}


/*
 * Search a line for the specified string starting at the specified
 * offset in the line.  Returns the offset of the found string, or -1.
 */
static int findString(const LINE *lp, const char *str, int len, int offset)
{
	int left;
	const char *cp, *ncp;

	cp = &lp->data[offset];
	left = lp->len - offset;

	while (left >= len) {
		ncp = memchr(cp, *str, left);
		if (ncp == NULL)
			return -1;
		left -= (ncp - cp);
		if (left < len)
			return -1;
		cp = ncp;
		if (memcmp(cp, str, len) == 0)
			return (cp - lp->data);
		cp++;
		left--;
	}

	return -1;
}


/*
 * Add lines which are typed in by the user.
 * The lines are inserted just before the specified line number.
 * The lines are terminated by a line containing a single dot (ugly!),
 * or by an end of file.
 */
static void addLines(int num)
{
	int len;
	char buf[USERSIZE + 1];

	while (1) {
		/* Returns:
		 * -1 on read errors or EOF, or on bare Ctrl-D.
		 * 0  on ctrl-C,
		 * >0 length of input string, including terminating '\n'
		 */
		len = read_line_input("", buf, sizeof(buf), NULL);
		if (len <= 0) {
			/* Previously, ctrl-C was exiting to shell.
			 * Now we exit to ed prompt. Is in important? */
			return;
		}
		if ((buf[0] == '.') && (buf[1] == '\n') && (buf[2] == '\0'))
			return;
		if (!insertLine(num++, buf, len))
			return;
	}
}


/*
 * Parse a line number argument if it is present.  This is a sum
 * or difference of numbers, '.', '$', 'x, or a search string.
 * Returns TRUE if successful (whether or not there was a number).
 * Returns FALSE if there was a parsing error, with a message output.
 * Whether there was a number is returned indirectly, as is the number.
 * The character pointer which stopped the scan is also returned.
 */
static int getNum(const char **retcp, smallint *retHaveNum, int *retNum)
{
	const char *cp;
	char *endStr, str[USERSIZE];
	int value, num;
	smallint haveNum, minus;

	cp = *retcp;
	value = 0;
	haveNum = FALSE;
	minus = 0;

	while (TRUE) {
		cp = skip_blank(cp);

		switch (*cp) {
			case '.':
				haveNum = TRUE;
				num = curNum;
				cp++;
				break;

			case '$':
				haveNum = TRUE;
				num = lastNum;
				cp++;
				break;

			case '\'':
				cp++;
				if ((*cp < 'a') || (*cp > 'z')) {
					bb_error_msg("bad mark name");
					return FALSE;
				}
				haveNum = TRUE;
				num = marks[*cp++ - 'a'];
				break;

			case '/':
				strcpy(str, ++cp);
				endStr = strchr(str, '/');
				if (endStr) {
					*endStr++ = '\0';
					cp += (endStr - str);
				} else
					cp = "";
				num = searchLines(str, curNum, lastNum);
				if (num == 0)
					return FALSE;
				haveNum = TRUE;
				break;

			default:
				if (!isdigit(*cp)) {
					*retcp = cp;
					*retHaveNum = haveNum;
					*retNum = value;
					return TRUE;
				}
				num = 0;
				while (isdigit(*cp))
					num = num * 10 + *cp++ - '0';
				haveNum = TRUE;
				break;
		}

		value += (minus ? -num : num);

		cp = skip_blank(cp);

		switch (*cp) {
			case '-':
				minus = 1;
				cp++;
				break;

			case '+':
				minus = 0;
				cp++;
				break;

			default:
				*retcp = cp;
				*retHaveNum = haveNum;
				*retNum = value;
				return TRUE;
		}
	}
}


/*
 * Read lines from a file at the specified line number.
 * Returns TRUE if the file was successfully read.
 */
static int readLines(const char *file, int num)
{
	int fd, cc;
	int len, lineCount, charCount;
	char *cp;

	if ((num < 1) || (num > lastNum + 1)) {
		bb_error_msg("bad line for read");
		return FALSE;
	}

	fd = open(file, 0);
	if (fd < 0) {
		perror(file);
		return FALSE;
	}

	bufPtr = bufBase;
	bufUsed = 0;
	lineCount = 0;
	charCount = 0;
	cc = 0;

	printf("\"%s\", ", file);
	fflush_all();

	do {
		cp = memchr(bufPtr, '\n', bufUsed);

		if (cp) {
			len = (cp - bufPtr) + 1;
			if (!insertLine(num, bufPtr, len)) {
				close(fd);
				return FALSE;
			}
			bufPtr += len;
			bufUsed -= len;
			charCount += len;
			lineCount++;
			num++;
			continue;
		}

		if (bufPtr != bufBase) {
			memcpy(bufBase, bufPtr, bufUsed);
			bufPtr = bufBase + bufUsed;
		}

		if (bufUsed >= bufSize) {
			len = (bufSize * 3) / 2;
			cp = realloc(bufBase, len);
			if (cp == NULL) {
				bb_error_msg("no memory for buffer");
				close(fd);
				return FALSE;
			}
			bufBase = cp;
			bufPtr = bufBase + bufUsed;
			bufSize = len;
		}

		cc = safe_read(fd, bufPtr, bufSize - bufUsed);
		bufUsed += cc;
		bufPtr = bufBase;

	} while (cc > 0);

	if (cc < 0) {
		perror(file);
		close(fd);
		return FALSE;
	}

	if (bufUsed) {
		if (!insertLine(num, bufPtr, bufUsed)) {
			close(fd);
			return -1;
		}
		lineCount++;
		charCount += bufUsed;
	}

	close(fd);

	printf("%d lines%s, %d chars\n", lineCount,
		(bufUsed ? " (incomplete)" : ""), charCount);

	return TRUE;
}


/*
 * Write the specified lines out to the specified file.
 * Returns TRUE if successful, or FALSE on an error with a message output.
 */
static int writeLines(const char *file, int num1, int num2)
{
	LINE *lp;
	int fd, lineCount, charCount;

	if (bad_nums(num1, num2, "write"))
		return FALSE;

	lineCount = 0;
	charCount = 0;

	fd = creat(file, 0666);
	if (fd < 0) {
		perror(file);
		return FALSE;
	}

	printf("\"%s\", ", file);
	fflush_all();

	lp = findLine(num1);
	if (lp == NULL) {
		close(fd);
		return FALSE;
	}

	while (num1++ <= num2) {
		if (full_write(fd, lp->data, lp->len) != lp->len) {
			perror(file);
			close(fd);
			return FALSE;
		}
		charCount += lp->len;
		lineCount++;
		lp = lp->next;
	}

	if (close(fd) < 0) {
		perror(file);
		return FALSE;
	}

	printf("%d lines, %d chars\n", lineCount, charCount);
	return TRUE;
}


/*
 * Print lines in a specified range.
 * The last line printed becomes the current line.
 * If expandFlag is TRUE, then the line is printed specially to
 * show magic characters.
 */
static int printLines(int num1, int num2, int expandFlag)
{
	const LINE *lp;
	const char *cp;
	int ch, count;

	if (bad_nums(num1, num2, "print"))
		return FALSE;

	lp = findLine(num1);
	if (lp == NULL)
		return FALSE;

	while (num1 <= num2) {
		if (!expandFlag) {
			write(STDOUT_FILENO, lp->data, lp->len);
			setCurNum(num1++);
			lp = lp->next;
			continue;
		}

		/*
		 * Show control characters and characters with the
		 * high bit set specially.
		 */
		cp = lp->data;
		count = lp->len;

		if ((count > 0) && (cp[count - 1] == '\n'))
			count--;

		while (count-- > 0) {
			ch = (unsigned char) *cp++;
			fputc_printable(ch | PRINTABLE_META, stdout);
		}

		fputs("$\n", stdout);

		setCurNum(num1++);
		lp = lp->next;
	}

	return TRUE;
}


/*
 * Insert a new line with the specified text.
 * The line is inserted so as to become the specified line,
 * thus pushing any existing and further lines down one.
 * The inserted line is also set to become the current line.
 * Returns TRUE if successful.
 */
static int insertLine(int num, const char *data, int len)
{
	LINE *newLp, *lp;

	if ((num < 1) || (num > lastNum + 1)) {
		bb_error_msg("inserting at bad line number");
		return FALSE;
	}

	newLp = malloc(sizeof(LINE) + len - 1);
	if (newLp == NULL) {
		bb_error_msg("failed to allocate memory for line");
		return FALSE;
	}

	memcpy(newLp->data, data, len);
	newLp->len = len;

	if (num > lastNum)
		lp = &lines;
	else {
		lp = findLine(num);
		if (lp == NULL) {
			free((char *) newLp);
			return FALSE;
		}
	}

	newLp->next = lp;
	newLp->prev = lp->prev;
	lp->prev->next = newLp;
	lp->prev = newLp;

	lastNum++;
	dirty = TRUE;
	return setCurNum(num);
}


/*
 * Delete lines from the given range.
 */
static void deleteLines(int num1, int num2)
{
	LINE *lp, *nlp, *plp;
	int count;

	if (bad_nums(num1, num2, "delete"))
		return;

	lp = findLine(num1);
	if (lp == NULL)
		return;

	if ((curNum >= num1) && (curNum <= num2)) {
		if (num2 < lastNum)
			setCurNum(num2 + 1);
		else if (num1 > 1)
			setCurNum(num1 - 1);
		else
			curNum = 0;
	}

	count = num2 - num1 + 1;
	if (curNum > num2)
		curNum -= count;
	lastNum -= count;

	while (count-- > 0) {
		nlp = lp->next;
		plp = lp->prev;
		plp->next = nlp;
		nlp->prev = plp;
		free(lp);
		lp = nlp;
	}

	dirty = TRUE;
}


/*
 * Search for a line which contains the specified string.
 * If the string is "", then the previously searched for string
 * is used.  The currently searched for string is saved for future use.
 * Returns the line number which matches, or 0 if there was no match
 * with an error printed.
 */
static NOINLINE int searchLines(const char *str, int num1, int num2)
{
	const LINE *lp;
	int len;

	if (bad_nums(num1, num2, "search"))
		return 0;

	if (*str == '\0') {
		if (searchString[0] == '\0') {
			bb_error_msg("no previous search string");
			return 0;
		}
		str = searchString;
	}

	if (str != searchString)
		strcpy(searchString, str);

	len = strlen(str);

	lp = findLine(num1);
	if (lp == NULL)
		return 0;

	while (num1 <= num2) {
		if (findString(lp, str, len, 0) >= 0)
			return num1;
		num1++;
		lp = lp->next;
	}

	bb_error_msg("cannot find string \"%s\"", str);
	return 0;
}


/*
 * Return a pointer to the specified line number.
 */
static LINE *findLine(int num)
{
	LINE *lp;
	int lnum;

	if ((num < 1) || (num > lastNum)) {
		bb_error_msg("line number %d does not exist", num);
		return NULL;
	}

	if (curNum <= 0) {
		curNum = 1;
		curLine = lines.next;
	}

	if (num == curNum)
		return curLine;

	lp = curLine;
	lnum = curNum;
	if (num < (curNum / 2)) {
		lp = lines.next;
		lnum = 1;
	} else if (num > ((curNum + lastNum) / 2)) {
		lp = lines.prev;
		lnum = lastNum;
	}

	while (lnum < num) {
		lp = lp->next;
		lnum++;
	}

	while (lnum > num) {
		lp = lp->prev;
		lnum--;
	}
	return lp;
}


/*
 * Set the current line number.
 * Returns TRUE if successful.
 */
static int setCurNum(int num)
{
	LINE *lp;

	lp = findLine(num);
	if (lp == NULL)
		return FALSE;
	curNum = num;
	curLine = lp;
	return TRUE;
}
