Annotation of 3BSD/cmd/ex/ex_vops2.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1979 Regents of the University of California */
                      2: #include "ex.h"
                      3: #include "ex_tty.h"
                      4: #include "ex_vis.h"
                      5: 
                      6: /*
                      7:  * Low level routines for operations sequences,
                      8:  * and mostly, insert mode (and a subroutine
                      9:  * to read an input line, including in the echo area.)
                     10:  */
                     11: char   *vUA1, *vUA2;
                     12: char   *vUD1, *vUD2;
                     13: 
                     14: /*
                     15:  * Obleeperate characters in hardcopy
                     16:  * open with \'s.
                     17:  */
                     18: bleep(i, cp)
                     19:        register int i;
                     20:        char *cp;
                     21: {
                     22: 
                     23:        i -= column(cp);
                     24:        do
                     25:                putchar('\\' | QUOTE);
                     26:        while (--i >= 0);
                     27:        rubble = 1;
                     28: }
                     29: 
                     30: /*
                     31:  * Common code for middle part of delete
                     32:  * and change operating on parts of lines.
                     33:  */
                     34: vdcMID()
                     35: {
                     36:        register char *cp;
                     37: 
                     38:        squish();
                     39:        setLAST();
                     40:        vundkind = VCHNG, CP(vutmp, linebuf);
                     41:        if (wcursor < cursor)
                     42:                cp = wcursor, wcursor = cursor, cursor = cp;
                     43:        vUD1 = vUA1 = vUA2 = cursor; vUD2 = wcursor;
                     44:        return (column(wcursor - 1));
                     45: }
                     46: 
                     47: /*
                     48:  * Take text from linebuf and stick it
                     49:  * in the VBSIZE buffer BUF.  Used to save
                     50:  * deleted text of part of line.
                     51:  */
                     52: takeout(BUF)
                     53:        char *BUF;
                     54: {
                     55:        register char *cp;
                     56: 
                     57:        if (wcursor < linebuf)
                     58:                wcursor = linebuf;
                     59:        if (cursor == wcursor) {
                     60:                beep();
                     61:                return;
                     62:        }
                     63:        if (wcursor < cursor) {
                     64:                cp = wcursor;
                     65:                wcursor = cursor;
                     66:                cursor = cp;
                     67:        }
                     68:        setBUF(BUF);
                     69:        if ((BUF[0] & (QUOTE|TRIM)) == OVERBUF)
                     70:                beep();
                     71: }
                     72: 
                     73: /*
                     74:  * Are we at the end of the printed representation of the
                     75:  * line?  Used internally in hardcopy open.
                     76:  */
                     77: ateopr()
                     78: {
                     79:        register int i, c;
                     80:        register char *cp = vtube[destline] + destcol;
                     81: 
                     82:        for (i = WCOLS - destcol; i > 0; i--) {
                     83:                c = *cp++;
                     84:                if (c == 0)
                     85:                        return (1);
                     86:                if (c != ' ' && (c & QUOTE) == 0)
                     87:                        return (0);
                     88:        }
                     89:        return (1);
                     90: }
                     91: 
                     92: /*
                     93:  * Append.
                     94:  *
                     95:  * This routine handles the top level append, doing work
                     96:  * as each new line comes in, and arranging repeatability.
                     97:  * It also handles append with repeat counts, and calculation
                     98:  * of autoindents for new lines.
                     99:  */
                    100: bool   vaifirst;
                    101: bool   gobbled;
                    102: char   *ogcursor;
                    103: 
                    104: vappend(ch, cnt, indent)
                    105:        char ch;
                    106:        int cnt, indent;
                    107: {
                    108:        register int i;
                    109:        register char *gcursor;
                    110:        bool escape;
                    111:        int repcnt;
                    112:        short oldhold = hold;
                    113: 
                    114:        /*
                    115:         * Before a move in hardopen when the line is dirty
                    116:         * or we are in the middle of the printed representation,
                    117:         * we retype the line to the left of the cursor so the
                    118:         * insert looks clean.
                    119:         */
                    120:        if (ch != 'o' && state == HARDOPEN && (rubble || !ateopr())) {
                    121:                rubble = 1;
                    122:                gcursor = cursor;
                    123:                i = *gcursor;
                    124:                *gcursor = ' ';
                    125:                wcursor = gcursor;
                    126:                vmove();
                    127:                *gcursor = i;
                    128:        }
                    129:        vaifirst = indent == 0;
                    130: 
                    131:        /*
                    132:         * Handle replace character by (eventually)
                    133:         * limiting the number of input characters allowed
                    134:         * in the vgetline routine.
                    135:         */
                    136:        if (ch == 'r')
                    137:                repcnt = 2;
                    138:        else
                    139:                repcnt = 0;
                    140: 
                    141:        /*
                    142:         * If an autoindent is specified, then
                    143:         * generate a mixture of blanks to tabs to implement
                    144:         * it and place the cursor after the indent.
                    145:         * Text read by the vgetline routine will be placed in genbuf,
                    146:         * so the indent is generated there.
                    147:         */
                    148:        if (value(AUTOINDENT) && indent != 0) {
                    149:                gcursor = genindent(indent);
                    150:                *gcursor = 0;
                    151:                vgotoCL(qcolumn(cursor - 1, genbuf));
                    152:        } else {
                    153:                gcursor = genbuf;
                    154:                *gcursor = 0;
                    155:                if (ch == 'o')
                    156:                        vfixcurs();
                    157:        }
                    158: 
                    159:        /*
                    160:         * Prepare for undo.  Pointers delimit inserted portion of line.
                    161:         */
                    162:        vUA1 = vUA2 = cursor;
                    163: 
                    164:        /*
                    165:         * If we are not in a repeated command and a ^@ comes in
                    166:         * then this means the previous inserted text.
                    167:         * If there is none or it was too long to be saved,
                    168:         * then beep() and also arrange to undo any damage done
                    169:         * so far (e.g. if we are a change.)
                    170:         */
                    171:        if ((vglobp && *vglobp == 0) || peekbr()) {
                    172:                if ((INS[0] & (QUOTE|TRIM)) == OVERBUF) {
                    173:                        beep();
                    174:                        if (!splitw)
                    175:                                ungetkey('u');
                    176:                        doomed = 0;
                    177:                        hold = oldhold;
                    178:                        return;
                    179:                }
                    180:                /*
                    181:                 * Unread input from INS.
                    182:                 * An escape will be generated at end of string.
                    183:                 * Hold off n^^2 type update on dumb terminals.
                    184:                 */
                    185:                vglobp = INS;
                    186:                hold |= HOLDQIK;
                    187:        } else if (vglobp == 0)
                    188:                /*
                    189:                 * Not a repeated command, get
                    190:                 * a new inserted text for repeat.
                    191:                 */
                    192:                INS[0] = 0;
                    193: 
                    194:        /*
                    195:         * For wrapmargin to hack away second space after a '.'
                    196:         * when the first space caused a line break we keep
                    197:         * track that this happened in gobblebl, which says
                    198:         * to gobble up a blank silently.
                    199:         */
                    200:        gobblebl = 0;
                    201: 
                    202:        /*
                    203:         * Text gathering loop.
                    204:         * New text goes into genbuf starting at gcursor.
                    205:         * cursor preserves place in linebuf where text will eventually go.
                    206:         */
                    207:        if (*cursor == 0 || state == CRTOPEN)
                    208:                hold |= HOLDROL;
                    209:        for (;;) {
                    210:                if (ch == 'r' && repcnt == 0)
                    211:                        escape = 0;
                    212:                else {
                    213:                        gcursor = vgetline(repcnt, gcursor, &escape);
                    214: 
                    215:                        /*
                    216:                         * After an append, stick information
                    217:                         * about the ^D's and ^^D's and 0^D's in
                    218:                         * the repeated text buffer so repeated
                    219:                         * inserts of stuff indented with ^D as backtab's
                    220:                         * can work.
                    221:                         */
                    222:                        if (HADUP)
                    223:                                addtext("^");
                    224:                        else if (HADZERO)
                    225:                                addtext("0");
                    226:                        while (CDCNT > 0)
                    227:                                addtext("\204"), CDCNT--;
                    228:                        if (gobbled)
                    229:                                addtext(" ");
                    230:                        addtext(ogcursor);
                    231:                }
                    232:                repcnt = 0;
                    233: 
                    234:                /*
                    235:                 * Smash the generated and preexisting indents together
                    236:                 * and generate one cleanly made out of tabs and spaces
                    237:                 * if we are using autoindent.
                    238:                 */
                    239:                if (!vaifirst && value(AUTOINDENT)) {
                    240:                        i = fixindent(indent);
                    241:                        if (!HADUP)
                    242:                                indent = i;
                    243:                        gcursor = strend(genbuf);
                    244:                }
                    245: 
                    246:                /*
                    247:                 * Limit the repetition count based on maximum
                    248:                 * possible line length; do output implied
                    249:                 * by further count (> 1) and cons up the new line
                    250:                 * in linebuf.
                    251:                 */
                    252:                cnt = vmaxrep(ch, cnt);
                    253:                CP(gcursor + 1, cursor);
                    254:                do {
                    255:                        CP(cursor, genbuf);
                    256:                        if (cnt > 1) {
                    257:                                int oldhold = hold;
                    258: 
                    259:                                Outchar = vinschar;
                    260:                                hold |= HOLDQIK;
                    261:                                printf("%s", genbuf);
                    262:                                hold = oldhold;
                    263:                                Outchar = vputchar;
                    264:                        }
                    265:                        cursor += gcursor - genbuf;
                    266:                } while (--cnt > 0);
                    267:                endim();
                    268:                vUA2 = cursor;
                    269:                if (escape != '\n')
                    270:                        CP(cursor, gcursor + 1);
                    271: 
                    272:                /*
                    273:                 * If doomed characters remain, clobber them,
                    274:                 * and reopen the line to get the display exact.
                    275:                 */
                    276:                if (state != HARDOPEN) {
                    277:                        DEPTH(vcline) = 0;
                    278:                        if (doomed > 0) {
                    279:                                register int cind = cindent();
                    280: 
                    281:                                physdc(cind, cind + doomed);
                    282:                                doomed = 0;
                    283:                        }
                    284:                        i = vreopen(LINE(vcline), lineDOT(), vcline);
                    285:                }
                    286: 
                    287:                /*
                    288:                 * All done unless we are continuing on to another line.
                    289:                 */
                    290:                if (escape != '\n')
                    291:                        break;
                    292: 
                    293:                /*
                    294:                 * Set up for the new line.
                    295:                 * First save the current line, then construct a new
                    296:                 * first image for the continuation line consisting
                    297:                 * of any new autoindent plus the pushed ahead text.
                    298:                 */
                    299:                killU();
                    300:                addtext(gobblebl ? " " : "\n");
                    301:                vsave();
                    302:                cnt = 1;
                    303:                if (value(AUTOINDENT)) {
                    304: #ifdef LISPCODE
                    305:                        if (value(LISP))
                    306:                                indent = lindent(dot + 1);
                    307:                        else
                    308: #endif
                    309:                             if (!HADUP && vaifirst)
                    310:                                indent = whitecnt(linebuf);
                    311:                        vaifirst = 0;
                    312:                        strcLIN(vpastwh(gcursor + 1));
                    313:                        gcursor = genindent(indent);
                    314:                        *gcursor = 0;
                    315:                        if (gcursor + strlen(linebuf) > &genbuf[LBSIZE - 2])
                    316:                                gcursor = genbuf;
                    317:                        CP(gcursor, linebuf);
                    318:                } else {
                    319:                        CP(genbuf, gcursor + 1);
                    320:                        gcursor = genbuf;
                    321:                }
                    322: 
                    323:                /*
                    324:                 * If we started out as a single line operation and are now
                    325:                 * turning into a multi-line change, then we had better yank
                    326:                 * out dot before it changes so that undo will work
                    327:                 * correctly later.
                    328:                 */
                    329:                if (vundkind == VCHNG) {
                    330:                        vremote(1, yank, 0);
                    331:                        undap1--;
                    332:                }
                    333: 
                    334:                /*
                    335:                 * Now do the append of the new line in the buffer,
                    336:                 * and update the display.  If slowopen
                    337:                 * we don't do very much.
                    338:                 */
                    339:                vdoappend(genbuf);
                    340:                vundkind = VMANYINS;
                    341:                vcline++;
                    342:                if (state != VISUAL)
                    343:                        vshow(dot, NOLINE);
                    344:                else {
                    345:                        i += LINE(vcline - 1);
                    346:                        vopen(dot, i);
                    347:                        if (value(SLOWOPEN))
                    348:                                vscrap();
                    349:                        else
                    350:                                vsync1(LINE(vcline));
                    351:                }
                    352:                strcLIN(gcursor);
                    353:                *gcursor = 0;
                    354:                cursor = linebuf;
                    355:                vgotoCL(qcolumn(cursor - 1, genbuf));
                    356:        }
                    357: 
                    358:        /*
                    359:         * All done with insertion, position the cursor
                    360:         * and sync the screen.
                    361:         */
                    362:        hold = oldhold;
                    363:        if (cursor > linebuf)
                    364:                cursor--;
                    365:        if (state != HARDOPEN)
                    366:                vsyncCL();
                    367:        else if (cursor > linebuf)
                    368:                back1();
                    369:        doomed = 0;
                    370:        wcursor = cursor;
                    371:        vmove();
                    372: }
                    373: 
                    374: /*
                    375:  * Subroutine for vgetline to back up a single character position,
                    376:  * backwards around end of lines (vgoto can't hack columns which are
                    377:  * less than 0 in general).
                    378:  */
                    379: back1()
                    380: {
                    381: 
                    382:        vgoto(destline - 1, WCOLS + destcol - 1);
                    383: }
                    384: 
                    385: /*
                    386:  * Get a line into genbuf after gcursor.
                    387:  * Cnt limits the number of input characters
                    388:  * accepted and is used for handling the replace
                    389:  * single character command.  Aescaped is the location
                    390:  * where we stick a termination indicator (whether we
                    391:  * ended with an ESCAPE or a newline/return.
                    392:  *
                    393:  * We do erase-kill type processing here and also
                    394:  * are careful about the way we do this so that it is
                    395:  * repeatable.  (I.e. so that your kill doesn't happen,
                    396:  * when you repeat an insert if it was escaped with \ the
                    397:  * first time you did it.
                    398:  */
                    399: char *
                    400: vgetline(cnt, gcursor, aescaped)
                    401:        int cnt;
                    402:        register char *gcursor;
                    403:        bool *aescaped;
                    404: {
                    405:        register int c, ch;
                    406:        register char *cp;
                    407:        int x, y, iwhite;
                    408:        char *iglobp;
                    409:        int (*OO)() = Outchar;
                    410: 
                    411:        /*
                    412:         * Clear the output state and counters
                    413:         * for autoindent backwards motion (counts of ^D, etc.)
                    414:         * Remember how much white space at beginning of line so
                    415:         * as not to allow backspace over autoindent.
                    416:         */
                    417:        *aescaped = 0;
                    418:        ogcursor = gcursor;
                    419:        flusho();
                    420:        CDCNT = 0;
                    421:        HADUP = 0;
                    422:        HADZERO = 0;
                    423:        gobbled = 0;
                    424:        iwhite = whitecnt(genbuf);
                    425:        iglobp = vglobp;
                    426: 
                    427:        /*
                    428:         * Carefully avoid using vinschar in the echo area.
                    429:         */
                    430:        if (splitw)
                    431:                Outchar = vputchar;
                    432:        else {
                    433:                Outchar = vinschar;
                    434:                vprepins();
                    435:        }
                    436:        for (;;) {
                    437:                if (gobblebl)
                    438:                        gobblebl--;
                    439:                if (cnt != 0) {
                    440:                        cnt--;
                    441:                        if (cnt == 0)
                    442:                                goto vadone;
                    443:                }
                    444:                ch = c = getkey() & (QUOTE|TRIM);
                    445:                if (value(MAPINPUT))
                    446:                        while ((ch = map(c, arrows)) != c)
                    447:                                c = ch;
                    448:                if (!iglobp) {
                    449: 
                    450:                        /*
                    451:                         * Erase-kill type processing.
                    452:                         * Only happens if we were not reading
                    453:                         * from untyped input when we started.
                    454:                         * Map users erase to ^H, kill to -1 for switch.
                    455:                         */
                    456:                        if (c == tty.sg_erase)
                    457:                                c = CTRL(h);
                    458:                        else if (c == tty.sg_kill)
                    459:                                c = -1;
                    460:                        switch (c) {
                    461: 
                    462:                        /*
                    463:                         * ^?           Interrupt drops you back to visual
                    464:                         *              command mode with an unread interrupt
                    465:                         *              still in the input buffer.
                    466:                         *
                    467:                         * ^\           Quit does the same as interrupt.
                    468:                         *              If you are a ex command rather than
                    469:                         *              a vi command this will drop you
                    470:                         *              back to command mode for sure.
                    471:                         */
                    472:                        case ATTN:
                    473:                        case QUIT:
                    474:                                ungetkey(c);
                    475:                                goto vadone;
                    476: 
                    477:                        /*
                    478:                         * ^H           Backs up a character in the input.
                    479:                         *
                    480:                         * BUG:         Can't back around line boundaries.
                    481:                         *              This is hard because stuff has
                    482:                         *              already been saved for repeat.
                    483:                         */
                    484:                        case CTRL(h):
                    485: bakchar:
                    486:                                cp = gcursor - 1;
                    487:                                if (cp < ogcursor) {
                    488:                                        if (splitw) {
                    489:                                                /*
                    490:                                                 * Backspacing over readecho
                    491:                                                 * prompt. Pretend delete but
                    492:                                                 * don't beep.
                    493:                                                 */
                    494:                                                ungetkey(c);
                    495:                                                goto vadone;
                    496:                                        }
                    497:                                        beep();
                    498:                                        continue;
                    499:                                }
                    500:                                goto vbackup;
                    501: 
                    502:                        /*
                    503:                         * ^W           Back up a white/non-white word.
                    504:                         */
                    505:                        case CTRL(w):
                    506:                                wdkind = 1;
                    507:                                for (cp = gcursor; cp > ogcursor && isspace(cp[-1]); cp--)
                    508:                                        continue;
                    509:                                for (c = wordch(cp - 1);
                    510:                                    cp > ogcursor && wordof(c, cp - 1); cp--)
                    511:                                        continue;
                    512:                                goto vbackup;
                    513: 
                    514:                        /*
                    515:                         * users kill   Kill input on this line, back to
                    516:                         *              the autoindent.
                    517:                         */
                    518:                        case -1:
                    519:                                cp = ogcursor;
                    520: vbackup:
                    521:                                if (cp == gcursor) {
                    522:                                        beep();
                    523:                                        continue;
                    524:                                }
                    525:                                endim();
                    526:                                *cp = 0;
                    527:                                c = cindent();
                    528:                                vgotoCL(qcolumn(cursor - 1, genbuf));
                    529:                                if (doomed >= 0)
                    530:                                        doomed += c - cindent();
                    531:                                gcursor = cp;
                    532:                                continue;
                    533: 
                    534:                        /*
                    535:                         * \            Followed by erase or kill
                    536:                         *              maps to just the erase or kill.
                    537:                         */
                    538:                        case '\\':
                    539:                                x = destcol, y = destline;
                    540:                                putchar('\\');
                    541:                                vcsync();
                    542:                                c = getkey();
                    543:                                if (c == tty.sg_erase || c == tty.sg_kill) {
                    544:                                        vgoto(y, x);
                    545:                                        if (doomed >= 0)
                    546:                                                doomed++;
                    547:                                        goto def;
                    548:                                }
                    549:                                ungetkey(c), c = '\\';
                    550:                                goto noput;
                    551: 
                    552:                        /*
                    553:                         * ^Q           Super quote following character
                    554:                         *              Only ^@ is verboten (trapped at
                    555:                         *              a lower level) and \n forces a line
                    556:                         *              split so doesn't really go in.
                    557:                         *
                    558:                         * ^V           Synonym for ^Q
                    559:                         */
                    560:                        case CTRL(q):
                    561:                        case CTRL(v):
                    562:                                x = destcol, y = destline;
                    563:                                putchar('^');
                    564:                                vgoto(y, x);
                    565:                                c = getkey();
                    566: #ifdef TIOCSETC
                    567:                                if (c == ATTN)
                    568:                                        c = nttyc.t_intrc;
                    569: #endif
                    570:                                if (c != NL) {
                    571:                                        if (doomed >= 0)
                    572:                                                doomed++;
                    573:                                        goto def;
                    574:                                }
                    575:                                break;
                    576:                        }
                    577:                }
                    578: 
                    579:                /*
                    580:                 * If we get a blank not in the echo area
                    581:                 * consider splitting the window in the wrapmargin.
                    582:                 */
                    583:                if (c == ' ' && !splitw) {
                    584:                        if (gobblebl) {
                    585:                                gobbled = 1;
                    586:                                continue;
                    587:                        }
                    588:                        if (value(WRAPMARGIN) && outcol >= OCOLUMNS - value(WRAPMARGIN)) {
                    589:                                c = NL;
                    590:                                gobblebl = 2;
                    591:                        }
                    592:                }
                    593:                switch (c) {
                    594: 
                    595:                /*
                    596:                 * ^M           Except in repeat maps to \n.
                    597:                 */
                    598:                case CR:
                    599:                        if (vglobp)
                    600:                                goto def;
                    601:                        c = '\n';
                    602:                        /* presto chango ... */
                    603: 
                    604:                /*
                    605:                 * \n           Start new line.
                    606:                 */
                    607:                case NL:
                    608:                        *aescaped = c;
                    609:                        goto vadone;
                    610: 
                    611:                /*
                    612:                 * escape       End insert unless repeat and more to repeat.
                    613:                 */
                    614:                case ESCAPE:
                    615:                        if (lastvgk)
                    616:                                goto def;
                    617:                        goto vadone;
                    618: 
                    619:                /*
                    620:                 * ^D           Backtab.
                    621:                 * ^T           Software forward tab.
                    622:                 *
                    623:                 *              Unless in repeat where this means these
                    624:                 *              were superquoted in.
                    625:                 */
                    626:                case CTRL(d):
                    627:                case CTRL(t):
                    628:                        if (vglobp)
                    629:                                goto def;
                    630:                        /* fall into ... */
                    631: 
                    632:                /*
                    633:                 * ^D|QUOTE     Is a backtab (in a repeated command).
                    634:                 */
                    635:                case CTRL(d) | QUOTE:
                    636:                        *gcursor = 0;
                    637:                        cp = vpastwh(genbuf);
                    638:                        c = whitecnt(genbuf);
                    639:                        if (ch == CTRL(t)) {
                    640:                                /*
                    641:                                 * ^t just generates new indent replacing
                    642:                                 * current white space rounded up to soft
                    643:                                 * tab stop increment.
                    644:                                 */
                    645:                                if (cp != gcursor)
                    646:                                        /*
                    647:                                         * BUG:         Don't hack ^T except
                    648:                                         *              right after initial
                    649:                                         *              white space.
                    650:                                         */
                    651:                                        continue;
                    652:                                cp = genindent(iwhite = backtab(c + value(SHIFTWIDTH) + 1));
                    653:                                ogcursor = cp;
                    654:                                goto vbackup;
                    655:                        }
                    656:                        /*
                    657:                         * ^D works only if we are at the (end of) the
                    658:                         * generated autoindent.  We count the ^D for repeat
                    659:                         * purposes.
                    660:                         */
                    661:                        if (c == iwhite && c != 0)
                    662:                                if (cp == gcursor) {
                    663:                                        iwhite = backtab(c);
                    664:                                        CDCNT++;
                    665:                                        ogcursor = cp = genindent(iwhite);
                    666:                                        goto vbackup;
                    667:                                } else if (&cp[1] == gcursor &&
                    668:                                    (*cp == '^' || *cp == '0')) {
                    669:                                        /*
                    670:                                         * ^^D moves to margin, then back
                    671:                                         * to current indent on next line.
                    672:                                         *
                    673:                                         * 0^D moves to margin and then
                    674:                                         * stays there.
                    675:                                         */
                    676:                                        HADZERO = *cp == '0';
                    677:                                        ogcursor = cp = genbuf;
                    678:                                        HADUP = 1 - HADZERO;
                    679:                                        CDCNT = 1;
                    680:                                        endim();
                    681:                                        back1();
                    682:                                        vputc(' ');
                    683:                                        goto vbackup;
                    684:                                }
                    685:                        if (vglobp && vglobp - iglobp >= 2 &&
                    686:                            (vglobp[-2] == '^' || vglobp[-2] == '0')
                    687:                            && gcursor == ogcursor + 1)
                    688:                                goto bakchar;
                    689:                        continue;
                    690: 
                    691:                default:
                    692:                        /*
                    693:                         * Possibly discard control inputs.
                    694:                         */
                    695:                        if (!vglobp && junk(c)) {
                    696:                                beep();
                    697:                                continue;
                    698:                        }
                    699: def:
                    700:                        putchar(c);
                    701: noput:
                    702:                        if (gcursor > &genbuf[LBSIZE - 2])
                    703:                                error("Line too long");
                    704:                        *gcursor++ = c & TRIM;
                    705:                        vcsync();
                    706: #ifdef LISPCODE
                    707:                        if (value(SHOWMATCH) && !iglobp)
                    708:                                if (c == ')' || c == '}')
                    709:                                        lsmatch(gcursor);
                    710: #endif
                    711:                        continue;
                    712:                }
                    713:        }
                    714: vadone:
                    715:        *gcursor = 0;
                    716:        Outchar = OO;
                    717:        endim();
                    718:        return (gcursor);
                    719: }
                    720: 
                    721: int    vgetsplit();
                    722: char   *vsplitpt;
                    723: 
                    724: /*
                    725:  * Append the line in buffer at lp
                    726:  * to the buffer after dot.
                    727:  */
                    728: vdoappend(lp)
                    729:        char *lp;
                    730: {
                    731:        register int oing = inglobal;
                    732: 
                    733:        vsplitpt = lp;
                    734:        inglobal = 1;
                    735:        ignore(append(vgetsplit, dot));
                    736:        inglobal = oing;
                    737: }
                    738: 
                    739: /*
                    740:  * Subroutine for vdoappend to pass to append.
                    741:  */
                    742: vgetsplit()
                    743: {
                    744: 
                    745:        if (vsplitpt == 0)
                    746:                return (EOF);
                    747:        strcLIN(vsplitpt);
                    748:        vsplitpt = 0;
                    749:        return (0);
                    750: }
                    751: 
                    752: /*
                    753:  * Vmaxrep determines the maximum repetitition factor
                    754:  * allowed that will yield total line length less than
                    755:  * LBSIZE characters and also does hacks for the R command.
                    756:  */
                    757: vmaxrep(ch, cnt)
                    758:        char ch;
                    759:        register int cnt;
                    760: {
                    761:        register int len, replen;
                    762: 
                    763:        if (cnt > LBSIZE - 2)
                    764:                cnt = LBSIZE - 2;
                    765:        replen = strlen(genbuf);
                    766:        if (ch == 'R') {
                    767:                len = strlen(cursor);
                    768:                if (replen < len)
                    769:                        len = replen;
                    770:                CP(cursor, cursor + len);
                    771:                vUD2 += len;
                    772:        }
                    773:        len = strlen(linebuf);
                    774:        if (len + cnt * replen <= LBSIZE - 2)
                    775:                return (cnt);
                    776:        cnt = (LBSIZE - 2 - len) / replen;
                    777:        if (cnt == 0) {
                    778:                vsave();
                    779:                error("Line too long");
                    780:        }
                    781:        return (cnt);
                    782: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.