/* 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 "busybox.h"

#define	USERSIZE	1024	/* max line length typed in by user */
#define	INITBUF_SIZE	1024	/* initial buffer size */
typedef struct LINE {
	struct LINE *next;
	struct LINE *prev;
	int len;
	char data[1];
} LINE;

static LINE lines, *curLine;
static int curNum, lastNum, marks[26], dirty;
static char *bufBase, *bufPtr, *fileName, searchString[USERSIZE];
static int bufUsed, bufSize;

static void doCommands(void);
static void subCommand(const char *cmd, int num1, int num2);
static int getNum(const char **retcp, int *retHaveNum, int *retNum);
static int setCurNum(int num);
static int initEdit(void);
static void termEdit(void);
static void addLines(int num);
static int insertLine(int num, const char *data, int len);
static int 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);

int ed_main(int argc, char **argv);
int ed_main(int argc, char **argv)
{
	if (!initEdit())
		return EXIT_FAILURE;

	if (argc > 1) {
		fileName = strdup(argv[1]);

		if (fileName == NULL) {
			bb_error_msg("no memory");
			termEdit();
			return EXIT_SUCCESS;
		}

		if (!readLines(fileName, 1)) {
			termEdit();
			return EXIT_SUCCESS;
		}

		if (lastNum)
			setCurNum(1);

		dirty = FALSE;
	}

	doCommands();

	termEdit();
	return EXIT_SUCCESS;
}

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

	while (TRUE) {
		printf(": ");
		fflush(stdout);

		if (fgets(buf, sizeof(buf), stdin) == NULL)
			return;

		len = strlen(buf);

		if (len == 0)
			return;

		endbuf = &buf[len - 1];

		if (*endbuf != '\n') {
			bb_error_msg("command line too long");

			do {
				len = fgetc(stdin);
			} while ((len != EOF) && (len != '\n'));

			continue;
		}

		while ((endbuf > buf) && isblank(endbuf[-1]))
			endbuf--;

		*endbuf = '\0';

		cp = buf;

		while (isblank(*cp))
			cp++;

		have1 = FALSE;
		have2 = FALSE;

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

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

		while (isblank(*cp))
			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;
				}

				while (isblank(*cp))
					cp++;

				if (*cp == '\0') {
					if (fileName)
						printf("\"%s\"\n", fileName);
					else
						printf("No file name\n");
					break;
				}

				newname = strdup(cp);

				if (newname == NULL) {
					bb_error_msg("no memory for file name");
					break;
				}

				if (fileName)
					free(fileName);

				fileName = newname;
				break;

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

			case 'k':
				while (isblank(*cp))
					cp++;

				if ((*cp < 'a') || (*cp > 'a') || 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':
				while (isblank(*cp))
					cp++;

				if (have1 || *cp) {
					bb_error_msg("bad quit command");
					break;
				}

				if (!dirty)
					return;

				printf("Really quit? ");
				fflush(stdout);

				buf[0] = '\0';
				fgets(buf, sizeof(buf), stdin);
				cp = buf;

				while (isblank(*cp))
					cp++;

				if ((*cp == 'y') || (*cp == 'Y'))
					return;

				break;

			case 'r':
				if (*cp && !isblank(*cp)) {
					bb_error_msg("bad read command");
					break;
				}

				while (isblank(*cp))
					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 = strdup(cp);

				break;

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

			case 'w':
				if (*cp && !isblank(*cp)) {
					bb_error_msg("bad write command");
					break;
				}

				while (isblank(*cp))
					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 ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) {
		bb_error_msg("bad line range for 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 = (LINE *) 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 (fgets(buf, sizeof(buf), stdin)) {
		if ((buf[0] == '.') && (buf[1] == '\n') && (buf[2] == '\0'))
			return;

		len = strlen(buf);

		if (len == 0)
			return;

		if (buf[len - 1] != '\n') {
			bb_error_msg("line too long");
			do {
				len = fgetc(stdin);
			} while ((len != EOF) && (len != '\n'));
			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, int *retHaveNum, int *retNum)
{
	const char *cp;
	char *endStr, str[USERSIZE];
	int haveNum, value, num, sign;

	cp = *retcp;
	haveNum = FALSE;
	value = 0;
	sign = 1;

	while (TRUE) {
		while (isblank(*cp))
			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 += num * sign;

		while (isblank(*cp))
			cp++;

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

			case '+':
				sign = 1;
				cp++;
				break;

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


/*
 * Initialize everything for editing.
 */
static int initEdit(void)
{
	int i;

	bufSize = INITBUF_SIZE;
	bufBase = malloc(bufSize);

	if (bufBase == NULL) {
		bb_error_msg("no memory for buffer");
		return FALSE;
	}

	bufPtr = bufBase;
	bufUsed = 0;

	lines.next = &lines;
	lines.prev = &lines;

	curLine = NULL;
	curNum = 0;
	lastNum = 0;
	dirty = FALSE;
	fileName = NULL;
	searchString[0] = '\0';

	for (i = 0; i < 26; i++)
		marks[i] = 0;

	return TRUE;
}


/*
 * Finish editing.
 */
static void termEdit(void)
{
	if (bufBase)
		free(bufBase);

	bufBase = NULL;
	bufPtr = NULL;
	bufSize = 0;
	bufUsed = 0;

	if (fileName)
		free(fileName);

	fileName = NULL;

	searchString[0] = '\0';

	if (lastNum)
		deleteLines(1, lastNum);

	lastNum = 0;
	curNum = 0;
	curLine = NULL;
}


/*
 * 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(stdout);

	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 = 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 ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) {
		bb_error_msg("bad line range for write");
		return FALSE;
	}

	lineCount = 0;
	charCount = 0;

	fd = creat(file, 0666);

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

	printf("\"%s\", ", file);
	fflush(stdout);

	lp = findLine(num1);

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

	while (num1++ <= num2) {
		if (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 ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) {
		bb_error_msg("bad line range for print");
		return FALSE;
	}

	lp = findLine(num1);

	if (lp == NULL)
		return FALSE;

	while (num1 <= num2) {
		if (!expandFlag) {
			write(1, 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 = *cp++;

			if (ch & 0x80) {
				fputs("M-", stdout);
				ch &= 0x7f;
			}

			if (ch < ' ') {
				fputc('^', stdout);
				ch += '@';
			}

			if (ch == 0x7f) {
				fputc('^', stdout);
				ch = '?';
			}

			fputc(ch, 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 int deleteLines(int num1, int num2)
{
	LINE *lp, *nlp, *plp;
	int count;

	if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) {
		bb_error_msg("bad line numbers for delete");
		return FALSE;
	}

	lp = findLine(num1);

	if (lp == NULL)
		return FALSE;

	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;
		lp->next = NULL;
		lp->prev = NULL;
		lp->len = 0;
		free(lp);
		lp = nlp;
	}

	dirty = TRUE;

	return TRUE;
}


/*
 * Search for a line which contains the specified string.
 * If the string is NULL, 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 int searchLines(const char *str, int num1, int num2)
{
	const LINE *lp;
	int len;

	if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) {
		bb_error_msg("bad line numbers for 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;
}
