/* 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(NULL, ": ", buf, sizeof(buf), /*timeout*/ -1);
		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(NULL, "Really quit? ", buf, 16, /*timeout*/ -1);
			/* 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 = xmalloc(sizeof(LINE) + lp->len + deltaLen);

		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(NULL, "", buf, sizeof(buf), /*timeout*/ -1);
		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) {
		bb_simple_perror_msg(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 = xrealloc(bufBase, len);
			bufBase = cp;
			bufPtr = bufBase + bufUsed;
			bufSize = len;
		}

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

	} while (cc > 0);

	if (cc < 0) {
		bb_simple_perror_msg(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) {
		bb_simple_perror_msg(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) {
			bb_simple_perror_msg(file);
			close(fd);
			return FALSE;
		}
		charCount += lp->len;
		lineCount++;
		lp = lp->next;
	}

	if (close(fd) < 0) {
		bb_simple_perror_msg(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 = xmalloc(sizeof(LINE) + len - 1);

	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("can't 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;
}
