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

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

unix.superglobalmegacorp.com

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