Annotation of 43BSDReno/contrib/jove/buf.c, revision 1.1.1.1

1.1       root        1: /***************************************************************************
                      2:  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
                      3:  * is provided to you without charge, and with no warranty.  You may give  *
                      4:  * away copies of JOVE, including sources, provided that this notice is    *
                      5:  * included in all the files.                                              *
                      6:  ***************************************************************************/
                      7: 
                      8: /* Contains commands that deal with creating, selecting, killing and
                      9:    listing buffers, and buffer modes, and find-file, etc. */
                     10: 
                     11: #include "jove.h"
                     12: #include "ctype.h"
                     13: #include "disp.h"
                     14: #if defined(IPROCS)
                     15: # include "fp.h"
                     16: # include "iproc.h"
                     17: #endif
                     18: 
                     19: #ifdef MAC
                     20: # include "mac.h"
                     21: #else
                     22: # include <sys/stat.h>
                     23: #endif
                     24: 
                     25: private Buffer
                     26:        *buf_alloc proto((void)),
                     27:        *mak_buf proto((void));
                     28: 
                     29: private char *line_cnt proto((Buffer *, char *));
                     30: 
                     31: private void
                     32:        defb_wind proto((Buffer *)),
                     33:        kill_buf proto((Buffer *)),
                     34:        mkbuflist proto((char **));
                     35: 
                     36: private char   *Mainbuf = "Main",
                     37:        *NoName = "Sans un nom!";
                     38: 
                     39: Buffer *world = 0,             /* First in the list */
                     40:        *curbuf = 0,    /* pointer into world for current buffer */
                     41:        *lastbuf = 0;   /* Last buffer we were in so we have a default
                     42:                           buffer during a select buffer. */
                     43: 
                     44: /* Toggle BIT in the current buffer's minor mode flags.  If argument is
                     45:    supplied, a positive one always turns on the mode and zero argument
                     46:    always turns it off. */
                     47: 
                     48: void
                     49: TogMinor(bit)
                     50: int    bit;
                     51: {
                     52:        if (is_an_arg()) {
                     53:                if (arg_value() == 0)
                     54:                        curbuf->b_minor &= ~bit;
                     55:                else
                     56:                        curbuf->b_minor |= bit;
                     57:        } else
                     58:                curbuf->b_minor ^= bit;
                     59:        UpdModLine = YES;
                     60: }
                     61: 
                     62: /* Creates a new buffer, links it at the end of the buffer chain, and
                     63:    returns it. */
                     64: 
                     65: private Buffer *
                     66: buf_alloc()
                     67: {
                     68:        register Buffer *b,
                     69:                        *lastbp;
                     70: 
                     71:        lastbp = 0;
                     72:        for (b = world; b != 0; lastbp = b, b = b->b_next)
                     73:                ;
                     74: 
                     75:        b = (Buffer *) emalloc(sizeof (Buffer));
                     76:        if (lastbp)
                     77:                lastbp->b_next = b;
                     78:        else
                     79:                world = b;
                     80:        b->b_first = 0;
                     81:        b->b_next = 0;
                     82: #if defined(MAC)
                     83:        b->Type = BUFFER;       /* kludge, but simplifies menu handlers */
                     84:        b->Name = 0;
                     85: #endif
                     86:        return b;
                     87: }
                     88: 
                     89: /* Makes a buffer and initializes it.  Obsolete.  Used to take two
                     90:    arguments, a buffer name and a file name. */
                     91: 
                     92: private Buffer *
                     93: mak_buf()
                     94: {
                     95:        register Buffer *newb;
                     96:        register int    i;
                     97: 
                     98:        newb = buf_alloc();
                     99:        newb->b_fname = 0;
                    100:        newb->b_name = NoName;
                    101:        set_ino(newb);
                    102:        newb->b_marks = 0;
                    103:        newb->b_themark = 0;            /* Index into markring */
                    104:        /* No marks yet */
                    105:        for (i = 0; i < NMARKS; i++)
                    106:                newb->b_markring[i] = 0;
                    107:        newb->b_modified = 0;
                    108:        newb->b_type = B_FILE;  /* File until proven SCRATCH */
                    109:        newb->b_ntbf = 0;
                    110:        newb->b_minor = 0;
                    111:        newb->b_major = TEXT;
                    112:        newb->b_first = 0;
                    113:        newb->b_map = 0;
                    114: #if defined(IPROCS)
                    115:        newb->b_process = 0;
                    116: #endif
                    117:        initlist(newb);
                    118: #if defined(MAC)
                    119:        Bufchange = 1;
                    120: #endif
                    121:        return newb;
                    122: }
                    123: 
                    124: void
                    125: ReNamBuf()
                    126: {
                    127:        register char   *new = 0,
                    128:                        *prompt = ProcFmt,
                    129:                        *second = "%s already exists; new name? ";
                    130: 
                    131:        for (;;) {
                    132:                new = ask((char *) 0, prompt, new);
                    133:                if (!buf_exists(new))
                    134:                        break;
                    135:                prompt = second;
                    136:        }
                    137:        setbname(curbuf, new);
                    138: }
                    139: 
                    140: void
                    141: FindFile()
                    142: {
                    143:        register char   *name;
                    144:        char    fnamebuf[FILESIZE];
                    145: 
                    146:        name = ask_file((char *) 0, curbuf->b_fname, fnamebuf);
                    147:        SetABuf(curbuf);
                    148:        SetBuf(do_find(curwind, name, 0));
                    149: }
                    150: 
                    151: private void
                    152: mkbuflist(bnamp)
                    153: register char  **bnamp;
                    154: {
                    155:        register Buffer *b;
                    156: 
                    157:        for (b = world; b != 0; b = b->b_next)
                    158:                if (b->b_name != 0)
                    159:                        *bnamp++ = b->b_name;
                    160:        *bnamp = 0;
                    161: }
                    162: 
                    163: char *
                    164: ask_buf(def)
                    165: Buffer *def;
                    166: {
                    167:        char    *bnames[100];
                    168:        register char   *bname;
                    169:        register int    offset;
                    170:        char    prompt[100];
                    171: 
                    172:        if (def != 0 && def->b_name != 0)
                    173:                swritef(prompt, ": %f (default %s) ", def->b_name);
                    174:        else
                    175:                swritef(prompt, ProcFmt);
                    176:        mkbuflist(bnames);
                    177:        offset = complete(bnames, prompt, RET_STATE);
                    178:        if (offset == EOF)
                    179:                complain((char *) 0);
                    180:        if (offset == ORIGINAL || offset == AMBIGUOUS)
                    181:                bname = Minibuf;
                    182:        else if (offset == NULLSTRING) {
                    183:                if (def)
                    184:                        bname = def->b_name;
                    185:                else
                    186:                        complain((char *) 0);
                    187:        } else if (offset < 0)
                    188:                complain((char *) 0);
                    189:        else
                    190:                bname = bnames[offset];
                    191: 
                    192:        return bname;
                    193: }
                    194: 
                    195: void
                    196: BufSelect()
                    197: {
                    198:        register char   *bname;
                    199: 
                    200:        bname = ask_buf(lastbuf);
                    201:        SetABuf(curbuf);
                    202:        SetBuf(do_select(curwind, bname));
                    203: }
                    204: 
                    205: #if defined(MSDOS)
                    206: 
                    207: private void
                    208: BufNSelect(n)
                    209: {
                    210:        char *bnames[100];
                    211:        char *bname;
                    212:        int i;
                    213: 
                    214:        mkbuflist(bnames);
                    215:        for (i=0; i<n; i++)
                    216:            if (bnames[i] == 0)
                    217:               complain("[No such buffer]");
                    218:        bname = bnames[n-1];
                    219:        SetABuf(curbuf);
                    220:        SetBuf(do_select(curwind, bname));
                    221: }
                    222: 
                    223: void Buf1Select() { BufNSelect(1); }
                    224: void Buf2Select() { BufNSelect(2); }
                    225: void Buf3Select() { BufNSelect(3); }
                    226: void Buf4Select() { BufNSelect(4); }
                    227: void Buf5Select() { BufNSelect(5); }
                    228: void Buf6Select() { BufNSelect(6); }
                    229: void Buf7Select() { BufNSelect(7); }
                    230: void Buf8Select() { BufNSelect(8); }
                    231: void Buf9Select() { BufNSelect(9); }
                    232: void Buf10Select() { BufNSelect(10); }
                    233: 
                    234: #endif /* MSDOS */
                    235: 
                    236: private void
                    237: defb_wind(b)
                    238: register Buffer *b;
                    239: {
                    240:        register Window *w = fwind;
                    241:        char    *alt;
                    242: 
                    243:        if (lastbuf == b || lastbuf == 0) {
                    244:                lastbuf = 0;
                    245:                alt = (b->b_next != 0) ? b->b_next->b_name : Mainbuf;
                    246:        } else
                    247:                alt = lastbuf->b_name;
                    248: 
                    249:        do {
                    250:                if (w->w_bufp == b) {
                    251:                        if (one_windp() || alt != Mainbuf)
                    252:                                (void) do_select(w, alt);
                    253:                        else {
                    254:                                Window  *save = w->w_next;
                    255: 
                    256:                                del_wind(w);
                    257:                                w = save->w_prev;
                    258:                        }
                    259:                }
                    260:                w = w->w_next;
                    261:        } while (w != fwind || w->w_bufp == b);
                    262: }
                    263: 
                    264: private Buffer *
                    265: getNMbuf()
                    266: {
                    267:        register Buffer *delbuf;
                    268:        register char   *bname;
                    269: 
                    270:        bname = ask_buf(curbuf);
                    271:        if ((delbuf = buf_exists(bname)) == 0)
                    272:                complain("[No such buffer]");
                    273:        if (delbuf->b_modified)
                    274:                confirm("%s modified, are you sure? ", bname);
                    275:        return delbuf;
                    276: }
                    277: 
                    278: void
                    279: BufErase()
                    280: {
                    281:        register Buffer *delbuf;
                    282: 
                    283:        if ((delbuf = getNMbuf()) != NIL) {
                    284:                initlist(delbuf);
                    285:                delbuf->b_modified = 0;
                    286:        }
                    287: }
                    288: 
                    289: private void
                    290: kill_buf(delbuf)
                    291: register Buffer        *delbuf;
                    292: {
                    293:        register Buffer *b,
                    294:                        *lastb = 0;
                    295: 
                    296: #if defined(IPROCS)
                    297:        pbuftiedp(delbuf);      /* check for lingering processes */
                    298: #endif
                    299:        /* clean up windows associated with this buffer */
                    300:        if (delbuf == curbuf)
                    301:                curbuf = NULL;
                    302:        if (delbuf == lastbuf)
                    303:                lastbuf = curbuf;       /* even if NULL */
                    304:        defb_wind(delbuf);
                    305:        if (curbuf == NULL)
                    306:                SetBuf(curwind->w_bufp);
                    307: 
                    308:        /* unlink the buffer */
                    309:        for (b = world; b != 0; lastb = b, b = b->b_next)
                    310:                if (b == delbuf)
                    311:                        break;
                    312:        if (lastb)
                    313:                lastb->b_next = delbuf->b_next;
                    314:        else
                    315:                world = delbuf->b_next;
                    316: 
                    317: #if !defined(MAC)
                    318:        if (perr_buf == delbuf) {
                    319:                ErrFree();
                    320:                perr_buf = 0;
                    321:        }
                    322: #endif
                    323: 
                    324:        lfreelist(delbuf->b_first);
                    325:        if (delbuf->b_name)
                    326:                free(delbuf->b_name);
                    327:        if (delbuf->b_fname)
                    328:                free(delbuf->b_fname);
                    329:        flush_marks(delbuf);
                    330:        free((char *) delbuf);
                    331: 
                    332: #if defined(MAC)
                    333:        Bufchange = 1;
                    334: #endif
                    335: }
                    336: 
                    337: /* offer to kill some buffers */
                    338: 
                    339: void
                    340: KillSome()
                    341: {
                    342:        register Buffer *b,
                    343:                        *next;
                    344:        Buffer  *oldb;
                    345:        register char   *y_or_n;
                    346: 
                    347:        for (b = world; b != 0; b = next) {
                    348:                next = b->b_next;
                    349:                if (yes_or_no_p("Kill %s? ", b->b_name) == NO)
                    350:                        continue;
                    351:                if (IsModified(b)) {
                    352:                        y_or_n = ask("No", "%s modified; should I save it? ", b->b_name);
                    353:                        if (CharUpcase(*y_or_n) == 'Y') {
                    354:                                oldb = curbuf;
                    355:                                SetBuf(b);
                    356:                                SaveFile();
                    357:                                SetBuf(oldb);
                    358:                        }
                    359:                }
                    360:                kill_buf(b);
                    361:        }
                    362: }
                    363: 
                    364: void
                    365: BufKill()
                    366: {
                    367:        Buffer  *b;
                    368: 
                    369:        if ((b = getNMbuf()) == 0)
                    370:                return;
                    371:        kill_buf(b);
                    372: }
                    373: 
                    374: private char *
                    375: line_cnt(b, buf)
                    376: register Buffer        *b;
                    377: char   *buf;
                    378: {
                    379:        register int    nlines = 0;
                    380:        register Line   *lp;
                    381: 
                    382:        for (lp = b->b_first; lp != 0; lp = lp->l_next, nlines++)
                    383:                ;
                    384:        swritef(buf, "%d", nlines);
                    385:        return buf;
                    386: }
                    387: 
                    388: private const char     *const TypeNames[] = {
                    389:        0,
                    390:        "Scratch",
                    391:        "File",
                    392:        "Process",
                    393: };
                    394: 
                    395: void
                    396: BufList()
                    397: {
                    398:        register char   *fmt = "%-2s %-5s %-11s %-1s %-*s  %-s";
                    399:        register Buffer *b;
                    400:        int     bcount = 1,             /* To give each buffer a number */
                    401:                buf_width = 11;
                    402:        char    nbuf[10];
                    403: 
                    404:        for (b = world; b != 0; b = b->b_next)
                    405:                buf_width = max(buf_width, (int)strlen(b->b_name));
                    406: 
                    407:        TOstart("Buffer list", TRUE);   /* true means auto-newline */
                    408: 
                    409:        Typeout("(* means buffer needs saving)");
                    410:        Typeout("(+ means file hasn't been read yet)");
                    411:        Typeout(NullStr);
                    412:        Typeout(fmt, "NO", "Lines", "Type", NullStr, buf_width, "Name", "File");
                    413:        Typeout(fmt, "--", "-----", "----", NullStr, buf_width, "----", "----");
                    414:        for (b = world; b != 0; b = b->b_next) {
                    415:                Typeout(fmt, itoa(bcount++),
                    416:                                line_cnt(b, nbuf),
                    417:                                TypeNames[b->b_type],
                    418:                                IsModified(b) ? "*" :
                    419:                                         b->b_ntbf ? "+" : NullStr,
                    420:                                buf_width,
                    421:                                /* For the * (variable length field) */
                    422:                                b->b_name,
                    423:                                filename(b));
                    424: 
                    425:                if (TOabort)
                    426:                        break;
                    427:        }
                    428:        TOstop();
                    429: }
                    430: 
                    431: void
                    432: bufname(b)
                    433: register Buffer        *b;
                    434: {
                    435:        char    tmp[100],
                    436:                *cp;
                    437:        int     try = 1;
                    438: 
                    439:        if (b->b_fname == 0)
                    440:                complain("[No file name]");
                    441:        cp = basename(b->b_fname);
                    442:        strcpy(tmp, cp);
                    443:        while (buf_exists(tmp)) {
                    444:                swritef(tmp, "%s.%d", cp, try);
                    445:                try += 1;
                    446:        }
                    447:        setbname(b, tmp);
                    448: }
                    449: 
                    450: void
                    451: initlist(b)
                    452: register Buffer        *b;
                    453: {
                    454:        lfreelist(b->b_first);
                    455:        b->b_first = b->b_dot = b->b_last = 0;
                    456:        (void) listput(b, b->b_first);
                    457: 
                    458:        SavLine(b->b_dot, NullStr);
                    459:        b->b_char = 0;
                    460:        AllMarkSet(b, b->b_dot, 0);
                    461:        if (b == curbuf)
                    462:                getDOT();
                    463: }
                    464: 
                    465: /* Returns pointer to buffer with name NAME, or if NAME is a string of digits
                    466:    returns the buffer whose number equals those digits.  Otherwise, returns
                    467:    0. */
                    468: 
                    469: Buffer *
                    470: buf_exists(name)
                    471: register char  *name;
                    472: {
                    473:        register Buffer *bp;
                    474:        int     n;
                    475: 
                    476:        if (name == 0)
                    477:                return 0;
                    478: 
                    479:        for (bp = world; bp != 0; bp = bp->b_next)
                    480:                if (strcmp(bp->b_name, name) == 0)
                    481:                        return bp;
                    482: 
                    483:        /* Doesn't match any names.  Try for a buffer number... */
                    484: 
                    485:        if (chr_to_int(name, 10, YES, &n) != INT_BAD) {
                    486:                for (bp = world; n > 1; bp = bp->b_next) {
                    487:                        if (bp == 0)
                    488:                                break;
                    489:                        n -= 1;
                    490:                }
                    491:                return bp;
                    492:        }
                    493: 
                    494:        return 0;
                    495: }
                    496: 
                    497: /* Returns buffer pointer with a file name NAME, if one exists.  Stat's the
                    498:    file and compares inodes, in case NAME is a link, as well as the actual
                    499:    characters that make up the file name. */
                    500: 
                    501: Buffer *
                    502: file_exists(name)
                    503: register char  *name;
                    504: {
                    505:        struct stat     stbuf;
                    506:        register struct stat    *s = &stbuf;
                    507:        register Buffer *b = 0;
                    508:        char    fnamebuf[FILESIZE];
                    509: 
                    510: #if defined(MSDOS)
                    511:        strlwr(name);
                    512: #endif /* MSDOS */
                    513:        if (name) {
                    514:                PathParse(name, fnamebuf);
                    515:                if (stat(fnamebuf, s) == -1)
                    516:                        s->st_ino = 0;
                    517:                for (b = world; b != 0; b = b->b_next) {
                    518:                        if (
                    519: #if !defined(MSDOS)
                    520:                            (b->b_ino != 0 && b->b_ino == s->st_ino &&
                    521:                             b->b_dev != 0 && b->b_dev == s->st_dev) ||
                    522: #endif /* MSDOS */
                    523:                            (b->b_fname != 0 &&
                    524:                             strcmp(b->b_fname, fnamebuf) == 0))
                    525:                                break;
                    526:                }
                    527:        }
                    528:        return b;
                    529: }
                    530: 
                    531: void
                    532: setbname(b, name)
                    533: register Buffer        *b;
                    534: register char  *name;
                    535: {
                    536:        UpdModLine = YES;       /* Kludge ... but speeds things up considerably */
                    537:        if (name) {
                    538:                if (b->b_name == NoName)
                    539:                        b->b_name = 0;
                    540:                b->b_name = ralloc(b->b_name, strlen(name) + 1);
                    541:                strcpy(b->b_name, name);
                    542:        } else
                    543:                b->b_name = 0;
                    544: #if defined(MAC)
                    545:        Bufchange = 1;
                    546: #endif
                    547: }
                    548: 
                    549: void
                    550: setfname(b, name)
                    551: register Buffer        *b;
                    552: register char  *name;
                    553: {
                    554:        char    wholename[FILESIZE],
                    555:                oldname[FILESIZE],
                    556:                *oldptr = oldname;
                    557:        Buffer  *save = curbuf;
                    558: 
                    559:        SetBuf(b);
                    560:        UpdModLine = YES;       /* Kludge ... but speeds things up considerably */
                    561:        if (b->b_fname == 0)
                    562:                oldptr = 0;
                    563:        else
                    564:                strcpy(oldname, b->b_fname);
                    565:        if (name) {
                    566: #if defined(MSDOS)
                    567:                strlwr(name);
                    568: #endif /* MSDOS */
                    569:                PathParse(name, wholename);
                    570:                curbuf->b_fname = ralloc(curbuf->b_fname, strlen(wholename) + 1);
                    571:                strcpy(curbuf->b_fname, wholename);
                    572:        } else
                    573:                b->b_fname = 0;
                    574:        DoAutoExec(curbuf->b_fname, oldptr);
                    575:        curbuf->b_mtime = curbuf->b_dev = curbuf->b_ino = 0;    /* until they're known. */
                    576:        SetBuf(save);
                    577: #if defined(MAC)
                    578:        Bufchange = 1;
                    579: #endif
                    580: }
                    581: 
                    582: void
                    583: set_ino(b)
                    584: register Buffer        *b;
                    585: {
                    586:        struct stat     stbuf;
                    587: 
                    588:        if (b->b_fname == 0 || stat(pr_name(b->b_fname, NO), &stbuf) == -1) {
                    589:                b->b_dev = 0;
                    590:                b->b_ino = 0;
                    591:                b->b_mtime = 0;
                    592:        } else {
                    593:                b->b_dev = stbuf.st_dev;
                    594:                b->b_ino = stbuf.st_ino;
                    595:                b->b_mtime = stbuf.st_mtime;
                    596:        }
                    597: }
                    598: 
                    599: /* Find the file `fname' into buf and put in in window `w' */
                    600: 
                    601: Buffer *
                    602: do_find(w, fname, force)
                    603: register Window        *w;
                    604: register char  *fname;
                    605: int    force;
                    606: {
                    607:        register Buffer *b;
                    608: 
                    609:        b = file_exists(fname);
                    610:        if (b == 0) {
                    611:                b = mak_buf();
                    612:                setfname(b, fname);
                    613:                bufname(b);
                    614:                set_ino(b);
                    615:                b->b_ntbf = 1;
                    616:        }
                    617:        if (force) {
                    618:                Buffer  *oldb = curbuf;
                    619: 
                    620:                SetBuf(b);      /* this'll read the file */
                    621:                SetBuf(oldb);
                    622:        }
                    623:        if (w)
                    624:                tiewind(w, b);
                    625:        return b;
                    626: }
                    627: 
                    628: /* set alternate buffer */
                    629: 
                    630: void
                    631: SetABuf(b)
                    632: Buffer *b;
                    633: {
                    634:        if (b != 0)
                    635:                lastbuf = b;
                    636: }
                    637: 
                    638: 
                    639: /* check to see if BP is a valid buffer pointer */
                    640: private int
                    641: valid_bp(bp)
                    642: register Buffer        *bp;
                    643: {
                    644:        register Buffer *b;
                    645: 
                    646:        for (b = world; b != 0; b = b->b_next)
                    647:                if (b == bp)
                    648:                        break;
                    649:        return b != 0;
                    650: }
                    651: 
                    652: void
                    653: SetBuf(newbuf)
                    654: register Buffer        *newbuf;
                    655: {
                    656:        if (newbuf == curbuf || newbuf == 0)
                    657:                return;
                    658: 
                    659:        if (!valid_bp(newbuf))
                    660:                complain("Internal error: (0x%x) is not a valid buffer pointer!", newbuf);
                    661:        lsave();
                    662:        curbuf = newbuf;
                    663:        curline = newbuf->b_dot;
                    664:        curchar = newbuf->b_char;
                    665:        getDOT();
                    666:        /* do the read now ... */
                    667:        if (curbuf->b_ntbf)
                    668:                read_file(curbuf->b_fname, 0);
                    669: #if defined(MAC)
                    670:        Modechange = 1;
                    671: #endif
                    672: }
                    673: 
                    674: Buffer *
                    675: do_select(w, name)
                    676: register Window        *w;
                    677: register char  *name;
                    678: {
                    679:        register Buffer *new;
                    680: 
                    681:        if ((new = buf_exists(name)) == 0) {
                    682:                new = mak_buf();
                    683:                setfname(new, (char *) 0);
                    684:                setbname(new, name);
                    685:        }
                    686:        if (w)
                    687:                tiewind(w, new);
                    688:        return new;
                    689: }
                    690: 
                    691: void
                    692: buf_init()
                    693: {
                    694:        SetBuf(do_select(curwind, Mainbuf));
                    695: }

unix.superglobalmegacorp.com

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