Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/editors/ed.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/editors/ed.c
r1765 r2725 9 9 10 10 #include "libbb.h" 11 12 #define searchString bb_common_bufsiz113 14 enum {15 USERSIZE = sizeof(searchString) > 1024 ? 102416 : sizeof(searchString) - 1, /* max line length typed in by user */17 INITBUF_SIZE = 1024, /* initial buffer size */18 };19 11 20 12 typedef struct LINE { … … 25 17 } LINE; 26 18 27 static LINE lines, *curLine; 28 static int curNum, lastNum, marks[26], dirty; 29 static char *bufBase, *bufPtr, *fileName; 30 static int bufUsed, bufSize; 19 20 #define searchString bb_common_bufsiz1 21 22 enum { 23 USERSIZE = sizeof(searchString) > 1024 ? 1024 24 : sizeof(searchString) - 1, /* max line length typed in by user */ 25 INITBUF_SIZE = 1024, /* initial buffer size */ 26 }; 27 28 struct globals { 29 int curNum; 30 int lastNum; 31 int bufUsed; 32 int bufSize; 33 LINE *curLine; 34 char *bufBase; 35 char *bufPtr; 36 char *fileName; 37 LINE lines; 38 smallint dirty; 39 int marks[26]; 40 }; 41 #define G (*ptr_to_globals) 42 #define curLine (G.curLine ) 43 #define bufBase (G.bufBase ) 44 #define bufPtr (G.bufPtr ) 45 #define fileName (G.fileName ) 46 #define curNum (G.curNum ) 47 #define lastNum (G.lastNum ) 48 #define bufUsed (G.bufUsed ) 49 #define bufSize (G.bufSize ) 50 #define dirty (G.dirty ) 51 #define lines (G.lines ) 52 #define marks (G.marks ) 53 #define INIT_G() do { \ 54 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 55 } while (0) 56 31 57 32 58 static void doCommands(void); 33 59 static void subCommand(const char *cmd, int num1, int num2); 34 static int getNum(const char **retcp, int *retHaveNum, int *retNum);60 static int getNum(const char **retcp, smallint *retHaveNum, int *retNum); 35 61 static int setCurNum(int num); 36 static int initEdit(void);37 static void termEdit(void);38 62 static void addLines(int num); 39 63 static int insertLine(int num, const char *data, int len); 40 static intdeleteLines(int num1, int num2);64 static void deleteLines(int num1, int num2); 41 65 static int printLines(int num1, int num2, int expandFlag); 42 66 static int writeLines(const char *file, int num1, int num2); … … 44 68 static int searchLines(const char *str, int num1, int num2); 45 69 static LINE *findLine(int num); 46 47 70 static int findString(const LINE *lp, const char * str, int len, int offset); 48 71 49 int ed_main(int argc, char **argv); 50 int ed_main(int argc, char **argv) 51 { 52 if (!initEdit()) 53 return EXIT_FAILURE; 54 55 if (argc > 1) { 56 fileName = strdup(argv[1]); 57 58 if (fileName == NULL) { 59 bb_error_msg("no memory"); 60 termEdit(); 72 73 static int bad_nums(int num1, int num2, const char *for_what) 74 { 75 if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) { 76 bb_error_msg("bad line range for %s", for_what); 77 return 1; 78 } 79 return 0; 80 } 81 82 83 static char *skip_blank(const char *cp) 84 { 85 while (isblank(*cp)) 86 cp++; 87 return (char *)cp; 88 } 89 90 91 int ed_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 92 int ed_main(int argc UNUSED_PARAM, char **argv) 93 { 94 INIT_G(); 95 96 bufSize = INITBUF_SIZE; 97 bufBase = xmalloc(bufSize); 98 bufPtr = bufBase; 99 lines.next = &lines; 100 lines.prev = &lines; 101 102 if (argv[1]) { 103 fileName = xstrdup(argv[1]); 104 if (!readLines(fileName, 1)) { 61 105 return EXIT_SUCCESS; 62 106 } 63 64 if (!readLines(fileName, 1)) {65 termEdit();66 return EXIT_SUCCESS;67 }68 69 107 if (lastNum) 70 108 setCurNum(1); 71 72 109 dirty = FALSE; 73 110 } 74 111 75 112 doCommands(); 76 77 termEdit();78 113 return EXIT_SUCCESS; 79 114 } … … 85 120 { 86 121 const char *cp; 87 char *endbuf, *newname, buf[USERSIZE]; 88 int len, num1, num2, have1, have2; 122 char *endbuf, buf[USERSIZE]; 123 int len, num1, num2; 124 smallint have1, have2; 89 125 90 126 while (TRUE) { 91 printf(": "); 92 fflush(stdout); 93 94 if (fgets(buf, sizeof(buf), stdin) == NULL) 127 /* Returns: 128 * -1 on read errors or EOF, or on bare Ctrl-D. 129 * 0 on ctrl-C, 130 * >0 length of input string, including terminating '\n' 131 */ 132 len = read_line_input(": ", buf, sizeof(buf), NULL); 133 if (len <= 0) 95 134 return; 96 97 len = strlen(buf);98 99 if (len == 0)100 return;101 102 135 endbuf = &buf[len - 1]; 103 104 if (*endbuf != '\n') {105 bb_error_msg("command line too long");106 107 do {108 len = fgetc(stdin);109 } while ((len != EOF) && (len != '\n'));110 111 continue;112 }113 114 136 while ((endbuf > buf) && isblank(endbuf[-1])) 115 137 endbuf--; 116 117 138 *endbuf = '\0'; 118 139 119 cp = buf; 120 121 while (isblank(*cp)) 122 cp++; 123 140 cp = skip_blank(buf); 124 141 have1 = FALSE; 125 142 have2 = FALSE; … … 133 150 continue; 134 151 135 while (isblank(*cp)) 136 cp++; 152 cp = skip_blank(cp); 137 153 138 154 if (*cp == ',') { 139 155 cp++; 140 141 156 if (!getNum(&cp, &have2, &num2)) 142 157 continue; 143 144 158 if (!have1) 145 159 num1 = 1; 146 147 160 if (!have2) 148 161 num2 = lastNum; 149 150 162 have1 = TRUE; 151 163 have2 = TRUE; 152 164 } 153 154 165 if (!have1) 155 166 num1 = curNum; 156 157 167 if (!have2) 158 168 num2 = num1; 159 169 160 170 switch (*cp++) { 161 case 'a': 162 addLines(num1 + 1); 163 break; 164 165 case 'c': 166 deleteLines(num1, num2); 167 addLines(num1); 168 break; 169 170 case 'd': 171 deleteLines(num1, num2); 172 break; 173 174 case 'f': 175 if (*cp && !isblank(*cp)) { 176 bb_error_msg("bad file command"); 177 break; 178 } 179 180 while (isblank(*cp)) 181 cp++; 182 183 if (*cp == '\0') { 184 if (fileName) 185 printf("\"%s\"\n", fileName); 186 else 187 printf("No file name\n"); 188 break; 189 } 190 191 newname = strdup(cp); 192 193 if (newname == NULL) { 194 bb_error_msg("no memory for file name"); 195 break; 196 } 197 171 case 'a': 172 addLines(num1 + 1); 173 break; 174 175 case 'c': 176 deleteLines(num1, num2); 177 addLines(num1); 178 break; 179 180 case 'd': 181 deleteLines(num1, num2); 182 break; 183 184 case 'f': 185 if (*cp && !isblank(*cp)) { 186 bb_error_msg("bad file command"); 187 break; 188 } 189 cp = skip_blank(cp); 190 if (*cp == '\0') { 198 191 if (fileName) 199 free(fileName); 200 201 fileName = newname; 202 break; 203 204 case 'i': 205 addLines(num1); 206 break; 207 208 case 'k': 209 while (isblank(*cp)) 210 cp++; 211 212 if ((*cp < 'a') || (*cp > 'a') || cp[1]) { 213 bb_error_msg("bad mark name"); 214 break; 215 } 216 217 marks[*cp - 'a'] = num2; 218 break; 219 220 case 'l': 221 printLines(num1, num2, TRUE); 222 break; 223 224 case 'p': 225 printLines(num1, num2, FALSE); 226 break; 227 228 case 'q': 229 while (isblank(*cp)) 230 cp++; 231 232 if (have1 || *cp) { 233 bb_error_msg("bad quit command"); 234 break; 235 } 236 237 if (!dirty) 238 return; 239 240 printf("Really quit? "); 241 fflush(stdout); 242 243 buf[0] = '\0'; 244 fgets(buf, sizeof(buf), stdin); 245 cp = buf; 246 247 while (isblank(*cp)) 248 cp++; 249 250 if ((*cp == 'y') || (*cp == 'Y')) 251 return; 252 253 break; 254 255 case 'r': 256 if (*cp && !isblank(*cp)) { 257 bb_error_msg("bad read command"); 258 break; 259 } 260 261 while (isblank(*cp)) 262 cp++; 263 264 if (*cp == '\0') { 265 bb_error_msg("no file name"); 266 break; 267 } 268 269 if (!have1) 270 num1 = lastNum; 271 272 if (readLines(cp, num1 + 1)) 273 break; 274 275 if (fileName == NULL) 276 fileName = strdup(cp); 277 278 break; 279 280 case 's': 281 subCommand(cp, num1, num2); 282 break; 283 284 case 'w': 285 if (*cp && !isblank(*cp)) { 286 bb_error_msg("bad write command"); 287 break; 288 } 289 290 while (isblank(*cp)) 291 cp++; 292 293 if (!have1) { 294 num1 = 1; 295 num2 = lastNum; 296 } 297 298 if (*cp == '\0') 299 cp = fileName; 300 301 if (cp == NULL) { 302 bb_error_msg("no file name specified"); 303 break; 304 } 305 306 writeLines(cp, num1, num2); 307 break; 308 309 case 'z': 310 switch (*cp) { 311 case '-': 312 printLines(curNum-21, curNum, FALSE); 313 break; 314 case '.': 315 printLines(curNum-11, curNum+10, FALSE); 316 break; 317 default: 318 printLines(curNum, curNum+21, FALSE); 319 break; 320 } 321 break; 322 192 printf("\"%s\"\n", fileName); 193 else 194 printf("No file name\n"); 195 break; 196 } 197 free(fileName); 198 fileName = xstrdup(cp); 199 break; 200 201 case 'i': 202 addLines(num1); 203 break; 204 205 case 'k': 206 cp = skip_blank(cp); 207 if ((*cp < 'a') || (*cp > 'z') || cp[1]) { 208 bb_error_msg("bad mark name"); 209 break; 210 } 211 marks[*cp - 'a'] = num2; 212 break; 213 214 case 'l': 215 printLines(num1, num2, TRUE); 216 break; 217 218 case 'p': 219 printLines(num1, num2, FALSE); 220 break; 221 222 case 'q': 223 cp = skip_blank(cp); 224 if (have1 || *cp) { 225 bb_error_msg("bad quit command"); 226 break; 227 } 228 if (!dirty) 229 return; 230 len = read_line_input("Really quit? ", buf, 16, NULL); 231 /* read error/EOF - no way to continue */ 232 if (len < 0) 233 return; 234 cp = skip_blank(buf); 235 if ((*cp | 0x20) == 'y') /* Y or y */ 236 return; 237 break; 238 239 case 'r': 240 if (*cp && !isblank(*cp)) { 241 bb_error_msg("bad read command"); 242 break; 243 } 244 cp = skip_blank(cp); 245 if (*cp == '\0') { 246 bb_error_msg("no file name"); 247 break; 248 } 249 if (!have1) 250 num1 = lastNum; 251 if (readLines(cp, num1 + 1)) 252 break; 253 if (fileName == NULL) 254 fileName = xstrdup(cp); 255 break; 256 257 case 's': 258 subCommand(cp, num1, num2); 259 break; 260 261 case 'w': 262 if (*cp && !isblank(*cp)) { 263 bb_error_msg("bad write command"); 264 break; 265 } 266 cp = skip_blank(cp); 267 if (!have1) { 268 num1 = 1; 269 num2 = lastNum; 270 } 271 if (*cp == '\0') 272 cp = fileName; 273 if (cp == NULL) { 274 bb_error_msg("no file name specified"); 275 break; 276 } 277 writeLines(cp, num1, num2); 278 break; 279 280 case 'z': 281 switch (*cp) { 282 case '-': 283 printLines(curNum - 21, curNum, FALSE); 284 break; 323 285 case '.': 324 if (have1) { 325 bb_error_msg("no arguments allowed"); 326 break; 327 } 328 286 printLines(curNum - 11, curNum + 10, FALSE); 287 break; 288 default: 289 printLines(curNum, curNum + 21, FALSE); 290 break; 291 } 292 break; 293 294 case '.': 295 if (have1) { 296 bb_error_msg("no arguments allowed"); 297 break; 298 } 299 printLines(curNum, curNum, FALSE); 300 break; 301 302 case '-': 303 if (setCurNum(curNum - 1)) 329 304 printLines(curNum, curNum, FALSE); 330 break; 331 332 case '-': 333 if (setCurNum(curNum - 1)) 334 printLines(curNum, curNum, FALSE); 335 336 break; 337 338 case '=': 339 printf("%d\n", num1); 340 break; 341 342 case '\0': 343 if (have1) { 344 printLines(num2, num2, FALSE); 345 break; 346 } 347 348 if (setCurNum(curNum + 1)) 349 printLines(curNum, curNum, FALSE); 350 351 break; 352 353 default: 354 bb_error_msg("unimplemented command"); 355 break; 305 break; 306 307 case '=': 308 printf("%d\n", num1); 309 break; 310 case '\0': 311 if (have1) { 312 printLines(num2, num2, FALSE); 313 break; 314 } 315 if (setCurNum(curNum + 1)) 316 printLines(curNum, curNum, FALSE); 317 break; 318 319 default: 320 bb_error_msg("unimplemented command"); 321 break; 356 322 } 357 323 } … … 363 329 * The current line is set to the last substitution done. 364 330 */ 365 static void subCommand(const char * 331 static void subCommand(const char *cmd, int num1, int num2) 366 332 { 367 333 char *cp, *oldStr, *newStr, buf[USERSIZE]; … … 370 336 int globalFlag, printFlag, didSub, needPrint; 371 337 372 if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) { 373 bb_error_msg("bad line range for substitute"); 338 if (bad_nums(num1, num2, "substitute")) 374 339 return; 375 }376 340 377 341 globalFlag = FALSE; … … 395 359 396 360 cp = strchr(cp, delim); 397 398 361 if (cp == NULL) { 399 362 bb_error_msg("missing 2nd delimiter for substitute"); … … 415 378 globalFlag = TRUE; 416 379 break; 417 418 380 case 'p': 419 381 printFlag = TRUE; 420 382 break; 421 422 383 default: 423 384 bb_error_msg("unknown option for substitute"); … … 430 391 return; 431 392 } 432 433 393 oldStr = searchString; 434 394 } … … 438 398 439 399 lp = findLine(num1); 440 441 400 if (lp == NULL) 442 401 return; … … 456 415 needPrint = FALSE; 457 416 } 458 459 417 offset = 0; 460 418 lp = lp->next; 461 419 num1++; 462 463 420 continue; 464 421 } … … 474 431 if (deltaLen <= 0) { 475 432 memcpy(&lp->data[offset], newStr, newLen); 476 477 433 if (deltaLen) { 478 434 memcpy(&lp->data[offset + newLen], … … 482 438 lp->len += deltaLen; 483 439 } 484 485 440 offset += newLen; 486 487 441 if (globalFlag) 488 442 continue; 489 490 443 if (needPrint) { 491 444 printLines(num1, num1, FALSE); 492 445 needPrint = FALSE; 493 446 } 494 495 447 lp = lp->next; 496 448 num1++; 497 498 449 continue; 499 450 } … … 504 455 * the old line structure. 505 456 */ 506 nlp = (LINE *) malloc(sizeof(LINE) + lp->len + deltaLen); 507 508 if (nlp == NULL) { 509 bb_error_msg("cannot get memory for line"); 510 return; 511 } 457 nlp = xmalloc(sizeof(LINE) + lp->len + deltaLen); 512 458 513 459 nlp->len = lp->len + deltaLen; 514 460 515 461 memcpy(nlp->data, lp->data, offset); 516 517 462 memcpy(&nlp->data[offset], newStr, newLen); 518 519 463 memcpy(&nlp->data[offset + newLen], 520 464 &lp->data[offset + oldLen], … … 555 499 * offset in the line. Returns the offset of the found string, or -1. 556 500 */ 557 static int findString( const LINE * lp, const char *str, int len, int offset)501 static int findString(const LINE *lp, const char *str, int len, int offset) 558 502 { 559 503 int left; … … 565 509 while (left >= len) { 566 510 ncp = memchr(cp, *str, left); 567 568 511 if (ncp == NULL) 569 512 return -1; 570 571 513 left -= (ncp - cp); 572 573 514 if (left < len) 574 515 return -1; 575 576 516 cp = ncp; 577 578 517 if (memcmp(cp, str, len) == 0) 579 518 return (cp - lp->data); 580 581 519 cp++; 582 520 left--; … … 598 536 char buf[USERSIZE + 1]; 599 537 600 while (fgets(buf, sizeof(buf), stdin)) { 538 while (1) { 539 /* Returns: 540 * -1 on read errors or EOF, or on bare Ctrl-D. 541 * 0 on ctrl-C, 542 * >0 length of input string, including terminating '\n' 543 */ 544 len = read_line_input("", buf, sizeof(buf), NULL); 545 if (len <= 0) { 546 /* Previously, ctrl-C was exiting to shell. 547 * Now we exit to ed prompt. Is in important? */ 548 return; 549 } 601 550 if ((buf[0] == '.') && (buf[1] == '\n') && (buf[2] == '\0')) 602 551 return; 603 604 len = strlen(buf);605 606 if (len == 0)607 return;608 609 if (buf[len - 1] != '\n') {610 bb_error_msg("line too long");611 do {612 len = fgetc(stdin);613 } while ((len != EOF) && (len != '\n'));614 return;615 }616 617 552 if (!insertLine(num++, buf, len)) 618 553 return; … … 629 564 * The character pointer which stopped the scan is also returned. 630 565 */ 631 static int getNum(const char **retcp, int *retHaveNum, int *retNum)566 static int getNum(const char **retcp, smallint *retHaveNum, int *retNum) 632 567 { 633 568 const char *cp; 634 569 char *endStr, str[USERSIZE]; 635 int haveNum, value, num, sign; 570 int value, num; 571 smallint haveNum, minus; 636 572 637 573 cp = *retcp; 574 value = 0; 638 575 haveNum = FALSE; 639 value = 0; 640 sign = 1; 576 minus = 0; 641 577 642 578 while (TRUE) { 643 while (isblank(*cp)) 644 cp++; 579 cp = skip_blank(cp); 645 580 646 581 switch (*cp) { … … 659 594 case '\'': 660 595 cp++; 661 662 596 if ((*cp < 'a') || (*cp > 'z')) { 663 597 bb_error_msg("bad mark name"); 664 598 return FALSE; 665 599 } 666 667 600 haveNum = TRUE; 668 601 num = marks[*cp++ - 'a']; … … 672 605 strcpy(str, ++cp); 673 606 endStr = strchr(str, '/'); 674 675 607 if (endStr) { 676 608 *endStr++ = '\0'; 677 609 cp += (endStr - str); 678 } 679 else 610 } else 680 611 cp = ""; 681 682 612 num = searchLines(str, curNum, lastNum); 683 684 613 if (num == 0) 685 614 return FALSE; 686 687 615 haveNum = TRUE; 688 616 break; … … 695 623 return TRUE; 696 624 } 697 698 625 num = 0; 699 700 626 while (isdigit(*cp)) 701 627 num = num * 10 + *cp++ - '0'; 702 703 628 haveNum = TRUE; 704 629 break; 705 630 } 706 631 707 value += num * sign; 708 709 while (isblank(*cp)) 710 cp++; 632 value += (minus ? -num : num); 633 634 cp = skip_blank(cp); 711 635 712 636 switch (*cp) { 713 637 case '-': 714 sign = -1;638 minus = 1; 715 639 cp++; 716 640 break; 717 641 718 642 case '+': 719 sign = 1;643 minus = 0; 720 644 cp++; 721 645 break; … … 732 656 733 657 /* 734 * Initialize everything for editing.735 */736 static int initEdit(void)737 {738 int i;739 740 bufSize = INITBUF_SIZE;741 bufBase = malloc(bufSize);742 743 if (bufBase == NULL) {744 bb_error_msg("no memory for buffer");745 return FALSE;746 }747 748 bufPtr = bufBase;749 bufUsed = 0;750 751 lines.next = &lines;752 lines.prev = &lines;753 754 curLine = NULL;755 curNum = 0;756 lastNum = 0;757 dirty = FALSE;758 fileName = NULL;759 searchString[0] = '\0';760 761 for (i = 0; i < 26; i++)762 marks[i] = 0;763 764 return TRUE;765 }766 767 768 /*769 * Finish editing.770 */771 static void termEdit(void)772 {773 if (bufBase)774 free(bufBase);775 776 bufBase = NULL;777 bufPtr = NULL;778 bufSize = 0;779 bufUsed = 0;780 781 if (fileName)782 free(fileName);783 784 fileName = NULL;785 786 searchString[0] = '\0';787 788 if (lastNum)789 deleteLines(1, lastNum);790 791 lastNum = 0;792 curNum = 0;793 curLine = NULL;794 }795 796 797 /*798 658 * Read lines from a file at the specified line number. 799 659 * Returns TRUE if the file was successfully read. 800 660 */ 801 static int readLines(const char * 661 static int readLines(const char *file, int num) 802 662 { 803 663 int fd, cc; … … 811 671 812 672 fd = open(file, 0); 813 814 673 if (fd < 0) { 815 perror(file);674 bb_simple_perror_msg(file); 816 675 return FALSE; 817 676 } … … 824 683 825 684 printf("\"%s\", ", file); 826 fflush (stdout);685 fflush_all(); 827 686 828 687 do { … … 831 690 if (cp) { 832 691 len = (cp - bufPtr) + 1; 833 834 692 if (!insertLine(num, bufPtr, len)) { 835 693 close(fd); 836 694 return FALSE; 837 695 } 838 839 696 bufPtr += len; 840 697 bufUsed -= len; … … 842 699 lineCount++; 843 700 num++; 844 845 701 continue; 846 702 } … … 853 709 if (bufUsed >= bufSize) { 854 710 len = (bufSize * 3) / 2; 855 cp = realloc(bufBase, len); 856 857 if (cp == NULL) { 858 bb_error_msg("no memory for buffer"); 859 close(fd); 860 return FALSE; 861 } 862 711 cp = xrealloc(bufBase, len); 863 712 bufBase = cp; 864 713 bufPtr = bufBase + bufUsed; … … 866 715 } 867 716 868 cc = read(fd, bufPtr, bufSize - bufUsed);717 cc = safe_read(fd, bufPtr, bufSize - bufUsed); 869 718 bufUsed += cc; 870 719 bufPtr = bufBase; … … 873 722 874 723 if (cc < 0) { 875 perror(file);724 bb_simple_perror_msg(file); 876 725 close(fd); 877 726 return FALSE; … … 883 732 return -1; 884 733 } 885 886 734 lineCount++; 887 735 charCount += bufUsed; … … 901 749 * Returns TRUE if successful, or FALSE on an error with a message output. 902 750 */ 903 static int writeLines(const char * 751 static int writeLines(const char *file, int num1, int num2) 904 752 { 905 753 LINE *lp; 906 754 int fd, lineCount, charCount; 907 755 908 if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) { 909 bb_error_msg("bad line range for write"); 756 if (bad_nums(num1, num2, "write")) 910 757 return FALSE; 911 }912 758 913 759 lineCount = 0; … … 915 761 916 762 fd = creat(file, 0666); 917 918 763 if (fd < 0) { 919 perror(file);764 bb_simple_perror_msg(file); 920 765 return FALSE; 921 766 } 922 767 923 768 printf("\"%s\", ", file); 924 fflush (stdout);769 fflush_all(); 925 770 926 771 lp = findLine(num1); 927 928 772 if (lp == NULL) { 929 773 close(fd); … … 932 776 933 777 while (num1++ <= num2) { 934 if ( write(fd, lp->data, lp->len) != lp->len) {935 perror(file);778 if (full_write(fd, lp->data, lp->len) != lp->len) { 779 bb_simple_perror_msg(file); 936 780 close(fd); 937 781 return FALSE; 938 782 } 939 940 783 charCount += lp->len; 941 784 lineCount++; … … 944 787 945 788 if (close(fd) < 0) { 946 perror(file);789 bb_simple_perror_msg(file); 947 790 return FALSE; 948 791 } … … 965 808 int ch, count; 966 809 967 if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) { 968 bb_error_msg("bad line range for print"); 810 if (bad_nums(num1, num2, "print")) 969 811 return FALSE; 970 }971 812 972 813 lp = findLine(num1); 973 974 814 if (lp == NULL) 975 815 return FALSE; … … 977 817 while (num1 <= num2) { 978 818 if (!expandFlag) { 979 write( 1, lp->data, lp->len);819 write(STDOUT_FILENO, lp->data, lp->len); 980 820 setCurNum(num1++); 981 821 lp = lp->next; 982 983 822 continue; 984 823 } … … 995 834 996 835 while (count-- > 0) { 997 ch = *cp++; 998 999 if (ch & 0x80) { 1000 fputs("M-", stdout); 1001 ch &= 0x7f; 1002 } 1003 1004 if (ch < ' ') { 1005 fputc('^', stdout); 1006 ch += '@'; 1007 } 1008 1009 if (ch == 0x7f) { 1010 fputc('^', stdout); 1011 ch = '?'; 1012 } 1013 1014 fputc(ch, stdout); 836 ch = (unsigned char) *cp++; 837 fputc_printable(ch | PRINTABLE_META, stdout); 1015 838 } 1016 839 … … 1032 855 * Returns TRUE if successful. 1033 856 */ 1034 static int insertLine(int num, const char * 857 static int insertLine(int num, const char *data, int len) 1035 858 { 1036 859 LINE *newLp, *lp; … … 1041 864 } 1042 865 1043 newLp = malloc(sizeof(LINE) + len - 1); 1044 1045 if (newLp == NULL) { 1046 bb_error_msg("failed to allocate memory for line"); 1047 return FALSE; 1048 } 866 newLp = xmalloc(sizeof(LINE) + len - 1); 1049 867 1050 868 memcpy(newLp->data, data, len); … … 1055 873 else { 1056 874 lp = findLine(num); 1057 1058 875 if (lp == NULL) { 1059 876 free((char *) newLp); … … 1076 893 * Delete lines from the given range. 1077 894 */ 1078 static intdeleteLines(int num1, int num2)895 static void deleteLines(int num1, int num2) 1079 896 { 1080 897 LINE *lp, *nlp, *plp; 1081 898 int count; 1082 899 1083 if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) { 1084 bb_error_msg("bad line numbers for delete"); 1085 return FALSE; 1086 } 900 if (bad_nums(num1, num2, "delete")) 901 return; 1087 902 1088 903 lp = findLine(num1); 1089 1090 904 if (lp == NULL) 1091 return FALSE;905 return; 1092 906 1093 907 if ((curNum >= num1) && (curNum <= num2)) { … … 1101 915 1102 916 count = num2 - num1 + 1; 1103 1104 917 if (curNum > num2) 1105 918 curNum -= count; 1106 1107 919 lastNum -= count; 1108 920 … … 1112 924 plp->next = nlp; 1113 925 nlp->prev = plp; 1114 lp->next = NULL;1115 lp->prev = NULL;1116 lp->len = 0;1117 926 free(lp); 1118 927 lp = nlp; … … 1120 929 1121 930 dirty = TRUE; 1122 1123 return TRUE;1124 931 } 1125 932 … … 1127 934 /* 1128 935 * Search for a line which contains the specified string. 1129 * If the string is NULL, then the previously searched for string936 * If the string is "", then the previously searched for string 1130 937 * is used. The currently searched for string is saved for future use. 1131 938 * Returns the line number which matches, or 0 if there was no match 1132 939 * with an error printed. 1133 940 */ 1134 static int searchLines(const char *str, int num1, int num2)941 static NOINLINE int searchLines(const char *str, int num1, int num2) 1135 942 { 1136 943 const LINE *lp; 1137 944 int len; 1138 945 1139 if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) { 1140 bb_error_msg("bad line numbers for search"); 946 if (bad_nums(num1, num2, "search")) 1141 947 return 0; 1142 }1143 948 1144 949 if (*str == '\0') { … … 1147 952 return 0; 1148 953 } 1149 1150 954 str = searchString; 1151 955 } … … 1157 961 1158 962 lp = findLine(num1); 1159 1160 963 if (lp == NULL) 1161 964 return 0; … … 1164 967 if (findString(lp, str, len, 0) >= 0) 1165 968 return num1; 1166 1167 969 num1++; 1168 970 lp = lp->next; 1169 971 } 1170 972 1171 bb_error_msg("can not find string \"%s\"", str);973 bb_error_msg("can't find string \"%s\"", str); 1172 974 return 0; 1173 975 } … … 1197 999 lp = curLine; 1198 1000 lnum = curNum; 1199 1200 1001 if (num < (curNum / 2)) { 1201 1002 lp = lines.next; 1202 1003 lnum = 1; 1203 } 1204 else if (num > ((curNum + lastNum) / 2)) { 1004 } else if (num > ((curNum + lastNum) / 2)) { 1205 1005 lp = lines.prev; 1206 1006 lnum = lastNum; … … 1229 1029 1230 1030 lp = findLine(num); 1231 1232 1031 if (lp == NULL) 1233 1032 return FALSE; 1234 1235 1033 curNum = num; 1236 1034 curLine = lp;
Note:
See TracChangeset
for help on using the changeset viewer.