ed: large cleanup
No binary (build failed)
—
(log yok)
| @@ -9,6 +9,14 @@ | |
| #include "libbb.h" | |
| + | typedef struct LINE { |
| + | struct LINE *next; |
| + | struct LINE *prev; |
| + | int len; |
| + | char data[1]; |
| + | } LINE; |
| + | |
| + | |
| #define searchString bb_common_bufsiz1 | |
| enum { | |
| @@ -17,64 +25,92 @@ enum { | |
| INITBUF_SIZE = 1024, /* initial buffer size */ | |
| }; | |
| - | typedef struct LINE { |
| - | struct LINE *next; |
| - | struct LINE *prev; |
| - | int len; |
| - | char data[1]; |
| - | } LINE; |
| + | 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 { \ |
| + | PTR_TO_GLOBALS = xzalloc(sizeof(G)); \ |
| + | } while (0) |
| - | static LINE lines, *curLine; |
| - | static int curNum, lastNum, marks[26], dirty; |
| - | static char *bufBase, *bufPtr, *fileName; |
| - | 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 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); | |
| + | |
| + | 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) |
| + | { |
| + | // NB: fix comment in skip_whitespace! |
| + | while (isblank(*cp)) |
| + | cp++; |
| + | return (char *)cp; |
| + | } |
| + | |
| + | |
| 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]); |
| + | INIT_G(); |
| - | if (fileName == NULL) { |
| - | bb_error_msg("no memory"); |
| - | termEdit(); |
| - | return EXIT_SUCCESS; |
| - | } |
| + | bufSize = INITBUF_SIZE; |
| + | bufBase = xmalloc(bufSize); |
| + | bufPtr = bufBase; |
| + | lines.next = &lines; |
| + | lines.prev = &lines; |
| + | if (argc > 1) { |
| + | fileName = xstrdup(argv[1]); |
| if (!readLines(fileName, 1)) { | |
| - | termEdit(); |
| return EXIT_SUCCESS; | |
| } | |
| - | |
| if (lastNum) | |
| setCurNum(1); | |
| - | |
| dirty = FALSE; | |
| } | |
| doCommands(); | |
| - | |
| - | termEdit(); |
| return EXIT_SUCCESS; | |
| } | |
| @@ -85,42 +121,25 @@ static void doCommands(void) | |
| { | |
| const char *cp; | |
| char *endbuf, *newname, buf[USERSIZE]; | |
| - | int len, num1, num2, have1, have2; |
| + | 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) |
| + | // NB: fix comment in lineedit.c! |
| + | /* 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(": ", buf, sizeof(buf), NULL); |
| + | 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; | |
| @@ -132,28 +151,21 @@ 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; | |
| @@ -176,10 +188,7 @@ static void doCommands(void) | |
| bb_error_msg("bad file command"); | |
| break; | |
| } | |
| - | |
| - | while (isblank(*cp)) |
| - | cp++; |
| - | |
| + | cp = skip_blank(cp); |
| if (*cp == '\0') { | |
| if (fileName) | |
| printf("\"%s\"\n", fileName); | |
| @@ -187,17 +196,12 @@ static void doCommands(void) | |
| 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); |
| - | |
| + | free(fileName); |
| fileName = newname; | |
| break; | |
| @@ -206,14 +210,11 @@ static void doCommands(void) | |
| break; | |
| case 'k': | |
| - | while (isblank(*cp)) |
| - | cp++; |
| - | |
| - | if ((*cp < 'a') || (*cp > 'a') || cp[1]) { |
| + | cp = skip_blank(cp); |
| + | if ((*cp < 'a') || (*cp > 'z') || cp[1]) { |
| bb_error_msg("bad mark name"); | |
| break; | |
| } | |
| - | |
| marks[*cp - 'a'] = num2; | |
| break; | |
| @@ -226,30 +227,20 @@ static void doCommands(void) | |
| break; | |
| case 'q': | |
| - | while (isblank(*cp)) |
| - | cp++; |
| - | |
| + | cp = skip_blank(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')) |
| + | len = read_line_input("Really quit? ", buf, 16, NULL); |
| + | /* 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': | |
| @@ -257,24 +248,17 @@ static void doCommands(void) | |
| bb_error_msg("bad read command"); | |
| break; | |
| } | |
| - | |
| - | while (isblank(*cp)) |
| - | cp++; |
| - | |
| + | 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 = strdup(cp); | |
| - | |
| break; | |
| case 's': | |
| @@ -286,36 +270,30 @@ static void doCommands(void) | |
| bb_error_msg("bad write command"); | |
| break; | |
| } | |
| - | |
| - | while (isblank(*cp)) |
| - | cp++; |
| - | |
| + | 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); |
| + | printLines(curNum - 21, curNum, FALSE); |
| break; | |
| case '.': | |
| - | printLines(curNum-11, curNum+10, FALSE); |
| + | printLines(curNum - 11, curNum + 10, FALSE); |
| break; | |
| default: | |
| - | printLines(curNum, curNum+21, FALSE); |
| + | printLines(curNum, curNum + 21, FALSE); |
| break; | |
| } | |
| break; | |
| @@ -325,29 +303,24 @@ static void doCommands(void) | |
| 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: | |
| @@ -362,17 +335,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; | |
| @@ -394,7 +365,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; | |
| @@ -414,11 +384,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; | |
| @@ -429,7 +397,6 @@ static void subCommand(const char * cmd, int num1, int num2) | |
| bb_error_msg("no previous search string"); | |
| return; | |
| } | |
| - | |
| oldStr = searchString; | |
| } | |
| @@ -437,7 +404,6 @@ static void subCommand(const char * cmd, int num1, int num2) | |
| strcpy(searchString, oldStr); | |
| lp = findLine(num1); | |
| - | |
| if (lp == NULL) | |
| return; | |
| @@ -455,11 +421,9 @@ static void subCommand(const char * cmd, int num1, int num2) | |
| printLines(num1, num1, FALSE); | |
| needPrint = FALSE; | |
| } | |
| - | |
| offset = 0; | |
| lp = lp->next; | |
| num1++; | |
| - | |
| continue; | |
| } | |
| @@ -473,7 +437,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], | |
| @@ -481,20 +444,15 @@ 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; | |
| } | |
| @@ -503,8 +461,7 @@ static void subCommand(const char * cmd, int num1, int num2) | |
| * structure and use that. Link it in in place of | |
| * the old line structure. | |
| */ | |
| - | nlp = (LINE *) malloc(sizeof(LINE) + lp->len + deltaLen); |
| - | |
| + | nlp = malloc(sizeof(LINE) + lp->len + deltaLen); |
| if (nlp == NULL) { | |
| bb_error_msg("cannot get memory for line"); | |
| return; | |
| @@ -513,9 +470,7 @@ static void subCommand(const char * cmd, int num1, int num2) | |
| 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); | |
| @@ -554,7 +509,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; | |
| @@ -564,20 +519,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--; | |
| } | |
| @@ -597,23 +546,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("", buf, sizeof(buf), NULL); |
| + | 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; | |
| } | |
| @@ -628,20 +574,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 '.': | |
| @@ -658,12 +604,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; | |
| @@ -671,19 +615,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; | |
| @@ -694,29 +633,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; | |
| @@ -730,75 +665,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; | |
| @@ -810,7 +681,6 @@ static int readLines(const char * file, int num) | |
| } | |
| fd = open(file, 0); | |
| - | |
| if (fd < 0) { | |
| perror(file); | |
| return FALSE; | |
| @@ -830,18 +700,15 @@ static int readLines(const char * file, int num) | |
| if (cp) { | |
| len = (cp - bufPtr) + 1; | |
| - | |
| if (!insertLine(num, bufPtr, len)) { | |
| close(fd); | |
| return FALSE; | |
| } | |
| - | |
| bufPtr += len; | |
| bufUsed -= len; | |
| charCount += len; | |
| lineCount++; | |
| num++; | |
| - | |
| continue; | |
| } | |
| @@ -853,19 +720,17 @@ 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; | |
| } | |
| - | |
| bufBase = cp; | |
| bufPtr = bufBase + bufUsed; | |
| bufSize = len; | |
| } | |
| - | cc = read(fd, bufPtr, bufSize - bufUsed); |
| + | cc = safe_read(fd, bufPtr, bufSize - bufUsed); |
| bufUsed += cc; | |
| bufPtr = bufBase; | |
| @@ -882,7 +747,6 @@ static int readLines(const char * file, int num) | |
| close(fd); | |
| return -1; | |
| } | |
| - | |
| lineCount++; | |
| charCount += bufUsed; | |
| } | |
| @@ -900,21 +764,18 @@ 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); | |
| return FALSE; | |
| @@ -924,19 +785,17 @@ static int writeLines(const char * file, int num1, int num2) | |
| fflush(stdout); | |
| lp = findLine(num1); | |
| - | |
| if (lp == NULL) { | |
| close(fd); | |
| return FALSE; | |
| } | |
| while (num1++ <= num2) { | |
| - | if (write(fd, lp->data, lp->len) != lp->len) { |
| + | if (full_write(fd, lp->data, lp->len) != lp->len) { |
| perror(file); | |
| close(fd); | |
| return FALSE; | |
| } | |
| - | |
| charCount += lp->len; | |
| lineCount++; | |
| lp = lp->next; | |
| @@ -964,13 +823,10 @@ 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; | |
| @@ -979,7 +835,6 @@ static int printLines(int num1, int num2, int expandFlag) | |
| write(1, lp->data, lp->len); | |
| setCurNum(num1++); | |
| lp = lp->next; | |
| - | |
| continue; | |
| } | |
| @@ -995,22 +850,18 @@ static int printLines(int num1, int num2, int expandFlag) | |
| 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); | |
| } | |
| @@ -1031,7 +882,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; | |
| @@ -1041,7 +892,6 @@ static int insertLine(int num, const char * data, int len) | |
| } | |
| newLp = malloc(sizeof(LINE) + len - 1); | |
| - | |
| if (newLp == NULL) { | |
| bb_error_msg("failed to allocate memory for line"); | |
| return FALSE; | |
| @@ -1054,7 +904,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; | |
| @@ -1075,20 +924,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) | |
| @@ -1100,10 +946,8 @@ static int deleteLines(int num1, int num2) | |
| } | |
| count = num2 - num1 + 1; | |
| - | |
| if (curNum > num2) | |
| curNum -= count; | |
| - | |
| lastNum -= count; | |
| while (count-- > 0) { | |
| @@ -1111,22 +955,17 @@ 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. | |
| @@ -1136,17 +975,14 @@ 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"); |
| + | 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; | |
| } | |
| @@ -1156,14 +992,12 @@ 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; | |
| } | |
| @@ -1196,12 +1030,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; | |
| } | |
| @@ -1228,10 +1060,8 @@ static int setCurNum(int num) | |
| LINE *lp; | |
| lp = findLine(num); | |
| - | |
| if (lp == NULL) | |
| return FALSE; | |
| - | |
| curNum = num; | |
| curLine = lp; | |
| return TRUE; | |