X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=editors%2Fed.c;h=c028b78cb8157599f3788e3a55e995b20401c395;hb=0af5265180877f4e8fbf8f1d9f2999b3fd2205d3;hp=42adca40938e256ffc5d38225764ce8fc474ff24;hpb=06af2165288cd6516b89001ec9e24992619230e0;p=oweals%2Fbusybox.git diff --git a/editors/ed.c b/editors/ed.c index 42adca409..c028b78cb 100644 --- a/editors/ed.c +++ b/editors/ed.c @@ -7,10 +7,24 @@ * The "ed" built-in command (much simplified) */ -#include "busybox.h" +//config:config ED +//config: bool "ed" +//config: default y +//config: help +//config: The original 1970's Unix text editor, from the days of teletypes. +//config: Small, simple, evil. Part of SUSv3. If you're not already using +//config: this, you don't need it. + +//kbuild:lib-$(CONFIG_ED) += ed.o + +//applet:IF_ED(APPLET(ed, BB_DIR_BIN, BB_SUID_DROP)) + +//usage:#define ed_trivial_usage "" +//usage:#define ed_full_usage "" + +#include "libbb.h" +#include "common_bufsiz.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; @@ -18,57 +32,101 @@ typedef struct LINE { 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; + +#define searchString bb_common_bufsiz1 + +enum { + USERSIZE = COMMON_BUFSIZE > 1024 ? 1024 + : COMMON_BUFSIZE - 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 { \ + setup_common_bufsiz(); \ + 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, int *retHaveNum, int *retNum); +static int getNum(const char **retcp, smallint *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 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); -int ed_main(int argc, char **argv); -int ed_main(int argc, char **argv) + +static int bad_nums(int num1, int num2, const char *for_what) { - if (!initEdit()) - return EXIT_FAILURE; + if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) { + bb_error_msg("bad line range for %s", for_what); + return 1; + } + return 0; +} - if (argc > 1) { - fileName = strdup(argv[1]); - if (fileName == NULL) { - bb_error_msg("no memory"); - termEdit(); - return EXIT_SUCCESS; - } +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)) { - termEdit(); return EXIT_SUCCESS; } - if (lastNum) setCurNum(1); - dirty = FALSE; } doCommands(); - - termEdit(); return EXIT_SUCCESS; } @@ -78,43 +136,25 @@ int ed_main(int argc, char **argv) static void doCommands(void) { const char *cp; - char *endbuf, *newname, buf[USERSIZE]; - int len, num1, num2, have1, have2; + char *endbuf, buf[USERSIZE]; + int len, num1, num2; + smallint have1, have2; while (TRUE) { - printf(": "); - fflush(stdout); - - if (fgets(buf, sizeof(buf), stdin) == NULL) - return; - - len = strlen(buf); - - if (len == 0) + /* 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]; - - 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++; - + cp = skip_blank(buf); have1 = FALSE; have2 = FALSE; @@ -126,227 +166,176 @@ static void doCommands(void) if (!getNum(&cp, &have1, &num1)) continue; - while (isblank(*cp)) - cp++; + 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; - } - - while (isblank(*cp)) - cp++; - - if (*cp == '\0') { - if (fileName) - printf("\"%s\"\n", fileName); - else - printf("No file name\n"); - break; - } + case 'a': + addLines(num1 + 1); + break; - newname = strdup(cp); + case 'c': + deleteLines(num1, num2); + addLines(num1); + break; - if (newname == NULL) { - bb_error_msg("no memory for file name"); - 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) - free(fileName); - - fileName = newname; + printf("\"%s\"\n", fileName); + else + puts("No file name"); break; + } + free(fileName); + fileName = xstrdup(cp); + break; - case 'i': - addLines(num1); + 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 'k': - while (isblank(*cp)) - cp++; + case 'l': + printLines(num1, num2, TRUE); + break; - if ((*cp < 'a') || (*cp > 'a') || cp[1]) { - bb_error_msg("bad mark name"); - break; - } + case 'p': + printLines(num1, num2, FALSE); + break; - marks[*cp - 'a'] = num2; + 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 'l': - printLines(num1, num2, TRUE); + case 'r': + if (*cp && !isblank(*cp)) { + bb_error_msg("bad read command"); break; - - case 'p': - printLines(num1, num2, FALSE); + } + cp = skip_blank(cp); + if (*cp == '\0') { + bb_error_msg("no file name"); 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; - + } + if (!have1) + num1 = lastNum; + if (readLines(cp, num1 + 1)) break; + if (fileName == NULL) + fileName = xstrdup(cp); + 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 's': - subCommand(cp, num1, num2); + case 'w': + if (*cp && !isblank(*cp)) { + bb_error_msg("bad write command"); 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); + } + 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; - } + case 'z': + switch (*cp) { + case '-': + printLines(curNum - 21, curNum, FALSE); break; - case '.': - if (have1) { - bb_error_msg("no arguments allowed"); - break; - } - - printLines(curNum, curNum, FALSE); + printLines(curNum - 11, curNum + 10, FALSE); break; - - case '-': - if (setCurNum(curNum - 1)) - printLines(curNum, curNum, FALSE); - + default: + printLines(curNum, curNum + 21, FALSE); break; + } + break; - case '=': - printf("%d\n", num1); + case '.': + if (have1) { + bb_error_msg("no arguments allowed"); break; + } + printLines(curNum, curNum, FALSE); + break; - case '\0': - if (have1) { - printLines(num2, num2, FALSE); - break; - } - - if (setCurNum(curNum + 1)) - printLines(curNum, curNum, FALSE); + 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; + default: + bb_error_msg("unimplemented command"); + break; } } } @@ -356,17 +345,15 @@ static void doCommands(void) * Do the substitute command. * The current line is set to the last substitution done. */ -static void subCommand(const char * cmd, int num1, int num2) +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"); + if (bad_nums(num1, num2, "substitute")) return; - } globalFlag = FALSE; printFlag = FALSE; @@ -388,7 +375,6 @@ static void subCommand(const char * cmd, int num1, int num2) oldStr = cp; cp = strchr(cp, delim); - if (cp == NULL) { bb_error_msg("missing 2nd delimiter for substitute"); return; @@ -408,11 +394,9 @@ static void subCommand(const char * cmd, int num1, int num2) case 'g': globalFlag = TRUE; break; - case 'p': printFlag = TRUE; break; - default: bb_error_msg("unknown option for substitute"); return; @@ -423,7 +407,6 @@ static void subCommand(const char * cmd, int num1, int num2) bb_error_msg("no previous search string"); return; } - oldStr = searchString; } @@ -431,7 +414,6 @@ static void subCommand(const char * cmd, int num1, int num2) strcpy(searchString, oldStr); lp = findLine(num1); - if (lp == NULL) return; @@ -449,11 +431,9 @@ static void subCommand(const char * cmd, int num1, int num2) printLines(num1, num1, FALSE); needPrint = FALSE; } - offset = 0; lp = lp->next; num1++; - continue; } @@ -467,7 +447,6 @@ static void subCommand(const char * cmd, int num1, int num2) */ if (deltaLen <= 0) { memcpy(&lp->data[offset], newStr, newLen); - if (deltaLen) { memcpy(&lp->data[offset + newLen], &lp->data[offset + oldLen], @@ -475,41 +454,29 @@ static void subCommand(const char * cmd, int num1, int num2) 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 + * structure and use that. Link it 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 = 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); @@ -548,7 +515,7 @@ static void subCommand(const char * cmd, int num1, int num2) * 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) +static int findString(const LINE *lp, const char *str, int len, int offset) { int left; const char *cp, *ncp; @@ -558,20 +525,14 @@ static int findString( const LINE * lp, const char * str, int len, int 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--; } @@ -591,23 +552,20 @@ 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')); + 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; } @@ -622,20 +580,20 @@ static void addLines(int num) * 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) +static int getNum(const char **retcp, smallint *retHaveNum, int *retNum) { const char *cp; char *endStr, str[USERSIZE]; - int haveNum, value, num, sign; + int value, num; + smallint haveNum, minus; cp = *retcp; - haveNum = FALSE; value = 0; - sign = 1; + haveNum = FALSE; + minus = 0; while (TRUE) { - while (isblank(*cp)) - cp++; + cp = skip_blank(cp); switch (*cp) { case '.': @@ -652,12 +610,10 @@ static int getNum(const char **retcp, int *retHaveNum, int *retNum) case '\'': cp++; - if ((*cp < 'a') || (*cp > 'z')) { bb_error_msg("bad mark name"); return FALSE; } - haveNum = TRUE; num = marks[*cp++ - 'a']; break; @@ -665,19 +621,14 @@ static int getNum(const char **retcp, int *retHaveNum, int *retNum) case '/': strcpy(str, ++cp); endStr = strchr(str, '/'); - if (endStr) { *endStr++ = '\0'; cp += (endStr - str); - } - else + } else cp = ""; - num = searchLines(str, curNum, lastNum); - if (num == 0) return FALSE; - haveNum = TRUE; break; @@ -688,29 +639,25 @@ static int getNum(const char **retcp, int *retHaveNum, int *retNum) *retNum = value; return TRUE; } - num = 0; - while (isdigit(*cp)) num = num * 10 + *cp++ - '0'; - haveNum = TRUE; break; } - value += num * sign; + value += (minus ? -num : num); - while (isblank(*cp)) - cp++; + cp = skip_blank(cp); switch (*cp) { case '-': - sign = -1; + minus = 1; cp++; break; case '+': - sign = 1; + minus = 0; cp++; break; @@ -724,75 +671,11 @@ static int getNum(const char **retcp, int *retHaveNum, int *retNum) } -/* - * 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) +static int readLines(const char *file, int num) { int fd, cc; int len, lineCount, charCount; @@ -804,9 +687,8 @@ static int readLines(const char * file, int num) } fd = open(file, 0); - if (fd < 0) { - perror(file); + bb_simple_perror_msg(file); return FALSE; } @@ -817,25 +699,22 @@ static int readLines(const char * file, int num) cc = 0; printf("\"%s\", ", file); - fflush(stdout); + 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; } @@ -846,27 +725,19 @@ static int readLines(const char * file, int num) 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; - } - + cp = xrealloc(bufBase, len); bufBase = cp; bufPtr = bufBase + bufUsed; bufSize = len; } - cc = read(fd, bufPtr, bufSize - bufUsed); + cc = safe_read(fd, bufPtr, bufSize - bufUsed); bufUsed += cc; bufPtr = bufBase; - } while (cc > 0); if (cc < 0) { - perror(file); + bb_simple_perror_msg(file); close(fd); return FALSE; } @@ -876,7 +747,6 @@ static int readLines(const char * file, int num) close(fd); return -1; } - lineCount++; charCount += bufUsed; } @@ -894,50 +764,45 @@ static int readLines(const char * file, int num) * 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) +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"); + if (bad_nums(num1, num2, "write")) return FALSE; - } lineCount = 0; charCount = 0; fd = creat(file, 0666); - if (fd < 0) { - perror(file); + bb_simple_perror_msg(file); return FALSE; } printf("\"%s\", ", file); - fflush(stdout); + fflush_all(); lp = findLine(num1); - if (lp == NULL) { close(fd); return FALSE; } while (num1++ <= num2) { - if (write(fd, lp->data, lp->len) != lp->len) { - perror(file); + 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) { - perror(file); + bb_simple_perror_msg(file); return FALSE; } @@ -958,22 +823,18 @@ static int printLines(int num1, int num2, int expandFlag) const char *cp; int ch, count; - if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) { - bb_error_msg("bad line range for print"); + 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); + write(STDOUT_FILENO, lp->data, lp->len); setCurNum(num1++); lp = lp->next; - continue; } @@ -988,24 +849,8 @@ static int printLines(int num1, int num2, int expandFlag) 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); + ch = (unsigned char) *cp++; + fputc_printable(ch | PRINTABLE_META, stdout); } fputs("$\n", stdout); @@ -1025,7 +870,7 @@ static int printLines(int num1, int num2, int expandFlag) * 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) +static int insertLine(int num, const char *data, int len) { LINE *newLp, *lp; @@ -1034,12 +879,7 @@ static int insertLine(int num, const char * data, int len) return FALSE; } - newLp = malloc(sizeof(LINE) + len - 1); - - if (newLp == NULL) { - bb_error_msg("failed to allocate memory for line"); - return FALSE; - } + newLp = xmalloc(sizeof(LINE) + len - 1); memcpy(newLp->data, data, len); newLp->len = len; @@ -1048,7 +888,6 @@ static int insertLine(int num, const char * data, int len) lp = &lines; else { lp = findLine(num); - if (lp == NULL) { free((char *) newLp); return FALSE; @@ -1069,20 +908,17 @@ static int insertLine(int num, const char * data, int len) /* * Delete lines from the given range. */ -static int deleteLines(int num1, int num2) +static void 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; - } + if (bad_nums(num1, num2, "delete")) + return; lp = findLine(num1); - if (lp == NULL) - return FALSE; + return; if ((curNum >= num1) && (curNum <= num2)) { if (num2 < lastNum) @@ -1094,10 +930,8 @@ static int deleteLines(int num1, int num2) } count = num2 - num1 + 1; - if (curNum > num2) curNum -= count; - lastNum -= count; while (count-- > 0) { @@ -1105,42 +939,34 @@ static int deleteLines(int num1, int num2) 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 + * 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 int searchLines(const char *str, int num1, int num2) +static NOINLINE 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"); + 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; } @@ -1150,19 +976,17 @@ static int searchLines(const char *str, int num1, int num2) 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); + bb_error_msg("can't find string \"%s\"", str); return 0; } @@ -1190,12 +1014,10 @@ static LINE *findLine(int num) lp = curLine; lnum = curNum; - if (num < (curNum / 2)) { lp = lines.next; lnum = 1; - } - else if (num > ((curNum + lastNum) / 2)) { + } else if (num > ((curNum + lastNum) / 2)) { lp = lines.prev; lnum = lastNum; } @@ -1222,10 +1044,8 @@ static int setCurNum(int num) LINE *lp; lp = findLine(num); - if (lp == NULL) return FALSE; - curNum = num; curLine = lp; return TRUE;