Annotation of 43BSD/contrib/jove/buf.c, revision 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.