示例#1
0
文件: ed.c 项目: Crobisaur/busybox
/*
 * 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;
}
示例#2
0
/*
 * 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(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 < ' ') {
				bb_putchar('^');
				ch += '@';
			}
			if (ch == 0x7f) {
				bb_putchar('^');
				ch = '?';
			}
			bb_putchar(ch);
		}

		fputs("$\n", stdout);

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

	return TRUE;
}
示例#3
0
文件: ed.c 项目: Crobisaur/busybox
/*
 * 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;
}
示例#4
0
文件: ed.c 项目: Crobisaur/busybox
/*
 * 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;
}
示例#5
0
文件: ed.c 项目: Crobisaur/busybox
/*
 * 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;
}
示例#6
0
文件: ed.c 项目: Crobisaur/busybox
/*
 * 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 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);
}