/* 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)
{
	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 = "";

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