Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/editors/ed.c


Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/editors/ed.c

    r1765 r2725  
    99
    1010#include "libbb.h"
    11 
    12 #define searchString bb_common_bufsiz1
    13 
    14 enum {
    15     USERSIZE = sizeof(searchString) > 1024 ? 1024
    16              : sizeof(searchString) - 1, /* max line length typed in by user */
    17     INITBUF_SIZE = 1024, /* initial buffer size */
    18 };
    1911
    2012typedef struct LINE {
     
    2517} LINE;
    2618
    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
     22enum {
     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
     28struct 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
    3157
    3258static void doCommands(void);
    3359static void subCommand(const char *cmd, int num1, int num2);
    34 static int getNum(const char **retcp, int *retHaveNum, int *retNum);
     60static int getNum(const char **retcp, smallint *retHaveNum, int *retNum);
    3561static int setCurNum(int num);
    36 static int initEdit(void);
    37 static void termEdit(void);
    3862static void addLines(int num);
    3963static int insertLine(int num, const char *data, int len);
    40 static int deleteLines(int num1, int num2);
     64static void deleteLines(int num1, int num2);
    4165static int printLines(int num1, int num2, int expandFlag);
    4266static int writeLines(const char *file, int num1, int num2);
     
    4468static int searchLines(const char *str, int num1, int num2);
    4569static LINE *findLine(int num);
    46 
    4770static int findString(const LINE *lp, const char * str, int len, int offset);
    4871
    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
     73static 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
     83static char *skip_blank(const char *cp)
     84{
     85    while (isblank(*cp))
     86        cp++;
     87    return (char *)cp;
     88}
     89
     90
     91int ed_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     92int 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)) {
    61105            return EXIT_SUCCESS;
    62106        }
    63 
    64         if (!readLines(fileName, 1)) {
    65             termEdit();
    66             return EXIT_SUCCESS;
    67         }
    68 
    69107        if (lastNum)
    70108            setCurNum(1);
    71 
    72109        dirty = FALSE;
    73110    }
    74111
    75112    doCommands();
    76 
    77     termEdit();
    78113    return EXIT_SUCCESS;
    79114}
     
    85120{
    86121    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;
    89125
    90126    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)
    95134            return;
    96 
    97         len = strlen(buf);
    98 
    99         if (len == 0)
    100             return;
    101 
    102135        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 
    114136        while ((endbuf > buf) && isblank(endbuf[-1]))
    115137            endbuf--;
    116 
    117138        *endbuf = '\0';
    118139
    119         cp = buf;
    120 
    121         while (isblank(*cp))
    122             cp++;
    123 
     140        cp = skip_blank(buf);
    124141        have1 = FALSE;
    125142        have2 = FALSE;
     
    133150            continue;
    134151
    135         while (isblank(*cp))
    136             cp++;
     152        cp = skip_blank(cp);
    137153
    138154        if (*cp == ',') {
    139155            cp++;
    140 
    141156            if (!getNum(&cp, &have2, &num2))
    142157                continue;
    143 
    144158            if (!have1)
    145159                num1 = 1;
    146 
    147160            if (!have2)
    148161                num2 = lastNum;
    149 
    150162            have1 = TRUE;
    151163            have2 = TRUE;
    152164        }
    153 
    154165        if (!have1)
    155166            num1 = curNum;
    156 
    157167        if (!have2)
    158168            num2 = num1;
    159169
    160170        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') {
    198191                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;
    323285            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))
    329304                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;
    356322        }
    357323    }
     
    363329 * The current line is set to the last substitution done.
    364330 */
    365 static void subCommand(const char * cmd, int num1, int num2)
     331static void subCommand(const char *cmd, int num1, int num2)
    366332{
    367333    char *cp, *oldStr, *newStr, buf[USERSIZE];
     
    370336    int globalFlag, printFlag, didSub, needPrint;
    371337
    372     if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) {
    373         bb_error_msg("bad line range for substitute");
     338    if (bad_nums(num1, num2, "substitute"))
    374339        return;
    375     }
    376340
    377341    globalFlag = FALSE;
     
    395359
    396360    cp = strchr(cp, delim);
    397 
    398361    if (cp == NULL) {
    399362        bb_error_msg("missing 2nd delimiter for substitute");
     
    415378            globalFlag = TRUE;
    416379            break;
    417 
    418380        case 'p':
    419381            printFlag = TRUE;
    420382            break;
    421 
    422383        default:
    423384            bb_error_msg("unknown option for substitute");
     
    430391            return;
    431392        }
    432 
    433393        oldStr = searchString;
    434394    }
     
    438398
    439399    lp = findLine(num1);
    440 
    441400    if (lp == NULL)
    442401        return;
     
    456415                needPrint = FALSE;
    457416            }
    458 
    459417            offset = 0;
    460418            lp = lp->next;
    461419            num1++;
    462 
    463420            continue;
    464421        }
     
    474431        if (deltaLen <= 0) {
    475432            memcpy(&lp->data[offset], newStr, newLen);
    476 
    477433            if (deltaLen) {
    478434                memcpy(&lp->data[offset + newLen],
     
    482438                lp->len += deltaLen;
    483439            }
    484 
    485440            offset += newLen;
    486 
    487441            if (globalFlag)
    488442                continue;
    489 
    490443            if (needPrint) {
    491444                printLines(num1, num1, FALSE);
    492445                needPrint = FALSE;
    493446            }
    494 
    495447            lp = lp->next;
    496448            num1++;
    497 
    498449            continue;
    499450        }
     
    504455         * the old line structure.
    505456         */
    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);
    512458
    513459        nlp->len = lp->len + deltaLen;
    514460
    515461        memcpy(nlp->data, lp->data, offset);
    516 
    517462        memcpy(&nlp->data[offset], newStr, newLen);
    518 
    519463        memcpy(&nlp->data[offset + newLen],
    520464            &lp->data[offset + oldLen],
     
    555499 * offset in the line.  Returns the offset of the found string, or -1.
    556500 */
    557 static int findString( const LINE * lp, const char * str, int len, int offset)
     501static int findString(const LINE *lp, const char *str, int len, int offset)
    558502{
    559503    int left;
     
    565509    while (left >= len) {
    566510        ncp = memchr(cp, *str, left);
    567 
    568511        if (ncp == NULL)
    569512            return -1;
    570 
    571513        left -= (ncp - cp);
    572 
    573514        if (left < len)
    574515            return -1;
    575 
    576516        cp = ncp;
    577 
    578517        if (memcmp(cp, str, len) == 0)
    579518            return (cp - lp->data);
    580 
    581519        cp++;
    582520        left--;
     
    598536    char buf[USERSIZE + 1];
    599537
    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        }
    601550        if ((buf[0] == '.') && (buf[1] == '\n') && (buf[2] == '\0'))
    602551            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 
    617552        if (!insertLine(num++, buf, len))
    618553            return;
     
    629564 * The character pointer which stopped the scan is also returned.
    630565 */
    631 static int getNum(const char **retcp, int *retHaveNum, int *retNum)
     566static int getNum(const char **retcp, smallint *retHaveNum, int *retNum)
    632567{
    633568    const char *cp;
    634569    char *endStr, str[USERSIZE];
    635     int haveNum, value, num, sign;
     570    int value, num;
     571    smallint haveNum, minus;
    636572
    637573    cp = *retcp;
     574    value = 0;
    638575    haveNum = FALSE;
    639     value = 0;
    640     sign = 1;
     576    minus = 0;
    641577
    642578    while (TRUE) {
    643         while (isblank(*cp))
    644             cp++;
     579        cp = skip_blank(cp);
    645580
    646581        switch (*cp) {
     
    659594            case '\'':
    660595                cp++;
    661 
    662596                if ((*cp < 'a') || (*cp > 'z')) {
    663597                    bb_error_msg("bad mark name");
    664598                    return FALSE;
    665599                }
    666 
    667600                haveNum = TRUE;
    668601                num = marks[*cp++ - 'a'];
     
    672605                strcpy(str, ++cp);
    673606                endStr = strchr(str, '/');
    674 
    675607                if (endStr) {
    676608                    *endStr++ = '\0';
    677609                    cp += (endStr - str);
    678                 }
    679                 else
     610                } else
    680611                    cp = "";
    681 
    682612                num = searchLines(str, curNum, lastNum);
    683 
    684613                if (num == 0)
    685614                    return FALSE;
    686 
    687615                haveNum = TRUE;
    688616                break;
     
    695623                    return TRUE;
    696624                }
    697 
    698625                num = 0;
    699 
    700626                while (isdigit(*cp))
    701627                    num = num * 10 + *cp++ - '0';
    702 
    703628                haveNum = TRUE;
    704629                break;
    705630        }
    706631
    707         value += num * sign;
    708 
    709         while (isblank(*cp))
    710             cp++;
     632        value += (minus ? -num : num);
     633
     634        cp = skip_blank(cp);
    711635
    712636        switch (*cp) {
    713637            case '-':
    714                 sign = -1;
     638                minus = 1;
    715639                cp++;
    716640                break;
    717641
    718642            case '+':
    719                 sign = 1;
     643                minus = 0;
    720644                cp++;
    721645                break;
     
    732656
    733657/*
    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 /*
    798658 * Read lines from a file at the specified line number.
    799659 * Returns TRUE if the file was successfully read.
    800660 */
    801 static int readLines(const char * file, int num)
     661static int readLines(const char *file, int num)
    802662{
    803663    int fd, cc;
     
    811671
    812672    fd = open(file, 0);
    813 
    814673    if (fd < 0) {
    815         perror(file);
     674        bb_simple_perror_msg(file);
    816675        return FALSE;
    817676    }
     
    824683
    825684    printf("\"%s\", ", file);
    826     fflush(stdout);
     685    fflush_all();
    827686
    828687    do {
     
    831690        if (cp) {
    832691            len = (cp - bufPtr) + 1;
    833 
    834692            if (!insertLine(num, bufPtr, len)) {
    835693                close(fd);
    836694                return FALSE;
    837695            }
    838 
    839696            bufPtr += len;
    840697            bufUsed -= len;
     
    842699            lineCount++;
    843700            num++;
    844 
    845701            continue;
    846702        }
     
    853709        if (bufUsed >= bufSize) {
    854710            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);
    863712            bufBase = cp;
    864713            bufPtr = bufBase + bufUsed;
     
    866715        }
    867716
    868         cc = read(fd, bufPtr, bufSize - bufUsed);
     717        cc = safe_read(fd, bufPtr, bufSize - bufUsed);
    869718        bufUsed += cc;
    870719        bufPtr = bufBase;
     
    873722
    874723    if (cc < 0) {
    875         perror(file);
     724        bb_simple_perror_msg(file);
    876725        close(fd);
    877726        return FALSE;
     
    883732            return -1;
    884733        }
    885 
    886734        lineCount++;
    887735        charCount += bufUsed;
     
    901749 * Returns TRUE if successful, or FALSE on an error with a message output.
    902750 */
    903 static int writeLines(const char * file, int num1, int num2)
     751static int writeLines(const char *file, int num1, int num2)
    904752{
    905753    LINE *lp;
    906754    int fd, lineCount, charCount;
    907755
    908     if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) {
    909         bb_error_msg("bad line range for write");
     756    if (bad_nums(num1, num2, "write"))
    910757        return FALSE;
    911     }
    912758
    913759    lineCount = 0;
     
    915761
    916762    fd = creat(file, 0666);
    917 
    918763    if (fd < 0) {
    919         perror(file);
     764        bb_simple_perror_msg(file);
    920765        return FALSE;
    921766    }
    922767
    923768    printf("\"%s\", ", file);
    924     fflush(stdout);
     769    fflush_all();
    925770
    926771    lp = findLine(num1);
    927 
    928772    if (lp == NULL) {
    929773        close(fd);
     
    932776
    933777    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);
    936780            close(fd);
    937781            return FALSE;
    938782        }
    939 
    940783        charCount += lp->len;
    941784        lineCount++;
     
    944787
    945788    if (close(fd) < 0) {
    946         perror(file);
     789        bb_simple_perror_msg(file);
    947790        return FALSE;
    948791    }
     
    965808    int ch, count;
    966809
    967     if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) {
    968         bb_error_msg("bad line range for print");
     810    if (bad_nums(num1, num2, "print"))
    969811        return FALSE;
    970     }
    971812
    972813    lp = findLine(num1);
    973 
    974814    if (lp == NULL)
    975815        return FALSE;
     
    977817    while (num1 <= num2) {
    978818        if (!expandFlag) {
    979             write(1, lp->data, lp->len);
     819            write(STDOUT_FILENO, lp->data, lp->len);
    980820            setCurNum(num1++);
    981821            lp = lp->next;
    982 
    983822            continue;
    984823        }
     
    995834
    996835        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);
    1015838        }
    1016839
     
    1032855 * Returns TRUE if successful.
    1033856 */
    1034 static int insertLine(int num, const char * data, int len)
     857static int insertLine(int num, const char *data, int len)
    1035858{
    1036859    LINE *newLp, *lp;
     
    1041864    }
    1042865
    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);
    1049867
    1050868    memcpy(newLp->data, data, len);
     
    1055873    else {
    1056874        lp = findLine(num);
    1057 
    1058875        if (lp == NULL) {
    1059876            free((char *) newLp);
     
    1076893 * Delete lines from the given range.
    1077894 */
    1078 static int deleteLines(int num1, int num2)
     895static void deleteLines(int num1, int num2)
    1079896{
    1080897    LINE *lp, *nlp, *plp;
    1081898    int count;
    1082899
    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;
    1087902
    1088903    lp = findLine(num1);
    1089 
    1090904    if (lp == NULL)
    1091         return FALSE;
     905        return;
    1092906
    1093907    if ((curNum >= num1) && (curNum <= num2)) {
     
    1101915
    1102916    count = num2 - num1 + 1;
    1103 
    1104917    if (curNum > num2)
    1105918        curNum -= count;
    1106 
    1107919    lastNum -= count;
    1108920
     
    1112924        plp->next = nlp;
    1113925        nlp->prev = plp;
    1114         lp->next = NULL;
    1115         lp->prev = NULL;
    1116         lp->len = 0;
    1117926        free(lp);
    1118927        lp = nlp;
     
    1120929
    1121930    dirty = TRUE;
    1122 
    1123     return TRUE;
    1124931}
    1125932
     
    1127934/*
    1128935 * Search for a line which contains the specified string.
    1129  * If the string is NULL, then the previously searched for string
     936 * If the string is "", then the previously searched for string
    1130937 * is used.  The currently searched for string is saved for future use.
    1131938 * Returns the line number which matches, or 0 if there was no match
    1132939 * with an error printed.
    1133940 */
    1134 static int searchLines(const char *str, int num1, int num2)
     941static NOINLINE int searchLines(const char *str, int num1, int num2)
    1135942{
    1136943    const LINE *lp;
    1137944    int len;
    1138945
    1139     if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) {
    1140         bb_error_msg("bad line numbers for search");
     946    if (bad_nums(num1, num2, "search"))
    1141947        return 0;
    1142     }
    1143948
    1144949    if (*str == '\0') {
     
    1147952            return 0;
    1148953        }
    1149 
    1150954        str = searchString;
    1151955    }
     
    1157961
    1158962    lp = findLine(num1);
    1159 
    1160963    if (lp == NULL)
    1161964        return 0;
     
    1164967        if (findString(lp, str, len, 0) >= 0)
    1165968            return num1;
    1166 
    1167969        num1++;
    1168970        lp = lp->next;
    1169971    }
    1170972
    1171     bb_error_msg("cannot find string \"%s\"", str);
     973    bb_error_msg("can't find string \"%s\"", str);
    1172974    return 0;
    1173975}
     
    1197999    lp = curLine;
    11981000    lnum = curNum;
    1199 
    12001001    if (num < (curNum / 2)) {
    12011002        lp = lines.next;
    12021003        lnum = 1;
    1203     }
    1204     else if (num > ((curNum + lastNum) / 2)) {
     1004    } else if (num > ((curNum + lastNum) / 2)) {
    12051005        lp = lines.prev;
    12061006        lnum = lastNum;
     
    12291029
    12301030    lp = findLine(num);
    1231 
    12321031    if (lp == NULL)
    12331032        return FALSE;
    1234 
    12351033    curNum = num;
    12361034    curLine = lp;
Note: See TracChangeset for help on using the changeset viewer.