Annotation of researchv9/cmd/emacs/emacs_buf.c, revision 1.1

1.1     ! root        1: /* EMACS_MODES: c !fill */
        !             2: #include <signal.h>
        !             3: #include <sys/types.h>
        !             4: #ifndef PC
        !             5: #include <sys/stat.h>
        !             6: #endif PC
        !             7: #include "emacs_io.h"
        !             8: #include "emacs_gb.h"
        !             9: #include "emacs_buf.h"
        !            10: 
        !            11: 
        !            12: 
        !            13: /* leng * length of a line in the buffer */
        !            14: 
        !            15: leng(line)
        !            16: 
        !            17: register int line;
        !            18: 
        !            19: {
        !            20: /* Keywords: line-representation:10 length */
        !            21:        
        !            22:        register char *lp;
        !            23:        register char *olp;
        !            24: 
        !            25:        olp = lp = mkline(line);
        !            26:        while (*lp++ != EOL);
        !            27:        return(lp-olp-1);
        !            28: }
        !            29: 
        !            30: allout ()                              /* break all links */
        !            31: 
        !            32: {
        !            33:        register unsigned *outp;
        !            34:        register int xptr;
        !            35:        register int q;
        !            36: /* Keywords: buffer-representation:50 line-representation:5 paging buffer-changing:10 */
        !            37:        
        !            38:        for (outp = ptrs+nlines; outp > ptrs; outp--) {
        !            39:                xptr = *outp;
        !            40:                if (xptr&01) {
        !            41:                        q = xptr-1;
        !            42:                        *outp = ((bblock[q>>BSHIFT]<<BRSHIFT) + ((q&BMASK)>>LSSHIFT))<<1;
        !            43:                }
        !            44:        }
        !            45: }
        !            46:        
        !            47: 
        !            48: /* mkline -- make a pointer to the current line */
        !            49: 
        !            50: /* pages in the line if out of core, makes a null string for an empty
        !            51: line */
        !            52: 
        !            53: char *
        !            54: 
        !            55: ckline(line,len)
        !            56: int line;
        !            57: int len;
        !            58: /* Keywords: buffer-representation:50 line-representation:50 paging:20 buffer-allocation */
        !            59: 
        !            60: {
        !            61:        register char *lp;
        !            62:        char *lp1;
        !            63:        register char *q;
        !            64:        register int fileadd;
        !            65:        int x;
        !            66:        int s;
        !            67:        
        !            68:        lp = mkline(line);
        !            69:        if (len <= (LSMALL*(*(lp-1))-2)) return(lp);
        !            70:        
        !            71:                                        /* current line is too small */
        !            72:        
        !            73: 
        !            74:        if ((len+2) >= MAXEL) {
        !            75:                error(WARN,33,line,MAXEL-1); /* report problems */
        !            76:                return(NULL);           /* line too long, let caller handle */
        !            77:        }
        !            78:        s = (len+1+LSMALL)>>LSSHIFT;
        !            79:        x = ptrs[line]-1;
        !            80:        
        !            81:        fileadd = (bblock[x>>BSHIFT]<<BRSHIFT) + ((x&BMASK)>>LSSHIFT);
        !            82:        
        !            83:        if ((fileadd + bbuf[0][x]) == BUFEND) {
        !            84:                if ((fileadd & BRMASK) == ((fileadd+s-1)&BRMASK)) {
        !            85:                        
        !            86:                                        /* current line extends in place */
        !            87:                        BUFEND = fileadd + s;
        !            88:                        bbuf [0] [x] = s;
        !            89:                        TRACE(TRCKEX);
        !            90:                        TRACE(line);
        !            91:                        TRACE(s);
        !            92: 
        !            93:                        return (&bbuf[0][x+1]);
        !            94:                }
        !            95:        }
        !            96:        
        !            97:                                        /* must copy to new buffer */
        !            98:        
        !            99:        if ((BUFEND&BRMASK) != ((BUFEND-1+s)&BRMASK)) {
        !           100:                BUFEND = (BUFEND&BRMASK)+BFACT;
        !           101:        }
        !           102:        ptrs[0] = BUFEND<<1;
        !           103:        BUFEND += s;
        !           104:        TRACE(TRCKCP);
        !           105:        TRACE(line);
        !           106:        TRACE(s);
        !           107:        xline = line;                   /* Mark the real line in ptrs[0] */
        !           108:        holdin(0,line);                 /* get both lines in memory */
        !           109:        q = &(bbuf[0][ptrs[line]]);     /* old line buffer */
        !           110:        lp = lp1 = &(bbuf[0][ptrs[0]]);         /* new buffer */
        !           111:        *(lp-1) = s;
        !           112:        s = (*(q-1)*LSMALL);            /* old length */
        !           113:        while (s--) if ((*lp++ = *q++) == EOL) break;
        !           114:        ptrs[line] = ptrs[0];
        !           115:        ptrs[0] = 0;
        !           116:        modify(line);
        !           117:        return(lp1);
        !           118: }
        !           119: 
        !           120: char *
        !           121: 
        !           122: mkl(line)
        !           123: register int line;
        !           124: 
        !           125: {
        !           126:        register char *p;
        !           127:        register int i;
        !           128:        int block;
        !           129:        int newf;
        !           130: /* Keywords: buffer-representation paging line-representation buffer-allocation */
        !           131:        
        !           132:        while (line>nlines) {
        !           133:                sputl(nlines+1,0,line);
        !           134:                if (line >= NPTRS) {
        !           135:                        if (!growbuf(line)) return(NULL);
        !           136:                }
        !           137:                nlines++;
        !           138:                ptrs[nlines] = 0;
        !           139:        }
        !           140: 
        !           141:        if (INMEM(line)) return (&bbuf[0][ptrs[line]]);
        !           142: 
        !           143:        /* no current line */
        !           144: 
        !           145:        nmkline++;                      /* count for stats */
        !           146: 
        !           147:        TRACE(TRMAKE);
        !           148:        TRACE(line);
        !           149: 
        !           150:        if (BUFILE == NULL) {
        !           151:                BUFILE = gtemp(curbf); /* get a temp file */
        !           152:                BUFEND = BFACT;         /* remember 0 == NULL */
        !           153:        }
        !           154:        if (ptrs[line] == 0) {
        !           155:                ptrs[line] = (BUFEND++)<<1; /* assign new buffer */
        !           156:                newf = 1;
        !           157:                TRACE(TRMKEM);
        !           158:        } else newf = 0;
        !           159:        block = ((ptrs[line]))>>(BRSHIFT+1);
        !           160: 
        !           161: /* first see if desired block is in memory already */
        !           162: 
        !           163:        for (i = fbkno; i < NBLOCK; i++) if (block == bblock[i]) {
        !           164:                goto bfill;
        !           165:        }
        !           166: 
        !           167:                                        /* now try to swap in */
        !           168:        
        !           169:        for (i = fbkno; i <= NBLOCK+1; i++) {
        !           170:                if (++nxtflsh >= NBLOCK) nxtflsh = fbkno;
        !           171:                if (bstat[nxtflsh] == 0) {
        !           172:                        bgrab(nxtflsh,block); /* get block in (won't fail)*/
        !           173:                        i = nxtflsh;
        !           174:                        if (line)lowpt[i]=hipt[i]=line;
        !           175:                        else lowpt[i]=hipt[i]=xline;
        !           176:                        goto bfill;
        !           177:                } else bflush(nxtflsh); /* try to force out block */
        !           178:        }
        !           179:        
        !           180: /* can't find a buffer to flush */
        !           181: 
        !           182:        error(FATAL,34);                /* File buffers broken */
        !           183: 
        !           184:        
        !           185: bfill:
        !           186:        p= &bbuf[i][LSMALL*((ptrs[line]>>1)&BRESID)+1];
        !           187:        ptrs[line] = p-bbuf[0];
        !           188:        if (newf) {
        !           189:                *(p-1) = 1;             /* line size */
        !           190:                *(p) = EOL;
        !           191:                modify(line);           /* make sure line is flushed */
        !           192:        }
        !           193:        if (line==0) line = xline;
        !           194:        if (line<lowpt[i])lowpt[i]=line;
        !           195:        if (line > hipt[i])hipt[i] = line;
        !           196:        return(p);
        !           197: }
        !           198: 
        !           199: 
        !           200: /* gtemp -- get a temp file, and unlink it */
        !           201: 
        !           202: gtemp(fn)
        !           203: int fn;
        !           204: {
        !           205: /* Keywords: temporary-files filenames:50 */
        !           206:        
        !           207:        char tfile [64];
        !           208:        register int tf;
        !           209: #ifdef PC
        !           210: retry: seprintf(tfile,"%s:emt.%d",BTEMPATH,fn);
        !           211:        tf = creat(tfile,6);
        !           212:        if (tf < 0) {
        !           213:                ctfile();
        !           214:                goto retry;
        !           215:        }
        !           216: #else
        !           217:        seprintf(tfile,"%s/em.%o.%o",BTEMPATH,fn,getpid());
        !           218:        while ((tf = creat(tfile,0600)) < 0) {
        !           219:                if ((errno != 4) && (errno != 23)) break;
        !           220:        }
        !           221:        close(tf);
        !           222:        while ((tf = open(tfile,2)) < 0) {
        !           223:                if ((errno != 4) && (errno != 23)) break;
        !           224:        }
        !           225:        if (tf < 0) {
        !           226:                error(FATAL,errno,"temp file");
        !           227:        }
        !           228: #ifdef MINFILES
        !           229:        if (fn == NBUF) unlink(tfile);  /* lose the file */
        !           230: #else
        !           231:        unlink(tfile);  /* lose the file */
        !           232: #endif
        !           233: #endif
        !           234:        return(tf);
        !           235: }
        !           236: 
        !           237: #ifdef PC
        !           238: rmtemp()
        !           239: {
        !           240: /* Keywords: temporary-files filenames:20 */
        !           241:        
        !           242:        char tfile[64];
        !           243:        int i;
        !           244:        btmpfile[curbf] = BUFILE;               /* set up for current buffer */
        !           245:        for (i = 0; i < NBUF; i++) if (btmpfile[i]) close(btmpfile[i]);
        !           246:        if (kfile) close(kfile);
        !           247:        for (i = 0; i <= NBUF; i++) {
        !           248:                seprintf(tfile,"%s:emt.%d",BTEMPATH,i);
        !           249:                unlink(tfile);
        !           250:        }
        !           251: }
        !           252: 
        !           253: /* Called on out of space errors, asks for file to delete and continues */
        !           254: 
        !           255: mkspace()
        !           256: {
        !           257:        char *cp;
        !           258:        char filebuf[64];
        !           259:        char tmp[128];
        !           260: /* Keywords: PC-only temporary-files deletion:10 user-interface:50 */
        !           261:        
        !           262:        if (error(WARN,76,BTEMPATH) == 0)  {
        !           263:                cp = getname("File to delete on temp file disk?");
        !           264:                if (cp) {
        !           265:                        mstrcpy(tmp,fnbuf); /* Preserve fnbuf */
        !           266:                        seprintf(filebuf,"%s:%s",BTEMPATH,cp);
        !           267:                        if (unlink(filebuf) == 0) {
        !           268:                                mstrcpy(fnbuf,tmp);
        !           269:                                return(1);
        !           270:                        }
        !           271:                        mstrcpy(fnbuf,tmp);
        !           272:                }
        !           273:        }
        !           274:        return(0);
        !           275: }
        !           276: #endif PC
        !           277: 
        !           278: #ifdef MINFILES
        !           279: rmtemp()
        !           280: {
        !           281: /* Keywords: temporary-files filenames:20 */
        !           282:        char tfile [64];
        !           283:        register int fn;
        !           284:        btmpfile[curbf] = BUFILE;               /* set up for current buffer */
        !           285:        for (fn = 0; fn < NBUF; fn++) {
        !           286:                if (btmpfile[fn]) {
        !           287:                        rftmp(fn);
        !           288:                }
        !           289:        }
        !           290:        rftmp(NBUF);
        !           291: }
        !           292: rftmp(fn)
        !           293: register int fn;
        !           294: {
        !           295: /* Keywords: temporary-files filenames:20 MINFILES-version */
        !           296:        char tfile[64];
        !           297:        seprintf(tfile,"%s/em.%o.%o",BTEMPATH,fn,getpid());
        !           298:        unlink(tfile);
        !           299: }
        !           300: 
        !           301: otemp(fn)
        !           302: int fn;
        !           303: {
        !           304: /* Keywords: temporary-files filenames:20 MINFILES-version */
        !           305:        char tfile [64];
        !           306:        register int tf;
        !           307:        seprintf(tfile,"%s/em.%o.%o",BTEMPATH,fn,getpid());
        !           308:        while ((tf = open(tfile,2)) < 0) {
        !           309:                if ((errno != 4) && (errno != 23)) break;
        !           310:        }
        !           311:        if (tf < 0) {
        !           312:                error(FATAL,errno,"temp file");
        !           313:        }
        !           314:        return(tf);
        !           315: }
        !           316: #endif 
        !           317: 
        !           318: /* utility program to insure that both lines are in memory before proceeding */
        !           319: 
        !           320: holdin(line1,line2)
        !           321: 
        !           322: register int line1,line2;
        !           323: /* Keywords: paging line-representation:10 */
        !           324: 
        !           325: {
        !           326: 
        !           327:        while (OUTMEM(line1) || OUTMEM(line2)) {
        !           328:                 mkline(line1);
        !           329:                 mkline(line2);
        !           330:        }
        !           331: }
        !           332: 
        !           333: /* growbuf -- grow the amount of buffer storage */
        !           334: growbuf(iline)
        !           335: 
        !           336: int iline;
        !           337: /* Keywords: buffer-representation memory-allocation */
        !           338: 
        !           339: {
        !           340:        register unsigned *ndadd;
        !           341:        register int line;
        !           342: 
        !           343:        
        !           344:        line = (iline&BRKMSK)+01000;            /* round up to next multiple
        !           345:                                         * of 512 */
        !           346:        
        !           347:        ndadd = &ptrs[line];            /* new need address */
        !           348: #ifdef PC
        !           349:        if (line >= MPTRS) {
        !           350: #else
        !           351:        if (brk(ndadd) != 0) {
        !           352: #endif PC
        !           353:                line = iline+4;         /* try for less */
        !           354:                ndadd = &ptrs[line];
        !           355: #ifdef PC
        !           356:                if (line >= MPTRS) {
        !           357: #else
        !           358:                if (brk(ndadd) != 0) {
        !           359: #endif PC
        !           360:                        error(NORM,35); /* Too Many lines */
        !           361:                        return(0);
        !           362:                }
        !           363:        }
        !           364:        NPTRS = line;
        !           365:        return(1);
        !           366: 
        !           367: }
        !           368: 
        !           369: 
        !           370: 
        !           371:                
        !           372: /* bgrab -- fill a specific buffer with a specific block */
        !           373: 
        !           374: bgrab(x,blkno)
        !           375: /* Keywords: buffer-representation paging paging-I/O encryption:10 */
        !           376: 
        !           377: register int x;
        !           378: int blkno;
        !           379: {
        !           380:        register int base;
        !           381:        register unsigned *p;
        !           382:        register unsigned *endp;
        !           383: #ifndef pdp11
        !           384:        unsigned bsblock;
        !           385: #else
        !           386:        unsigned short bsblock;
        !           387: #endif
        !           388:        int rstat;
        !           389:        long seekpos;
        !           390:        
        !           391:        TRACE(TRBGRAB);
        !           392:        TRACE(x);
        !           393:        TRACE(blkno);
        !           394:        if (bblock[x]) {                /* if block is occupied */
        !           395:                if (bstat[x]) {
        !           396:                        if (bflush(x)== 0) return(0);
        !           397:                }
        !           398:                base = x*BLEN+1;
        !           399:                bsblock = bblock[x]<<(1+BRSHIFT);
        !           400:                if (hipt[x] > nlines) hipt[x]=nlines; /* Make sure it's in bounds! */
        !           401:                if (lowpt[x] < 0) lowpt[x] = 0; /* likewise */
        !           402:                endp = &ptrs[lowpt[x]];         
        !           403:                for (p= &ptrs[hipt[x]]; p>=endp; p--) {
        !           404:                        if((*p &01) && (((*p - base)&(~BMASK)) == NULL)) {
        !           405:                                *p = bsblock + ((*p - base)>>(LSSHIFT-1));
        !           406:                        }
        !           407:                }
        !           408:                        /* break all links to block */
        !           409: 
        !           410:        }
        !           411:        bblock[x] = blkno;
        !           412:        if (blkno&& (blkno<=mostwrit)) {
        !           413:                if (blkno != sblk) { /* if we must seek */
        !           414:                        TRACE(TRSEEK);
        !           415:                        TRACE(sblk);
        !           416:                        TRACE(blkno);
        !           417:                        seekpos = (long) BLEN * (long) blkno;
        !           418:                        nbseek++;
        !           419:                        lseek(BUFILE,seekpos,0);
        !           420:                }
        !           421:                nbread++;
        !           422:                TRACE(TRREAD);
        !           423:                TRACE(x);
        !           424:                TRACE(blkno);
        !           425:                while ((rstat =read(BUFILE,bbuf[x],BLEN)) != BLEN) {
        !           426:                        if (errno != 4) break;
        !           427:                }
        !           428:                if (rstat != BLEN) error(FATAL,errno,"reading buffer");
        !           429: #ifdef CRYPTO
        !           430:                if (bbuf[x][0]&0200) {
        !           431: 
        !           432: /* First byte of buffer is always a count, and thus shouldn't have the */
        !           433: /* 0200 bit on.  This insures that enciphered bufferes are deciphered */
        !           434: 
        !           435:                        cryptic(&bbuf[x][0]);
        !           436:                        bbuf[x][0] &= 0177; /* Make sure high order bit is off */
        !           437:                }
        !           438: #endif
        !           439:                sblk = blkno+1;
        !           440:        }
        !           441:        return(1);
        !           442: }
        !           443: #ifdef CRYPTO
        !           444: cryptic(cp)
        !           445: register long *cp;                     /* Types deliberately mismatched */
        !           446: {
        !           447: /* Keywords: buffer-representation encryption paging:10 */
        !           448:        
        !           449:        long x;
        !           450:        register long *endp;
        !           451:        
        !           452:        endp = cp + BLEN/sizeof(x);
        !           453:        while (cp < endp) *cp++ ^= bufkey;
        !           454: }
        !           455: #endif
        !           456: /* bflush -- flush contents of a buffer */ 
        !           457: 
        !           458: bflush(x)
        !           459: /* Keywords: buffer-representation paging paging-I/O encryption:10 */
        !           460: 
        !           461: register int x;
        !           462: {
        !           463:        
        !           464:        long seekpos;
        !           465:        if (bstat[x]) {
        !           466: retry:
        !           467:                if (sblk != bblock[x]) {
        !           468:                        seekpos = (long) bblock[x] * (long) BLEN;
        !           469:                        TRACE(TRSEEK);
        !           470:                        TRACE(sblk);
        !           471:                        TRACE(bblock[x]);
        !           472:                        nbseek++;
        !           473:                        lseek(BUFILE,seekpos,0);
        !           474:                }
        !           475: #ifdef CRYPTO
        !           476:                if (crypt) {
        !           477:                        cryptic(&bbuf[x][0]);
        !           478:                        bbuf[x][0] |= 0200;
        !           479:                }
        !           480: #endif CRYPTO
        !           481:                while(write(BUFILE,bbuf[x],BLEN) != BLEN) {
        !           482: #ifdef PC
        !           483:                        if (mkspace()) {
        !           484:                                bblock[x] = -1; /* Don't know where we are */
        !           485:                                goto retry;
        !           486:                        }
        !           487:                        return(0);
        !           488: #else
        !           489:                        if (errno != 4) error(FATAL,errno,"buffer file");
        !           490: #endif                 
        !           491:                }
        !           492: #ifdef CRYPTO
        !           493:                if (bbuf[x][0]&0200) {
        !           494:                        cryptic(&bbuf[x][0]);
        !           495:                        bbuf[x][0] &= 0177; /* Make sure high order bit is off */
        !           496:                }
        !           497: #endif CRYPTO
        !           498:                nbwrite++;
        !           499:                TRACE(TRWRIT);
        !           500:                TRACE(x);
        !           501:                TRACE(bblock[x]);
        !           502:                sblk = bblock[x]+1;
        !           503:                if (bblock[x] > mostwrit) mostwrit = bblock[x];
        !           504:                bstat[x] = 0;
        !           505:        }
        !           506:        return(1);
        !           507: }
        !           508: 
        !           509: /* initializes line buffer free list, ptrs array to empty */
        !           510: 
        !           511: 
        !           512: 
        !           513: bufinit()
        !           514: /* Keywords: buffer-changing:10 buffer-representation buffer-allocation:50 */
        !           515: 
        !           516: {
        !           517:        register int i;
        !           518:        register unsigned *p;
        !           519: 
        !           520: /* now set up buffer stuff */
        !           521: 
        !           522: 
        !           523:        for (p = &ptrs[NPTRS-1]; p >= ptrs; p--) { /* clear ptrs */
        !           524:                *p = 0;
        !           525:        }
        !           526: 
        !           527:        /* set up free buffer line list */
        !           528: 
        !           529:        for (i = fbkno; i < NBLOCK; i++) bstat[i] = bblock[i] = 0;
        !           530:        nxtflsh= NBLOCK;                        /* initial buffer to use */
        !           531:        nlines = 1;
        !           532:        mostwrit = 0;
        !           533:        sblk = 0;
        !           534:        curln = 1;
        !           535:        column = 0;
        !           536:        curblk = 0;
        !           537:        if (BUFILE) BUFEND = BFACT;     /* re-use buffer */
        !           538: }
        !           539: #ifdef PC
        !           540: 
        !           541: /*     change temp file -- change place where temp files are put. */
        !           542: 
        !           543: 
        !           544: ctfile()
        !           545: {
        !           546: /* Keywords: PC-only buffer-representation temporary-files filenames:10 */
        !           547: 
        !           548:        char *cp;
        !           549:        cp = getname("Tempfile Directory? ");
        !           550:        if (cp) {
        !           551:                *BTEMPATH = *cp;
        !           552:        }
        !           553:        if (mostwrit == 0) {
        !           554:                                        /* Re-allocate current buffer */
        !           555:                close(BUFILE);
        !           556:                BUFILE = gtemp(curbf);
        !           557:        }
        !           558: }
        !           559: 
        !           560: #endif PC
        !           561: /* wout -- write out file */
        !           562: 
        !           563: wout(name,aflag)
        !           564: /* Keywords: writing buffer-representation:50 commands:10 PC-only:10 macro-hooks:10 */
        !           565: /* Keywords: encryption:20 unix-interface:10 dired:20 user-interface:10 */
        !           566: 
        !           567: char *name;
        !           568: int aflag;
        !           569: {
        !           570:        FILE outbuf[1];
        !           571:        register FILE *outfile;
        !           572:        register int i;
        !           573:        int nosave;                     /* return value from backup link */
        !           574:        char backb[128];                /* buffer for name of backup file */
        !           575:        char *backp;
        !           576:        char *bp;
        !           577:        register char *cp;
        !           578: #ifndef PC
        !           579:        struct stat inode;              /* status buffer */
        !           580: #endif
        !           581:        int status;
        !           582:        int xstat;      
        !           583:        
        !           584:        if (hooks[Pre_Write_Hook]) {
        !           585:                stkstr(name);
        !           586:                if (hook(Pre_Write_Hook)==0) {
        !           587:                        unprompt();
        !           588:                        return(0);
        !           589:                }
        !           590:                retrvs(fnbuf,FNLEN);
        !           591:                name=fnbuf;
        !           592:        }
        !           593: 
        !           594: #ifdef DIRED
        !           595:        if (diron) return(dclean());
        !           596: #endif
        !           597:        if (*name == NULL) return(0);
        !           598:        bp = name;
        !           599:        cp = backp = backb;
        !           600:        while (*cp = *bp++) {
        !           601:                if (*cp++ == '/') backp = cp;
        !           602:        }
        !           603:        strcpy(backp,"EMACS_save");
        !           604:        nosave = 1;
        !           605:        prompt1("Wait");
        !           606: #ifndef PC
        !           607:        mflush(stdout);
        !           608:        status = stat(name,&inode);             /* get old file modes */
        !           609:                                        /* don't care if file not there */
        !           610: /*     if ((status==0) && (((inode.st_mode &0200) == 0) || (inode.st_uid != myuid))) {*/
        !           611:        if (status == 0) {
        !           612:                if (inode.st_mode & S_IFDIR)  {/* Writing a directory, yuck */
        !           613:                        error(WARN,81,name,name,filename);
        !           614:                        return(0);
        !           615:                }
        !           616:                if (access(name,02) != 0) {
        !           617:                        if (gyn("File not explicitly writeable, write anyway?")<=0) return(0);
        !           618:                }
        !           619:        }
        !           620: #endif PC
        !           621:        if ((aflag>1)||(aflag<-1)) {
        !           622:                outfile = xopen (outbuf,name,"ba");
        !           623:                if (status == 0) goto wfile1; /* if file was there */
        !           624:        }
        !           625: #ifndef PC
        !           626:        if ((status == 0) && streq(filename,name) && 
        !           627:        (mtime[bfnumb()]) && (mtime[bfnumb()] != inode.st_mtime)) {
        !           628:                        
        !           629:                error(WARN,78,name);
        !           630:                return(0);
        !           631:        } 
        !           632:        /* don't prompt if user wants file links saved */
        !           633:        if (savelink) goto wfile;
        !           634:        if ((status== 0) && (inode.st_nlink != 1)) {
        !           635: 
        !           636:                i = gyn("File %s is linked to another, write to both (y) or only to %s ?",name,name);
        !           637:                if (i < 0) return(0);
        !           638:                if (i > 0) goto wfile;
        !           639:        }
        !           640:        
        !           641:        nosave = streq(name,backb);     /* see if we are trying to link backup */
        !           642:        if (nosave==0) {
        !           643:                nosave = link (name,backb);
        !           644: 
        !           645:                /* make backup link to file in case */
        !           646:                /* we crash.  Old copy will be in  
        !           647:                 * EMACS_save if crash occurs during write */
        !           648:                if (nosave == 0) unlink(name);  /* remove old file */
        !           649:        }
        !           650: #endif PC
        !           651: wfile: outfile = xopen (outbuf,name,"bw");
        !           652: wfile1:        if (outfile == NULL) {
        !           653:                error(WARN,errno,name);
        !           654:                return(0);
        !           655:        }
        !           656:        prompt1("Writing");
        !           657:        mflush(stdout);
        !           658: 
        !           659: #ifdef CRYPTO
        !           660:        if (crypt) {
        !           661:                char crbuf[32];
        !           662:                seprintf(crbuf,"crypt %s",cryptkey);
        !           663:                splfile = outfile ->_frn;
        !           664:                if (unx(crbuf,6)<0) return(0);
        !           665:                outfile->_frn = splfile;
        !           666:        }
        !           667: #endif 
        !           668: 
        !           669:        for (i = 1; i <= nlines; i++) {
        !           670:                if (i != 1) {
        !           671: #ifdef PC
        !           672:                        if (BINMODE == 0) putc(CTRLM,outfile);
        !           673: #endif PC
        !           674:                        putc('\n',outfile);
        !           675:                }
        !           676:                cp = mkline(i);
        !           677:                while (*cp != EOL) {
        !           678:                        if (PICMODE && (*cp == ' ')) {
        !           679:                                register int x;
        !           680:                                for (x = 1; cp[x]==' '; x++);
        !           681:                                if (cp[x] == EOL) break;
        !           682:                                while (x--) {
        !           683:                                        putc(*cp,outfile);
        !           684:                                        cp++;
        !           685:                                }
        !           686:                        } else {
        !           687:                                putc(*cp,outfile);
        !           688:                                cp++;
        !           689:                        }
        !           690:                }
        !           691:        }
        !           692:        if (EOFNL) {
        !           693:                cp = mkline(nlines);
        !           694:                if (*cp!=EOL) {
        !           695:                        putc('\n', outfile);
        !           696: #ifdef PC
        !           697:                        if (BINMODE == 0) putc(CTRLM,outfile);
        !           698: #endif PC
        !           699:                }
        !           700:        }
        !           701: #ifdef PC
        !           702:        if (BINMODE == 0) putc('\032',outfile);
        !           703:        mclose(outfile);
        !           704: #else
        !           705:        if (mclose(outfile)) {          /* Error occurred during write */
        !           706:                                        /* Try to put back old file */
        !           707:                if (nosave==0) { /* error writing saved file */
        !           708:                        unlink(name);
        !           709:                        link(backb,name); /* Put everything back */
        !           710:                        unlink(backb);
        !           711:                        prompt1("No write: %s", name);
        !           712:                        return(0);
        !           713:                }
        !           714:                prompt1("File errors: %s", name);
        !           715:                mtime[bfnumb()] = 0; 
        !           716:                return(0);
        !           717:        }
        !           718: 
        !           719: #ifdef CRYPTO
        !           720:        if (crypt) wait(&xstat);        /* Eliminate zombies */
        !           721: #endif
        !           722:        if (nosave == 0) unlink(backb);  /* remove backup link */
        !           723: 
        !           724:        if (status == 0) {
        !           725:                chmod(name,inode.st_mode);/* set modes right */
        !           726:                chown(name,inode.st_uid,inode.st_gid); /* set owner and group */
        !           727:        } else {
        !           728:                chmod(name,0666 & ~mymask);/* Modes by umask */
        !           729:        }
        !           730: #endif PC
        !           731:        if ((aflag<2)&&(aflag>-2)) {
        !           732:                prompt1("Written: %s", name);
        !           733:        }
        !           734:        else prompt1("Appended: %s", name);
        !           735:        NSCHAR=0;
        !           736:        if (aflag>0) {
        !           737:                strcpy(filename,name);
        !           738:                bufmod = 0;
        !           739:        }
        !           740: #ifndef PC
        !           741:        if (streq(filename,name)) {
        !           742:                
        !           743:                if (stat(name,&inode) != 0) {
        !           744:                        error(WARN,errno,name);
        !           745:                } else {
        !           746:                        mtime[bfnumb()] = inode.st_mtime;
        !           747:                }
        !           748:        }
        !           749: #endif
        !           750:        dispmod();
        !           751:        move(curln,column);             /* Restore state information */
        !           752:        return(1);
        !           753: }
        !           754: 
        !           755: /* read in a file into the buffer */
        !           756: /* re-initializes buffer first */
        !           757: 
        !           758: 
        !           759: readin(fn,reinit)
        !           760: 
        !           761: char *fn;
        !           762: int reinit;
        !           763: {
        !           764: 
        !           765: /* Keywords: reading encryption:20 PC-only:10 dired:10 unix-interface:10 commands:10 macro-hooks:10 */
        !           766: 
        !           767:        FILE *filein;
        !           768:        FILE finbuf[1];
        !           769: #ifndef PC
        !           770:        struct stat inode;
        !           771:        int xstat;
        !           772: #endif
        !           773: #ifdef DIRED
        !           774:        extern char dired_args[];
        !           775: #endif
        !           776: 
        !           777:        if (fn[0] == 0) fn =  filename;                 /* default to previous file */
        !           778:        if (fn[0] == 0) return(0);              /* no default */
        !           779: 
        !           780:        if (VERBOSE) {
        !           781:                prompt1 ("Wait");
        !           782:                mflush(stdout);
        !           783:        }
        !           784:        if (hooks[Pre_Read_Hook]) {
        !           785:                stkstr(fn);
        !           786:                if (hook(Pre_Read_Hook) == 0) {
        !           787:                        unprompt();
        !           788:                        return(0);
        !           789:                }
        !           790:                retrvs(fnbuf,FNLEN);
        !           791:                fn = fnbuf;
        !           792:        }
        !           793:        filein = xopen( finbuf,fn,"br");
        !           794:        if (filein == NULL) {
        !           795:                unprompt();
        !           796:                if (reinit>0) error(WARN,errno,fn);
        !           797:                if (filename[0] == 0) {
        !           798:                        strcpy(filename,fn); /* copy name */
        !           799:                        dispmod();
        !           800:                }
        !           801:                return(0);
        !           802:        }
        !           803: #ifndef PC
        !           804:        if (fstat(filein->_frn,&inode) != 0) {
        !           805:                error(WARN,errno,fn);
        !           806:                return(0);
        !           807:        }
        !           808:        if (inode.st_size >= MAXFS) { /* Check for grossly huge file */
        !           809:                error(WARN,77,fn);
        !           810:                return(0);
        !           811:        }
        !           812: #ifndef DIRED
        !           813:        if (inode.st_mode & S_IFDIR) {
        !           814:                                        /* Reading a directory, check to be sure */
        !           815:                if (error(WARN,82,fn)) return(0);
        !           816:                                        /* go ahead and read it if the user wants to */
        !           817:        }
        !           818: #endif
        !           819: #endif
        !           820: #ifdef DIRED
        !           821:        if (inode.st_mode & S_IFDIR) {
        !           822:                char dircom[128];
        !           823:                diron = 1;
        !           824:                splfile = filein ->_frn;
        !           825:                seprintf(dircom,"ls %s %s", dired_args,fn);
        !           826:                if (unx(dircom,7) < 0) return(0);
        !           827:                filein->_frn = splfile;
        !           828:        } else diron = 0;
        !           829: #endif
        !           830:        if (VERBOSE) {
        !           831:                prompt1("Reading");
        !           832:                mflush(stdout);
        !           833:        }
        !           834:        if (reinit == -1) reinit = 1;
        !           835:        if (reinit == 1) bufinit();
        !           836: #ifdef CRYPTO
        !           837:        if (crypt) {
        !           838:                char crbuf[32];
        !           839:                seprintf(crbuf,"crypt %s",cryptkey);
        !           840:                splfile = filein->_frn;
        !           841:                if (unx(crbuf ,7)<0) return(0);
        !           842:                filein->_frn = splfile;
        !           843:        }
        !           844: #endif 
        !           845:        readsub(filein,reinit,fn,0);            /* do the reading */
        !           846: #ifdef CRYPTO
        !           847:        if (crypt) wait(&xstat);                        /* Eliminate zombies */
        !           848: #endif 
        !           849: #ifdef DIRED
        !           850:        if (diron) wait(&xstat);        /* Eliminate zombies */
        !           851: #endif 
        !           852: #ifndef PC
        !           853:        if (streq(filename,fn)) {
        !           854:                struct stat ninode;
        !           855:                mtime[bfnumb()] = inode.st_mtime;
        !           856:                if (stat(fn,&ninode) != 0) {
        !           857:                        error(WARN,errno,fn);
        !           858:                } else {
        !           859:                        if ((ninode.st_mtime != inode.st_mtime)||
        !           860:                            (ninode.st_ino   != inode.st_ino))  {
        !           861:                                error(WARN,79,fn);
        !           862:                        }
        !           863:                }
        !           864:        }
        !           865: #endif
        !           866:        unprompt();
        !           867:        ttfill();                       /* try to read ahead*/
        !           868:        if (hooks[Post_Read_Hook]) hook (Post_Read_Hook);
        !           869:        return(1);
        !           870: }
        !           871: 
        !           872: 
        !           873: readsub(filein,reinit,fn,cpyflag)
        !           874: /* Keywords: reading buffer-representation:5 unix-interface:20 dired:30 file-modes:10 */
        !           875: 
        !           876: int reinit;
        !           877: #ifndef pdp11
        !           878: register
        !           879: #endif
        !           880: int cpyflag;
        !           881: register FILE *filein;
        !           882: char *fn;
        !           883: {
        !           884:        register int c;
        !           885:        int i;
        !           886:        char fbuf[MAXEL];
        !           887:        register char *fp;
        !           888:        register char *endbuf;
        !           889:        int warnl;
        !           890:        
        !           891:        i = curln;
        !           892:        if (reinit != 1) {
        !           893:                RARE = 1;                       /* turn off trouble */
        !           894:                while ((c = getc(filein)) != EOF) {
        !           895: #ifdef PC
        !           896:                        if (BINMODE == 0){
        !           897:                                if (c == '\032') break;
        !           898:                                if (c == '\n') bdel(1); /* Wipe out spurious cr */
        !           899:                                
        !           900:                        }
        !           901: #endif PC
        !           902:                        if (cpyflag) putchar(c); /* output character */
        !           903:                        put(c);
        !           904:                        if (c == EOL) clptr = mkline(curln);
        !           905:                }
        !           906:        } else {
        !           907:                if (BUFILE == NULL) {
        !           908:                        BUFILE = gtemp(curbf); /* get a temp file */
        !           909:                }
        !           910:                BUFEND = BFACT;         /* remember 0 == NULL */
        !           911:                fp = &fbuf[0];  
        !           912:                endbuf = fbuf+MAXEL-2;
        !           913:                warnl = -1;                     /* last "line too long" */
        !           914:                while ((c = getc(filein)) != EOF) {
        !           915: #ifdef PC
        !           916:                        if (BINMODE == 0){
        !           917:                                if (c == '\032') break;
        !           918:                                if (c == '\n') fp--; /* Wipe out trailing CR */
        !           919:                        }
        !           920: #endif PC
        !           921:                        if (cpyflag) putchar(c); /* echo to terminal */
        !           922: 
        !           923:                        if (c == '\n') {
        !           924:                                *fp = EOL;
        !           925:                                if (addline(fbuf,fp-fbuf,i++)==0) goto eof;
        !           926:                                fp = &fbuf[0];
        !           927:                        } else {
        !           928: #ifdef DIRED
        !           929:                                if (diron) while (fp-fbuf < 4) *fp++ = ' '; /* make room for markings */
        !           930: 
        !           931: #endif
        !           932:                                *fp++ = c;
        !           933:                                if (fp >= endbuf) {
        !           934:                                        fp--;
        !           935:                                        if (i == warnl) continue;
        !           936:                                        warnl = i;
        !           937:                                        if(error(NORM,33,i,MAXEL-1)) goto eof;
        !           938:                                        continue;
        !           939:                                }
        !           940:                        }
        !           941:                }
        !           942: eof:           *fp = EOL;
        !           943:                addline(fbuf,fp-fbuf,i);
        !           944:                move(1,0);
        !           945:                strncpy(filename,fn,FNLEN); /* Copy name written */
        !           946:                bufmod = 0;             /* buffer up to date */
        !           947:        }
        !           948:        mclose(filein);
        !           949:        if (cpyflag) mflush(stdout);    /* Force output to come out */
        !           950:        NSCHAR = 0;
        !           951:        bfmodes();      /* set buffer modes */
        !           952:        fclear();       /* file is now bad */
        !           953:        RARE = 0;       /* normal modes back on */
        !           954: }
        !           955: 
        !           956: /* Express access to the buffer.  This code plunks in one line at
        !           957:  * the end of the buffer, manipulating all appropriate data, much
        !           958:  * swifter than the usual ckline-bgrab sequence.  What is assumed by
        !           959:  * this function is that it is called after bufinit and no other
        !           960:  * intervening buffer manipulations.  It leaves the ptrs array set
        !           961:  * up with no lines in memory, but with the last n blocks of the
        !           962:  * file in bbuf and properly initialized.   */
        !           963: 
        !           964: 
        !           965: 
        !           966: 
        !           967: addline(cp,len,line)
        !           968: register char *cp;
        !           969: int len;
        !           970: int line;
        !           971: {
        !           972: /* Keywords: buffer-representation:50 line-representation:20 reading:10 buffer-allocation:20 */
        !           973: 
        !           974:        register char *lp;
        !           975:        register int x;
        !           976:        register int s;
        !           977: 
        !           978:        if (line >= NPTRS) {
        !           979:                if (!growbuf(line)) {
        !           980:                        error(NORM,35);
        !           981:                        return(0);
        !           982:                }
        !           983:        }
        !           984:        nlines=line;
        !           985:        
        !           986:        s = (len+1+LSMALL)>>LSSHIFT;
        !           987:        if (((BUFEND-1) & BRMASK) != ((BUFEND+s-1)&BRMASK)) {
        !           988: 
        !           989: /* Need to go into the next block */
        !           990:                
        !           991:                nxtflsh++;
        !           992:                if (nxtflsh>=NBLOCK) nxtflsh=fbkno;
        !           993:                x = nxtflsh;
        !           994:                bflush(x);
        !           995:                BUFEND=((BUFEND-1)&BRMASK)+BFACT;
        !           996:                bstat[x]=1;
        !           997:                lowpt[x]=hipt[x]=line;
        !           998:                bblock[x]=(BUFEND>>BRSHIFT);
        !           999:        }
        !          1000:        ptrs[nlines] = BUFEND<<1;
        !          1001:        lp = &bbuf[nxtflsh][((BUFEND&BRESID)<<LSSHIFT)];
        !          1002:        *lp++ = s;                      /* save size */
        !          1003:        while ((*lp++ = *cp++) != EOL); /* copy the line */
        !          1004:        BUFEND += s;
        !          1005:        return(1);
        !          1006: }
        !          1007: 
        !          1008: 
        !          1009: 
        !          1010: /* findf -- go forward to find row and columns */
        !          1011: 
        !          1012: /* leaves kline, kcol pointing at the character count characters ahead
        !          1013: of curln, column */
        !          1014: 
        !          1015: 
        !          1016: findf(count)
        !          1017: 
        !          1018: register int count;
        !          1019: /* Keywords: buffer-representation:10 movement:20 commands:10 forwards */
        !          1020: 
        !          1021: {
        !          1022:        kmark();
        !          1023:        while (count--) {
        !          1024:                if (*klptr++ != EOL) kcol++;
        !          1025:                else {
        !          1026:                        if (kline == nlines) return(0);
        !          1027:                        kcol = 0;
        !          1028:                        ++kline;
        !          1029:                        klptr = mkline(kline);
        !          1030:                }
        !          1031:        }
        !          1032:        return(1);
        !          1033: }
        !          1034: 
        !          1035: /* findb -- go back n chars */
        !          1036: 
        !          1037: /* leaves kline, kcol pointing at the character count characters before
        !          1038: the current character */
        !          1039: /* Keywords: buffer-representation:10 movement:20 commands:10 backwards */
        !          1040: findb(count)
        !          1041: 
        !          1042: register int count;
        !          1043: 
        !          1044: {
        !          1045:        kline = curln;
        !          1046:        kcol = column;
        !          1047:        
        !          1048:        while (count) {
        !          1049:                if (count > kcol) {
        !          1050:                        count-=(kcol+1);        /*plus one for the nl */
        !          1051:                        kcol = 0;
        !          1052:                        if (kline == 1) return(0);
        !          1053:                        kline--;
        !          1054:                        kcol = leng(kline);
        !          1055:                } else {
        !          1056:                        kcol -= count;
        !          1057:                        return(1);
        !          1058:                }
        !          1059:        }
        !          1060:        return(1);
        !          1061: }
        !          1062: 
        !          1063: 
        !          1064: /* mark a line as modified (also re-displays mode line if necessary) */
        !          1065: 
        !          1066: 
        !          1067: modify(line)
        !          1068: /* Keywords: buffer-representation:10 dired:20 mode-line:10 deletion:10 insertion:10 */
        !          1069: 
        !          1070: register int line;
        !          1071: 
        !          1072: {
        !          1073:        
        !          1074:        if (INMEM(line)) {
        !          1075:                bstat[(ptrs[line])>>BSHIFT] = 1;
        !          1076:        }
        !          1077: #ifdef DIRED
        !          1078:        if (diron) {
        !          1079:                register char *lp;
        !          1080:                lp = mkline(line);
        !          1081:                if ((column > 4) && (column < 14)) {
        !          1082:                        lp[1] = 'M';
        !          1083:                } else if ((column > 18) && (column < 36)) {
        !          1084:                        lp[2] = 'O';
        !          1085:                }
        !          1086:                sputl(line,1,line);     /* refresh */
        !          1087:        }
        !          1088: #endif
        !          1089:        if (bufmod == 0) {
        !          1090:                bufmod++;
        !          1091:                dispmod();
        !          1092:        }
        !          1093: }
        !          1094: 
        !          1095: /* stack text segment on kill stack */
        !          1096: 
        !          1097: /* the kill stack holds up to NKILLP segments, or a total of KBSIZE
        !          1098:  * characters.  killstk adds the segment delimited by its arguments to
        !          1099:  * this stack */
        !          1100: 
        !          1101: killstk(a,b,c,d)
        !          1102: /* Keywords: killstack stacking picture-mode:10 deletion:10 */
        !          1103: 
        !          1104: register int a;
        !          1105: register int b;
        !          1106: int c;
        !          1107: int d;
        !          1108: 
        !          1109: {
        !          1110:        register char *ap;
        !          1111:        
        !          1112:        if (kbapp) {                    /* if appending */
        !          1113:                kend--;                 /* backspace over the \0 */
        !          1114:        } else {
        !          1115:                if (nkp == NKILLP)  {   /* no more kill pointers available */
        !          1116:                        mvdown();
        !          1117:                }
        !          1118:                nkp++;
        !          1119:                kstk[nkp] = kend;               /* start of saved text */
        !          1120:        }
        !          1121:        kget(kend);
        !          1122: 
        !          1123:        if (PICMODE) {
        !          1124:                int x;
        !          1125:                if (b>d) {
        !          1126:                        x=d;
        !          1127:                        d=b;
        !          1128:                        b=x;
        !          1129:                }
        !          1130:                while (a <= c) {
        !          1131:                        ap = mkline(a);
        !          1132:                        a++;
        !          1133:                        for (x = 0; x < d; x++) {
        !          1134:                                if (x<b) {
        !          1135:                                        if (*ap != EOL) ap++;
        !          1136:                                } else {
        !          1137:                                        if (*ap != EOL) {
        !          1138:                                                kbuf[kptr++] = *ap++;
        !          1139:                                        } else {
        !          1140:                                                kbuf[kptr++] = ' ';
        !          1141:                                        }
        !          1142:                                        kbmod=1;
        !          1143:                                        if (kptr>=KBSIZE) knext();
        !          1144:                                }        
        !          1145:                        }         
        !          1146:                        if (a<=c) {
        !          1147:                                kbmod=1;
        !          1148:                                kbuf[kptr++] = EOL;
        !          1149:                                if (kptr>=KBSIZE) knext();
        !          1150:                        }        
        !          1151:                }         
        !          1152:        } else {    
        !          1153:                ap = mkline(a);
        !          1154:                while ((a < c) || (b < d) ) {
        !          1155:                        if ((kbuf[kptr] = ap[b++]) == EOL) {
        !          1156:                                ++a;     
        !          1157:                                ap = mkline(a);
        !          1158:                                b = 0;  
        !          1159:                        }        
        !          1160:                        kbmod = 1;
        !          1161:                        if (++kptr>=KBSIZE) {
        !          1162:                                knext();
        !          1163:                        }        
        !          1164:                }         
        !          1165:        }          
        !          1166:        kbapp = 0;                      /* don't turn on append for now */
        !          1167:        kbuf[kptr++] = 0;
        !          1168:        kbmod = 1; 
        !          1169:        if (kptr>=KBSIZE) {
        !          1170:                knext();  
        !          1171:        }          
        !          1172:        kend = (long)kptr + kbase;
        !          1173: }
        !          1174: stkstr(sp)
        !          1175: /* Keywords: killstack stacking macro-programming:50 */
        !          1176: 
        !          1177: register char *sp;
        !          1178: {
        !          1179:        register char c;
        !          1180:        
        !          1181:        if (kbapp) {                    /* if appending */
        !          1182:                kend--;                 /* backspace over the \0 */
        !          1183:        } else {
        !          1184:                if (nkp == NKILLP)  {   /* no more kill pointers available */
        !          1185:                        mvdown();
        !          1186:                }
        !          1187:                nkp++;
        !          1188:                kstk[nkp] = kend;               /* start of saved text */
        !          1189:        }
        !          1190:        kget(kend);
        !          1191:        do {
        !          1192:                c = kbuf[kptr++] = *sp++;
        !          1193:                kbmod = 1;
        !          1194:                if (kptr>=KBSIZE) knext();
        !          1195:        } while (c);
        !          1196:        kend = (long)kptr + kbase;
        !          1197:        kbapp = 0;
        !          1198: }
        !          1199: 
        !          1200: kput(ptr)
        !          1201: unsigned int ptr;
        !          1202: {
        !          1203: /* Keywords: killstack stacking string-variables macro-programming:20 */
        !          1204:        
        !          1205:        long real_ptr;
        !          1206:        int x;
        !          1207: 
        !          1208:        if (sizeof(x) < 4) {            /* If int's are only 16 bits, adjust ptr */
        !          1209:                
        !          1210:                real_ptr = kend & 0177777;
        !          1211:                if (real_ptr > ptr) real_ptr = ((long) ptr) + (kend & 037777600000);
        !          1212:                else real_ptr = ((long) ptr) + (kend & 037777600000) -65536;
        !          1213:        } else real_ptr = ptr;
        !          1214: 
        !          1215:        if ((real_ptr < 0) || (real_ptr >= kend)) {
        !          1216:                error (WARN,82);
        !          1217:                real_ptr = 0;
        !          1218:        }
        !          1219:        if (nkp == NKILLP)  {   /* no more kill pointers available */
        !          1220:                mvdown();
        !          1221:        }
        !          1222:        nkp++;
        !          1223:        kstk[nkp] = real_ptr;           /* start of saved text */
        !          1224: }
        !          1225: kgptr()
        !          1226: {
        !          1227: /* Keywords: killstack stacking insertion:10 retrieval:10 string-variables:10 */
        !          1228:        if (nkp>-1) {
        !          1229:                nkp--;
        !          1230:                return(kstk[nkp+1]);
        !          1231:        } else {
        !          1232:                return(0);                      /* Error, too many pops */
        !          1233:        }
        !          1234: }
        !          1235: 
        !          1236:        
        !          1237: 
        !          1238: /* kapp -- append to kill buffer */
        !          1239: 
        !          1240: kapp()
        !          1241: {
        !          1242: /* Keywords: commands killstack appending */
        !          1243:        
        !          1244:        kbapp = 2;                      /* force next kill to append */
        !          1245: }
        !          1246: 
        !          1247: /*knext -- next kill buffer*/
        !          1248: 
        !          1249: 
        !          1250: knext()
        !          1251: {
        !          1252:        long nbase;
        !          1253: /* Keywords: killstack paging */
        !          1254:        
        !          1255:        nbase = kbase + (long) KBSIZE;
        !          1256:        if (nbase >= KBLIM) nbase = 0;
        !          1257:        kget(nbase);
        !          1258: }
        !          1259: 
        !          1260: 
        !          1261: /* kget get next kill buffer */
        !          1262: 
        !          1263: kget(nbase)
        !          1264: long nbase;
        !          1265: {
        !          1266: /* Keywords: killstack paging paging-I/O */
        !          1267:        
        !          1268:        register long xbase;
        !          1269:        int st;
        !          1270:        
        !          1271: #ifdef univac                                          /* MZ */
        !          1272:        xbase = nbase & 0xffffffe00;    /* Univac uses one's compliment. */
        !          1273: #else                                  /* MZ */
        !          1274:        xbase = nbase &( (long) -KBSIZE);
        !          1275: #endif                                 /* MZ */
        !          1276: 
        !          1277:        if (xbase == kbase) {
        !          1278:                kptr = nbase - kbase;
        !          1279:                return;
        !          1280:        }
        !          1281:        if (kfile == 0) {
        !          1282:                kfile = gtemp(NBUF);
        !          1283:        }
        !          1284:        if (kbmod) {
        !          1285: retry:         lseek(kfile,kbase,0);
        !          1286:                while(write(kfile,kbuf,KBSIZE) != KBSIZE) {
        !          1287: #ifdef PC
        !          1288:                        if (mkspace()) goto retry;
        !          1289:                        break;
        !          1290: #else
        !          1291:                        if (errno != 4) error(FATAL,errno,"kill buffer");
        !          1292: #endif
        !          1293:                }
        !          1294:                if (kbase >= kbwrt) kbwrt = kbase+KBSIZE;
        !          1295:                kbmod = 0;
        !          1296:        }
        !          1297:        if (nbase < kbwrt) {
        !          1298:                lseek(kfile,xbase,0);
        !          1299:                while((st=read(kfile,kbuf,KBSIZE) != KBSIZE)) {
        !          1300:                        if (errno != 4) {
        !          1301:                                error(FATAL,errno,"reading kill buffer");
        !          1302:                                return;
        !          1303:                        }
        !          1304:                }
        !          1305:        }
        !          1306:        kbase = xbase;
        !          1307:        kptr = nbase-xbase;
        !          1308:        return;
        !          1309: }
        !          1310: 
        !          1311: /* mvdown pushes the bottom text segment off of the kill stack */
        !          1312: 
        !          1313: 
        !          1314: 
        !          1315: mvdown()               /* move down kill stack */
        !          1316: /* Keywords: killstack stacking */
        !          1317: 
        !          1318: {
        !          1319:        register int i;
        !          1320:        for (i = 0; i <= nkp; i++) kstk[i] = kstk[i+1];
        !          1321:        nkp--;
        !          1322: }
        !          1323: 
        !          1324: /* retrv retrieves the top text segment from the kill stack and inserts
        !          1325:   * it into the buffer at the current location */
        !          1326: 
        !          1327: 
        !          1328: retrv()        /* retrieve from kill stack */
        !          1329: /* Keywords: commands killstack picture-mode:20 insertion:10 retrieval */
        !          1330: 
        !          1331: {
        !          1332:        register char c;
        !          1333:        register int oldcol,oldln;
        !          1334:        
        !          1335:        if (nkp <0) return(0);          /* nothing in the kill stack */
        !          1336:        RARE = 1;                       /* turn off trouble */
        !          1337:        oldln = curln;
        !          1338:        oldcol = column;
        !          1339:        kget(kstk[nkp]);
        !          1340:        while (c= kbuf[kptr]) {
        !          1341:                if (PICMODE) {
        !          1342:                        if (c==EOL) {
        !          1343:                                move(++curln,0);
        !          1344:                                lext(curln,oldcol);
        !          1345:                        } else {
        !          1346:                                insertc(1,c);
        !          1347:                        }
        !          1348:                } else {
        !          1349:                        if(put(c)==0) break;
        !          1350:                }
        !          1351:                if (++kptr >= KBSIZE) {
        !          1352:                        knext();
        !          1353:                }
        !          1354:        }
        !          1355:        RARE = 0;                       /* normal modes back on */
        !          1356:        unins(oldln,oldcol);
        !          1357:        return(1);                              /* done */
        !          1358: }
        !          1359: 
        !          1360: retrvs(strp,mc)                        /* retrieve from kill stack */
        !          1361: /* Keywords: commands killstack macro-programming retrieval */
        !          1362: 
        !          1363: register char *strp;
        !          1364: register int mc;
        !          1365: {
        !          1366:        register int nc;
        !          1367: 
        !          1368:        nc = 0;
        !          1369: 
        !          1370: 
        !          1371:        kget(kstk[nkp]);
        !          1372:        while (*strp++ = kbuf[kptr]) {
        !          1373:                if (++nc >= mc) {
        !          1374:                        *(--strp) = 0; /* finish off string */
        !          1375:                        error(WARN,63); /* file name too big */
        !          1376:                        break;          /* break loop */
        !          1377:                }
        !          1378:                if (++kptr >= KBSIZE) {
        !          1379:                        knext();
        !          1380:                }
        !          1381:        }
        !          1382:        kpop();                         /* pop the kill stack */
        !          1383:        if (etrace) {
        !          1384:                putout("Retrieved %s from kill stack",strp-nc-1);
        !          1385:        }
        !          1386:        return(nc);                             /* done */
        !          1387: }
        !          1388: 
        !          1389: /* kpop pops the top item off of the kill stack */
        !          1390: kpop()
        !          1391: /* Keywords: commands killstack stacking popping */
        !          1392: 
        !          1393: {
        !          1394:        if (nkp>-1) {
        !          1395:                nkp--;
        !          1396:                return(1);
        !          1397:        } else return(0);
        !          1398: }
        !          1399: 
        !          1400: /* fsave saves the buffer if it has been modified since last read or write */
        !          1401: 
        !          1402: 
        !          1403: fsave(arg)
        !          1404: register int arg;
        !          1405: {
        !          1406: /* Keywords: commands buffers files writing:50 saving dired:10 */
        !          1407:        
        !          1408:        if ((arg == 0) && (streq(bbfname[curbf],".exec"))) return(0);
        !          1409: 
        !          1410: #ifdef DIRED
        !          1411:        if (diron) return(dclean());
        !          1412: #endif
        !          1413:        if (READONLY) {
        !          1414:                if (arg) error(WARN,71);
        !          1415:                return(0);
        !          1416:        }
        !          1417:        if (bufmod && (*filename== 0)) {
        !          1418:                if (infrn == 0) return(fright(1)); /* no file name */
        !          1419:                error(WARN,65,bufname); /* Don't read the file name in a macro */
        !          1420:                return(0);
        !          1421:        }
        !          1422: 
        !          1423:        if (bufmod) {
        !          1424:                return(wout(filename,1));
        !          1425:        } else {
        !          1426:                if (arg == 0) return(1);
        !          1427:                prompt1("File %s is up to date",filename);
        !          1428:                return(1);
        !          1429:        }
        !          1430: }
        !          1431: 
        !          1432: /* fname, bname, and modded return the current file, buffer, and buffer
        !          1433:  * modified flags */
        !          1434: 
        !          1435: 
        !          1436: char *
        !          1437: fname()
        !          1438: {
        !          1439:        return(filename);
        !          1440: }
        !          1441: char *
        !          1442: bname()
        !          1443: {
        !          1444:        return(bufname);
        !          1445: }
        !          1446: int
        !          1447: bfnumb()
        !          1448: {
        !          1449:        return(curbf);
        !          1450: }
        !          1451: int
        !          1452: modded()
        !          1453: {
        !          1454:        if (bufmod) return(1);
        !          1455:        else return(0);
        !          1456: }
        !          1457: 
        !          1458: /* chbuf moves to a new buffer denoted by the buffer number of its
        !          1459:  * argument */
        !          1460: 
        !          1461: /* each buffer has a filename, buffername, modified flag, current
        !          1462:  * position, and size,  The ptrs array of a non-active buffer is stored in
        !          1463:  * the temp file for the buffer.
        !          1464:  */
        !          1465: 
        !          1466: chbuf(x)
        !          1467: 
        !          1468: register int x;
        !          1469: /* Keywords: buffers:50 buffer-representation buffer-changing unix-interface macro-hooks:10 */
        !          1470: 
        !          1471: {
        !          1472:        register int i;
        !          1473:        register int rx;
        !          1474:        unsigned cpointer;
        !          1475: 
        !          1476:        
        !          1477:        if (SAVEMD) IGNORE(fsave(0)); /* save buffer */
        !          1478:        if (hooks[Leave_Buffer_Hook]) hook(Leave_Buffer_Hook);
        !          1479:        for (i = fbkno; i < NBLOCK; i++) bflush(i);
        !          1480:        allout();
        !          1481:        NSCHAR = 0;
        !          1482:        btmpfile[curbf] = BUFILE;
        !          1483:        btmpfree[curbf] = BUFEND;
        !          1484:        bcurln[curbf] = curln;
        !          1485:        bcolumn[curbf] = column;
        !          1486:        if (BUFILE) {
        !          1487:                while (1) {
        !          1488:                        lseek(BUFILE,(long)((long) BUFEND * (long) LSMALL),0);
        !          1489:                        rx = write(BUFILE,(char *)ptrs,(nlines+1)*(sizeof cpointer));
        !          1490:                        if (rx == (nlines+1)*(sizeof cpointer)) break;
        !          1491: #ifdef PC
        !          1492:                        mkspace();
        !          1493: #endif
        !          1494:                }
        !          1495:        }
        !          1496:        bnlines[curbf] = nlines;
        !          1497: #ifdef MINFILES
        !          1498:        if (BUFILE) close(BUFILE);
        !          1499:        if (btmpfile[x]) btmpfile[x] = otemp(x);
        !          1500: #endif 
        !          1501:        curbf = x;
        !          1502:        bufinit();
        !          1503:        
        !          1504:        BUFEND = btmpfree[x];
        !          1505:        mostwrit = ((BUFEND-1)/BFACT);
        !          1506:        BUFILE = btmpfile[x];
        !          1507:        nlines = bnlines[x];
        !          1508:        if (BUFILE) {
        !          1509:                while (1) {
        !          1510:                        lseek(BUFILE, (long)((long) BUFEND * (long) LSMALL),  0);
        !          1511:                        rx = read(BUFILE,(char *)ptrs, (nlines+1)*(sizeof cpointer));
        !          1512:                        if (rx ==(nlines+1)*(sizeof cpointer)) break;
        !          1513:                        if (errno != 4) error (FATAL,errno,"Reading line pointers");
        !          1514:                }
        !          1515:        }
        !          1516:        
        !          1517:        bfmodes();                      /* set buffer modes */
        !          1518:        move(bcurln[x],bcolumn[x]);
        !          1519:        if (bnlines[x] == 0) bufmod = 0; /* EMPTY BUFFERS CAN'T HAVE BEEN MODIFIED!!!! */
        !          1520:        if (hooks[Enter_Buffer_Hook]) hook(Enter_Buffer_Hook);
        !          1521: }
        !          1522: 
        !          1523: /* chgbuf changes buffers by name.  If no buffer of the right name
        !          1524:  * exists, one is made */
        !          1525: 
        !          1526: 
        !          1527: chgbuf(sp)
        !          1528: /* Keywords: buffers commands:10 buffer-representation:20 */
        !          1529: 
        !          1530: char *sp;
        !          1531: 
        !          1532: {
        !          1533:        int i;
        !          1534:        i = finbuf(sp,1);
        !          1535:        if (i >= 0) {
        !          1536:                chbuf(i);
        !          1537:                return(1);
        !          1538:        }
        !          1539:        return(0);
        !          1540: }
        !          1541: 
        !          1542: 
        !          1543: finbuf(sp,crflg)
        !          1544: /* Keywords: commands:20 buffers:50 files:50 reading:20 buffer-changing */
        !          1545: 
        !          1546: char *sp;
        !          1547: int crflg;
        !          1548: {
        !          1549:        register int ep = -1;
        !          1550:        register int i;
        !          1551:        
        !          1552:        if (*sp == 0) {
        !          1553:                error(WARN,36);
        !          1554:                return(-1);
        !          1555:                }
        !          1556:        for (i = 0; i < NBUF; i++) {
        !          1557:                if (streq(sp,bbfname[i])) {
        !          1558:                        return(i);
        !          1559:                }
        !          1560:                if ((ep < 0) && (bbfname[i] [0] == 0)) ep = i;
        !          1561:        }
        !          1562:        i = aint(sp);                   /* try numeric buffer name */
        !          1563:        if ((i < NBUF) && (i >= 0)) {
        !          1564:                if (bbfname[i] [0] == 0) {
        !          1565:                        inibuf(i);
        !          1566:                        seprintf(bbfname[i],"%d",i); /* name buffer */
        !          1567:                }
        !          1568:                return(i);
        !          1569:        }
        !          1570:        if (crflg == 0) return(-1);     /* Don't create new buffer */
        !          1571:        if (crflg < 0) {                /* Complain about buffer */
        !          1572:                error(WARN,39,sp);
        !          1573:                return(-1);
        !          1574:        }
        !          1575:        
        !          1576: /* Buffer does not now exist, create it */
        !          1577:        
        !          1578:        if (ep>=0) {
        !          1579:                inibuf(ep);
        !          1580:                if (streq(sp,"...")) seprintf(bbfname[ep],"%d",ep);
        !          1581:                else strcpy(bbfname[ep],sp);
        !          1582:                return(ep);
        !          1583:        } else {
        !          1584:                error(WARN,37,NBUF);
        !          1585:                return(-1);
        !          1586:        }
        !          1587: }
        !          1588: 
        !          1589: /* inibuf -- initialize buffer data */
        !          1590: 
        !          1591: inibuf(ep)
        !          1592: register int ep;                               /* buffer number  */
        !          1593: /* Keywords: buffer-representation buffers commands:10 */
        !          1594: 
        !          1595: {
        !          1596:        bbfname[ep] [0] = 0;
        !          1597:        btmpfree[ep] = 0;
        !          1598:        bcurln[ep] = bcolumn[ep] = 0;
        !          1599:        bnlines[ep] = 0;
        !          1600:        bbfmod[ep] = 0;
        !          1601:        bfilname[ep] [0] = 0;
        !          1602:        mtime[ep] = 0;
        !          1603: }
        !          1604: 
        !          1605: /* edbuf is the find file command, it asks for a filename, finds a
        !          1606:  * buffer containing the file if it exists, otherwise it makes a new buffer
        !          1607:  * to hold the file */
        !          1608: 
        !          1609: edbuf(arg)
        !          1610: /* Keywords: commands buffers buffer-changing reading:10 files dired:20 */
        !          1611: 
        !          1612: int arg;
        !          1613: {
        !          1614:        register int i;
        !          1615:        int retv;
        !          1616:        int exists;
        !          1617:        char *sp;
        !          1618: #ifdef DIRED
        !          1619:        char nbuf[256];
        !          1620: #endif
        !          1621:        exists = 0;
        !          1622:        sp = expenv(getname("Filename to Find? "));
        !          1623:        if (sp == NULL) return(0);
        !          1624: #ifdef DIRED
        !          1625:        if (*sp != '/') {
        !          1626:                catstr(nbuf,filename,sp); /* relative path */
        !          1627:                if ((nbuf[0] == '.') && (nbuf[1] == '/')) sp = nbuf+2;
        !          1628:                else sp = nbuf;
        !          1629:        }
        !          1630: #endif
        !          1631:        for (i = 0; i < NBUF; i++) {
        !          1632:                if (streq(bfilname[i], sp)) {
        !          1633:                        chbuf(i);
        !          1634:                        if (arg > 1) return(readin(sp,1));
        !          1635:                        return(1);
        !          1636:                }
        !          1637:                if (streq(bbfname[i], sp)) {
        !          1638:                        exists = 1;
        !          1639:                }
        !          1640:        }
        !          1641:        if (exists) retv = chgbuf("...");
        !          1642:        else retv = chgbuf(sp);
        !          1643:        if (retv) retv=readin(sp,arg);
        !          1644:        return(retv);
        !          1645: }
        !          1646: 
        !          1647: /* cpbuf is the change buffer command, it prompts for a buffer name and
        !          1648:  * mmoves to  it unless the name is '*', in which case a list of active
        !          1649:  * buffers is displayed */
        !          1650: 
        !          1651: cpbuf(arg)
        !          1652: /* Keywords: commands buffer-changing files:10 */
        !          1653: int arg;
        !          1654: {
        !          1655:        int i;
        !          1656:        i = fndbuf(arg);
        !          1657:        if (arg && (i >= 0)) chbuf(i);
        !          1658:        return(i>= 0);
        !          1659: }
        !          1660: buflist()                              /* list active buffers */
        !          1661: /* Keywords: commands buffers user-interface informational-displays */
        !          1662: 
        !          1663: {
        !          1664:        register int i;
        !          1665:        char c;
        !          1666:        
        !          1667:        mtop();
        !          1668:        putout("Buffers used:");
        !          1669:        putout ("");
        !          1670:        for(i = 0; i < NBUF; i++) {
        !          1671:                if (bbfname[i] [0] ) {
        !          1672:                        if (i == curbf) c = '*';
        !          1673:                        else c = ' ';
        !          1674:                        putout ("%c (%d) %s  %c  %s",
        !          1675:                        c,i,bbfname[i],mdchar[bbfmod[i]], bfilname[i]);
        !          1676:                }
        !          1677:        }
        !          1678:        putout (endput);
        !          1679:        return(contin());
        !          1680: }
        !          1681: 
        !          1682: 
        !          1683: /* fndbuf finds/creates a buffer with a given name */
        !          1684: 
        !          1685: 
        !          1686: fndbuf(crflg)
        !          1687: int crflg;
        !          1688: {
        !          1689: /* Keywords: commands:20 buffers files:20 windows:10 */
        !          1690:        
        !          1691: 
        !          1692:        register char *bn;
        !          1693:        
        !          1694: again: bn = getname("Buffer Name? ");
        !          1695:        
        !          1696:        if (bn == NULL) return(-1);
        !          1697:        if ((*bn == 0) || (*bn == '*')) {
        !          1698:                if(buflist()) return(-1);
        !          1699:                else goto again;
        !          1700:        }
        !          1701:        return(finbuf(bn,crflg));
        !          1702: }      
        !          1703: 
        !          1704: /* bufmove -- pipe text from one buffer to another */
        !          1705: 
        !          1706: /* sends the text in the region to a specified buffer */
        !          1707: 
        !          1708: bfsend(arg)
        !          1709: 
        !          1710: int arg;
        !          1711: {
        !          1712:        register int i;
        !          1713:        register int j;
        !          1714:        
        !          1715: /* Keywords: commands buffers regions insertion:20 buffer-changing:50 */
        !          1716:        
        !          1717:        i = fndbuf(1);
        !          1718:        if (i >= 0) {
        !          1719:                pickup(arg);            /* pick up the region */
        !          1720:                j = curbf;
        !          1721:                chbuf(i);
        !          1722:                if (i == procbuf) {
        !          1723:                        bot(); /* Force insertion to the bottom */
        !          1724:                        mark(curbf); /* Force mark to end of buffer */
        !          1725:                }
        !          1726:                retrv();
        !          1727:                kpop();
        !          1728: #ifndef PC
        !          1729:                if (i == procbuf) {
        !          1730:                        exch(curbf);
        !          1731:                        while (curln < nlines) {
        !          1732:                                sendproc (mkline(curln)+column,leng(curln)+1-column);
        !          1733:                                curln++;
        !          1734:                                column=0;
        !          1735:                        }
        !          1736:                        sendproc (mkline(curln)+column,leng(curln)-column);
        !          1737:                        bot();
        !          1738:                }
        !          1739: #endif
        !          1740:                chbuf(j);               /* back to old buffer */
        !          1741:        }
        !          1742: }
        !          1743: 
        !          1744: /* rnbuf -- rename buffer or buffer file */
        !          1745: 
        !          1746: 
        !          1747: rnbuf(arg)
        !          1748: 
        !          1749: int arg;
        !          1750: /* Keywords: commands buffers:50 files:50 naming */
        !          1751: 
        !          1752: {
        !          1753:        register char *sp;
        !          1754:        int bn;
        !          1755:        
        !          1756:        sp = expenv(getname("New Name? "));
        !          1757:        if ((sp== NULL) || ((arg == 1) && (*sp == NULL))) return;
        !          1758:        if (arg == 1) {                 /* change buffer name */
        !          1759:                bn = finbuf(sp,0);
        !          1760:                if ((bn >= 0) && (bn != curbf)) {
        !          1761:                                        /* (allow change to current name */
        !          1762:                        error(WARN,38,sp); /* Buffer name in use */
        !          1763:                        return;
        !          1764:                }
        !          1765:                strcpy(bbfname[curbf],sp);
        !          1766:        } else {
        !          1767:                strcpy(bfilname[curbf],sp);
        !          1768:                mtime[curbf]=0;         /* Buffer wasn't read from this file */
        !          1769: 
        !          1770:        }
        !          1771:        dispmod();
        !          1772: }
        !          1773: 
        !          1774: /* rmbuf prompts for a buffer name and removes the buffer */
        !          1775: 
        !          1776: 
        !          1777: rmbuf()
        !          1778: /* Keywords: buffers commands deletion */
        !          1779: 
        !          1780: {
        !          1781:        register int i;
        !          1782:        
        !          1783:        if ((i = fndbuf(-1)) >= 0) {
        !          1784:                klbfr(i);
        !          1785:                return(1);
        !          1786:        } 
        !          1787:        return(0);
        !          1788: }
        !          1789: klbfr(i)
        !          1790: 
        !          1791: register int i;
        !          1792: /* Keywords: commands:10 buffers buffer-representation:20 deletion unix-interface:10 shell-escape:20 */
        !          1793: 
        !          1794: {
        !          1795:        if (i == curbf) {
        !          1796:                IGNORE(error (WARN,40));
        !          1797:                return;
        !          1798:        }
        !          1799: #ifndef PC
        !          1800:        if (i == procbuf) flushproc();
        !          1801: #endif
        !          1802:        if (i == windbuf()) onewind();          /* killing other window */
        !          1803: 
        !          1804:        if (btmpfile[i]) {
        !          1805: #ifdef MINFILES
        !          1806:                rftmp(i);
        !          1807: #else
        !          1808:                close(btmpfile[i]);
        !          1809: #endif
        !          1810:                btmpfile[i] = 0;
        !          1811:        }
        !          1812:        inibuf(i);
        !          1813: }
        !          1814: 
        !          1815: /* clean up unwritten buffers.  bclean checks for unwritten buffers, and
        !          1816:  * if any are found, writes them out if the user wishes */
        !          1817: 
        !          1818: bclean()
        !          1819: /* Keywords: dired:20 saving:70 exit-processing files:30 user-interface:10 */
        !          1820: 
        !          1821: {
        !          1822:        register int i;
        !          1823:        
        !          1824:        bbfmod[curbf] = bufmod;
        !          1825:        bnlines[curbf] = nlines;
        !          1826: #ifdef DIRED
        !          1827:        if (diron) fsave(0);
        !          1828: #endif 
        !          1829:        for (i = 0; i < NBUF; i++) {
        !          1830:                if ((bbfmod[i]) && (bbfname[i] [0]) &&
        !          1831:                        (bnlines[i] > 1) &&
        !          1832:                        (READONLY == 0) &&
        !          1833:                        (streq(bbfname[i],".exec") == 0)){
        !          1834: 
        !          1835: 
        !          1836:                        if (SAVEMD) {
        !          1837:                                chbuf(i);
        !          1838:                                fsave(0);
        !          1839:                                
        !          1840:                        } else {
        !          1841:                                switch (gyn("buffer %s modified since last write to file %s, write?",
        !          1842:                                        &(bbfname[i][0]),&(bfilname[i][0]))) {
        !          1843:                                case 0:
        !          1844:                                        break; /* no  */
        !          1845:                                case 1:
        !          1846:                                        /* yes answer */
        !          1847:                                        chbuf(i);
        !          1848:                                        if(fsave(1)<= 0) return(-1);
        !          1849:                                        break;
        !          1850:                                case -1:
        !          1851:                                default:
        !          1852:                                        unprompt(); /* clean up msg */
        !          1853:                                        return(-1);
        !          1854:                                }
        !          1855:                        }
        !          1856:                }
        !          1857:        }
        !          1858:        return(0);
        !          1859: }
        !          1860: 
        !          1861: crash(arg)                                     /* handle crashes */
        !          1862: 
        !          1863: int arg;                               /* sometimes is reason for crash */
        !          1864: {
        !          1865: /* Keywords: internal-errors saving unix-interface:30 files:20 */
        !          1866: #ifndef PC     
        !          1867:        register int i;
        !          1868:        register char *home;
        !          1869:        register int x = 0;
        !          1870: 
        !          1871:        signal(SIGHUP,SIG_IGN);
        !          1872:        signal(SIGINT,SIG_IGN);         /* go into our shell */
        !          1873: 
        !          1874:        if (arg == SIGHUP) {
        !          1875:                no_io = 1;      /* Make sure we do no I/O */
        !          1876:                close(0);
        !          1877:                close(1);
        !          1878:                close(2);
        !          1879:                open("/dev/null",2);
        !          1880:                dup(0);
        !          1881:                dup(0);
        !          1882:        }
        !          1883:        if (crashes++) eabort(0);       /* one crash per customer */
        !          1884:        home = getenv("HOME");
        !          1885: 
        !          1886:        bbfmod[curbf] = bufmod;
        !          1887: 
        !          1888:        for (i = 0; i < NBUF; i++) {
        !          1889:                if ((bbfmod[i]) && (bbfname[i] [0])){
        !          1890:                        seprintf(bfilname[i],"%s/emacs%d",home,i);
        !          1891:                        chbuf(i);
        !          1892:                        mtime[curbf] = 0; /* Don't complain about previous file! */
        !          1893:                        IGNORE(fsave(0));
        !          1894:                        x++;            /* flag that we saved one */
        !          1895:                }
        !          1896:        }
        !          1897:        if (x) {
        !          1898:                USILENT++;
        !          1899:                infrn = -1;             /* Make sure that unx doesn't ask questions */
        !          1900:                unx("echo $LOGTTY your emacs buffers are in $HOME/emacs[0-9]* | mail $LOGNAME &",0);
        !          1901:        }
        !          1902: #endif
        !          1903:        quit();
        !          1904: }
        !          1905: 
        !          1906: /* collect -- garbage collection of buffer file */
        !          1907: 
        !          1908: collect()
        !          1909: 
        !          1910: /* Keywords: buffer-allocation buffer-representation killstack:20 */
        !          1911: {
        !          1912:        int oldcol;
        !          1913:        int oldln;
        !          1914:        int onlns;
        !          1915:        
        !          1916:        prompt1("Garbage collecting buffer");
        !          1917:        mflush(stdout);
        !          1918:        
        !          1919:        oldln = curln;
        !          1920:        oldcol = column;
        !          1921:        
        !          1922:        top();
        !          1923:        onlns = kline = nlines;
        !          1924:        kcol = leng(kline);
        !          1925:        tkill();                        /* kill all text into kill buffer */
        !          1926:        
        !          1927:        bufinit();                      /* reinit buffer storage */
        !          1928:        top();
        !          1929:        retrv();
        !          1930:        if (onlns != curln) {
        !          1931:                error(WARN,75);         /* buffer too large for emacs */
        !          1932:        }
        !          1933:        kpop();
        !          1934:        unpop(2);                       /* Ignore for undo */
        !          1935:        move(oldln,oldcol);
        !          1936:        unprompt();
        !          1937: }
        !          1938: 
        !          1939: /* pshchr -- push a character into the macro buffer */
        !          1940: 
        !          1941: pshchr(ch)
        !          1942: 
        !          1943: register int ch;
        !          1944: /* Keywords: memory-allocation:10 macro-programming:10 paging:20 */
        !          1945: /* Keywords: buffer-allocation:20 buffer-representation:20 */
        !          1946: {
        !          1947:        if (macptr >= fbkno*BLEN) {
        !          1948:                if ((fbkno+2<NBLOCK) && bgrab(fbkno++,0)){
        !          1949:                        /* grab another buffer */
        !          1950:                        if (nxtflsh < fbkno) nxtflsh = fbkno;
        !          1951:                        clptr=mkline(curln); /* Restore line pointer */
        !          1952:                } else error(FATAL,41); /* too many macros */
        !          1953:        }
        !          1954:        bbuf[0][macptr++] = ch;
        !          1955: }
        !          1956: 
        !          1957: pbfname()                              /* put buffer name in kill stack*/
        !          1958: {
        !          1959: /* Keywords: commands macro-programming naming buffers */
        !          1960:        stkstr(bname());
        !          1961: }
        !          1962: pfnname()                              /* put file name in kill stack */
        !          1963: /* Keywords: commands macro-programming naming files */
        !          1964: {
        !          1965:        stkstr(fname());
        !          1966: }
        !          1967: 
        !          1968: pvname(count)                          /* put version in kill stack */
        !          1969: int count;
        !          1970: {
        !          1971: /* Keywords: commands macro-programming naming versions */
        !          1972:        if (count) stkstr(version);
        !          1973:        else stkstr(serial);
        !          1974: }
        !          1975: 
        !          1976: recurse(arg)                           /* call emacs recursively */
        !          1977: int arg;
        !          1978: /* Keywords: user-interface:10 macro-programming:90 key-bindings:10 mode-line:5 recursive-editing commands:50 */
        !          1979: {
        !          1980:        long svkst[NKILLP+1];           /* kill buffer save area */
        !          1981:        int svnkp;
        !          1982:        register int i,c;
        !          1983:        char *omyname;
        !          1984:        char nmbuf[64];
        !          1985:        int eresult;
        !          1986:        
        !          1987: 
        !          1988:        if (arg == 0) {
        !          1989:                register char *map;
        !          1990:                map = getname(""); /* Termination map */
        !          1991:                pushin(NULL);           /* back to the tty */
        !          1992:                while (1) {
        !          1993:                        disup();
        !          1994:                        c = (getchar()&0177);
        !          1995: 
        !          1996: /* Map is a bit map of 4 bit bytes, each represented as a hex digit */
        !          1997:                        
        !          1998:                        i = map[c>>2];
        !          1999:                        if (i>'9') i = 9+(i&017);
        !          2000:                        else i = i - '0';
        !          2001:                        if (8 & (i<<(c&3))) put(c);
        !          2002:                        else {
        !          2003:                                inpop();
        !          2004:                                return(c);
        !          2005:                        }
        !          2006:                }
        !          2007:        }
        !          2008:        for (i = 0; i <= NKILLP; i++) svkst[i] = kstk[i];
        !          2009:        svnkp = nkp;
        !          2010:        omyname = myname;
        !          2011:        pushin(NULL);           /* back to the tty */
        !          2012:        seprintf(nmbuf,"%s*",myname);
        !          2013:        myname = nmbuf;
        !          2014:        dispmod();
        !          2015:        eresult = edit(1);
        !          2016:        myname = omyname; /* pop name */
        !          2017:        dispmod();
        !          2018:        inpop();                        /* pop input */
        !          2019:        for (i = 0; i <= NKILLP; i++) kstk[i] = svkst[i];
        !          2020:        nkp = svnkp;
        !          2021:        return(eresult);
        !          2022: }
        !          2023: 
        !          2024: kdup(arg)                              /* duplicate argument */
        !          2025: 
        !          2026: int arg;                               /* level to duplicate */
        !          2027: /* Keywords: commands macro-programming killstack string-variables:20 stacking */
        !          2028: {
        !          2029:        register long dupkp;
        !          2030:        
        !          2031:        if (arg > nkp) return(0);
        !          2032:        dupkp = kstk[nkp-arg];
        !          2033:        if (nkp == NKILLP) mvdown(); /* make room */
        !          2034:        kstk[++nkp] = dupkp;
        !          2035:        return(1);
        !          2036: }
        !          2037: 
        !          2038: kflush(count)                          /* flush kill stack */
        !          2039: 
        !          2040: register int count;
        !          2041: /* Keywords: commands macro-programming killstack string-variables:20 popping */
        !          2042: {
        !          2043:        while (count--) {
        !          2044:                if (kpop() == 0) return(0);
        !          2045:        }
        !          2046:        return(1);
        !          2047: }
        !          2048: 
        !          2049: kexch(count)                           /* exchange kill stack */
        !          2050: /* Keywords: commands macro-programming killstack string-variables:20 */
        !          2051: {
        !          2052:        register long dupkp;
        !          2053:        
        !          2054:        if (count<(nkp+1)) {
        !          2055:                dupkp = kstk[nkp];
        !          2056:                kstk[nkp] = kstk[nkp-count];
        !          2057:                kstk[nkp-count] = dupkp;
        !          2058:                return(1);
        !          2059:        } else return(0);
        !          2060: }
        !          2061: 
        !          2062: /* unmod -- mark or change buffer modified flag */
        !          2063: 
        !          2064: unmod(arg)
        !          2065: /* Keywords: mode-line:20 buffers:80 file-modes:10 files:20 macro-programming:50 */
        !          2066: {
        !          2067:        if (arg == 1) bufmod = 0;
        !          2068:        else if (arg > 1) bufmod = 1;
        !          2069:        dispmod();
        !          2070:        return(bufmod);
        !          2071: }
        !          2072: 
        !          2073: #ifdef PC
        !          2074: #define KBDFILE "c:emk"
        !          2075: #define KBDMODE 1
        !          2076: #else
        !          2077: #define KBDFILE "$HOME/.emacs_kbd"
        !          2078: #define KBDMODE 0666
        !          2079: #endif
        !          2080: strtkbd()
        !          2081: {
        !          2082: /* Keywords: commands macro-programming:20 filenames:10 unix-interface:40 keyboard-macros */
        !          2083:        if (kbdfile) endkbd();
        !          2084:        kbdfile = creat(expenv(KBDFILE),KBDMODE);
        !          2085:        return(kbdfile);
        !          2086: }
        !          2087: endkbd()
        !          2088: {
        !          2089: /* Keywords: commands macro-programming:20 filenames:10 unix-interface:40 keyboard-macros */
        !          2090:        if (kbdfile) close(kbdfile);
        !          2091:        kbdfile=0;
        !          2092: }
        !          2093: exkbd(arg)
        !          2094: register int arg;
        !          2095: /* Keywords: commands macro-programming:20 filenames:10 unix-interface:40 keyboard-macros */
        !          2096: {
        !          2097:        while (arg-- > 0) infile(KBDFILE);
        !          2098: }
        !          2099: setkey()
        !          2100: /* Keywords: commands files file-modes:50 encryption */
        !          2101: {
        !          2102: #ifdef CRYPTO
        !          2103:        char *kp;
        !          2104:        kp = getname("Encryption Key? ");
        !          2105:        if (kp && *kp) {
        !          2106:                strcpy(cryptkey,kp);
        !          2107:                crypt = 1;
        !          2108:        } else crypt = 0;
        !          2109: #else
        !          2110:        beep();
        !          2111: #endif
        !          2112: }
        !          2113: #ifndef PC
        !          2114: access(path, amode)
        !          2115: char *path;
        !          2116: int amode;
        !          2117: /* Keywords: file-modes files reading:20 writing:20 unix-interface */
        !          2118: {
        !          2119:        struct stat stb;
        !          2120:        register int uid;
        !          2121: 
        !          2122:        /*** This nonsense would not be necessary if ***/
        !          2123:        /*** the saccess in sys2.c would do the check based on ***/
        !          2124:        /*** the effective uid and gid instead of the real ones ***/
        !          2125: 
        !          2126:        if( stat(path, &stb) < 0 ) {
        !          2127:                return(-1);
        !          2128:        }
        !          2129: 
        !          2130:        if( (uid=geteuid())==0 || amode==0 ) {
        !          2131:                /*** super user or existence check only ***/
        !          2132: 
        !          2133:                return(0);
        !          2134:        }
        !          2135: 
        !          2136:        if( uid == stb.st_uid ) {
        !          2137:                /*** uid's match ***/
        !          2138: 
        !          2139:                amode <<= 6;
        !          2140:        } else {
        !          2141:                if( getegid() == stb.st_gid ) {
        !          2142:                        /*** gid's match ***/
        !          2143: 
        !          2144:                        amode <<= 3;
        !          2145:                }
        !          2146:        }
        !          2147: 
        !          2148:        if( (stb.st_mode&amode) == amode ) {
        !          2149:                return(0);
        !          2150:        }
        !          2151:        return(-1);
        !          2152: }
        !          2153: 
        !          2154: #endif PC
        !          2155: 
        !          2156: 
        !          2157: undoit(n,doit)
        !          2158: 
        !          2159: /* Keywords: undo insertion:50 deletion:50 killstack:20 */
        !          2160: 
        !          2161: int n;
        !          2162: int doit;
        !          2163: {
        !          2164:        int unline;
        !          2165:        int uncol;
        !          2166:        long unparm;
        !          2167:        int untype;
        !          2168:        
        !          2169: 
        !          2170:        uncol = undostack[--n] & (MAXEL-1);
        !          2171:        unline = undostack[n]>>MAXELSH;
        !          2172:        move(unline,uncol);
        !          2173:        unparm = undostack[--n]>>UNDSHIFT;
        !          2174:        untype = undostack[n] & UNDMASK;
        !          2175: 
        !          2176:        switch(untype) {
        !          2177:                
        !          2178:        case UNINS:
        !          2179:                if (doit) {
        !          2180:                        kline = unparm >>MAXELSH;
        !          2181:                        kcol = unparm & (MAXEL-1);
        !          2182:                        tkill();
        !          2183:                        kpop();
        !          2184:                }
        !          2185:                break;
        !          2186:        case UNBAD:                     /* Multiple undo that exceeds limits */
        !          2187:        
        !          2188:                if (error(WARN,85)) return(n);
        !          2189: 
        !          2190:        case UNMUL:                     /* Multi-segment undo */
        !          2191:                while (unparm>0) {
        !          2192:                        untype = undoit(n,doit);
        !          2193:                        uncol = n-untype;
        !          2194:                        if (uncol<0) uncol += NUNDO;
        !          2195:                        unparm -= uncol/2;
        !          2196:                        n = untype;
        !          2197:                }
        !          2198:                break;
        !          2199:        case UNDEL:
        !          2200:                if (doit) {
        !          2201:                        if (nkp == NKILLP)  {   /* no more kill pointers available */
        !          2202:                        mvdown();
        !          2203:                        }
        !          2204:                        nkp++;
        !          2205:                        kstk[nkp] = unparm;
        !          2206:                        retrv();
        !          2207:                }
        !          2208:                break;
        !          2209:        }
        !          2210:        if (n<= 0) n = NUNDO;
        !          2211:        return(n);
        !          2212: }
        !          2213: 
        !          2214: unadd()
        !          2215: {
        !          2216: /* Keywords: undo stacking */
        !          2217:        
        !          2218:        undostack[undop++] = ((long) curln) * MAXEL + column;
        !          2219: }
        !          2220: 
        !          2221: unins(stline,stcol)
        !          2222: 
        !          2223: /* Keywords: undo insertion stacking */
        !          2224: 
        !          2225: {
        !          2226:        long n;
        !          2227:        if (undop >= NUNDO) {
        !          2228:                undop = 0;
        !          2229:                unseg++;
        !          2230:        }
        !          2231:        n = ((long) stline) * MAXEL + stcol;
        !          2232:        undostack[undop++] = UNINS+ (n<<UNDSHIFT);
        !          2233:        unadd();
        !          2234: }
        !          2235: 
        !          2236: undel()
        !          2237: 
        !          2238: /* Keywords: undo deletion stacking */
        !          2239: 
        !          2240: {
        !          2241:        if (undop >= NUNDO) {
        !          2242:                undop = 0;
        !          2243:                unseg++;
        !          2244:        }
        !          2245:        undostack[undop++] = UNDEL+ (kend<<UNDSHIFT);
        !          2246:        unadd();
        !          2247: }
        !          2248: 
        !          2249: unstart()
        !          2250: {
        !          2251:        return (undop+unseg*NUNDO);
        !          2252: }
        !          2253: unend(unp)
        !          2254: register int unp;
        !          2255: {
        !          2256:        int untype;
        !          2257:        
        !          2258:        unp = (undop+unseg*NUNDO)-unp;
        !          2259:        if (unp >= NUNDO/2) {
        !          2260:                untype= UNBAD;
        !          2261:                unp = NUNDO/2-2;
        !          2262:        } else untype = UNMUL;
        !          2263:        unp = unp / 2;
        !          2264:        if (unp == 1) return;           /* No point in storing extra indirection */
        !          2265:        if (undop >= NUNDO) undop = 0;
        !          2266:        undostack[undop++] = untype + (unp<<UNDSHIFT);
        !          2267:        unadd();
        !          2268: }
        !          2269: 
        !          2270: undo(arg)
        !          2271: 
        !          2272: /* Keywords: commands undo */
        !          2273: 
        !          2274: {
        !          2275:        int undp;
        !          2276:        int unp;
        !          2277:        
        !          2278:        unp = unstart();                        /* Set up for undoing undo */
        !          2279:        undp = undop;
        !          2280:        while (arg--) {
        !          2281: /* Only the last undo really undoes anything */
        !          2282:                
        !          2283:                undp = undoit(undp,(arg == 0));
        !          2284:        }
        !          2285:        unend(unp);
        !          2286: }
        !          2287: unpop(n)
        !          2288: {
        !          2289:        undop -= 2*n;
        !          2290:        if (undop < 0) undop += NUNDO;
        !          2291: }

unix.superglobalmegacorp.com

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