Annotation of coherent/g/usr/bin/me/buffer.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Buffer management.
        !             3:  * Some of the functions are internal and some are actually attached to user
        !             4:  * keys.  Like everyone else, they set hints for the display system.
        !             5:  */
        !             6: #include       <stdio.h>
        !             7: #include       "ed.h"
        !             8: 
        !             9: /*
        !            10:  * Attach a buffer to a window.  The values of dot and mark come from the buffer
        !            11:  * if the use count is 0. Otherwise, they come from some other window.
        !            12:  */
        !            13: usebuffer(f, n)
        !            14: {
        !            15:        register BUFFER *bp;
        !            16:        register WINDOW *wp;
        !            17:        register int    s;
        !            18:        uchar           bufn[NBUFN];
        !            19: 
        !            20:        if ((s=mlreply("Use buffer: ", bufn, NBUFN)) != TRUE)
        !            21:                return (s);
        !            22: #if    GEM
        !            23:        fixname(bufn);
        !            24: #endif
        !            25:        if ((bp=bfind(bufn, TRUE, 0)) == NULL)
        !            26:                return (FALSE);
        !            27:        if (--curbp->b_nwnd == 0) {             /* Last use.            */
        !            28:                curbp->b_dotp  = curwp->w_dotp;
        !            29:                curbp->b_doto  = curwp->w_doto;
        !            30:                curbp->b_markp = curwp->w_markp;
        !            31:                curbp->b_marko = curwp->w_marko;
        !            32:        }
        !            33:        curbp = bp;                             /* Switch.              */
        !            34:        curwp->w_bufp  = bp;
        !            35:        curwp->w_linep = bp->b_linep;           /* For macros, ignored. */
        !            36:        curwp->w_flag |= WFMODE|WFFORCE|WFHARD; /* Quite nasty.         */
        !            37:        if (bp->b_nwnd++ == 0) {                /* First use.           */
        !            38:                curwp->w_dotp  = bp->b_dotp;
        !            39:                curwp->w_doto  = bp->b_doto;
        !            40:                curwp->w_markp = bp->b_markp;
        !            41:                curwp->w_marko = bp->b_marko;
        !            42:                return (TRUE);
        !            43:        }
        !            44:        wp = wheadp;                            /* Look for old.        */
        !            45:        while (wp != NULL) {
        !            46:                if (wp!=curwp && wp->w_bufp==bp) {
        !            47:                        curwp->w_dotp  = wp->w_dotp;
        !            48:                        curwp->w_doto  = wp->w_doto;
        !            49:                        curwp->w_markp = wp->w_markp;
        !            50:                        curwp->w_marko = wp->w_marko;
        !            51:                        break;
        !            52:                }
        !            53:                wp = wp->w_wndp;
        !            54:        }
        !            55:        return (TRUE);
        !            56: }
        !            57: 
        !            58: /*
        !            59:  * Dispose of a buffer, by name.
        !            60:  * Ask for the name. Look it up (don't get too upset if it isn't there at
        !            61:  * all!).  Get quite upset if the buffer is the current buffer.  If it is
        !            62:  * displayed, make sure the user wants it gone, and if (s)he does, delete
        !            63:  * the windows associated with it as well.
        !            64:  * Clear the buffer (ask if the buffer has been changed). Then free the header
        !            65:  * line and the buffer header. Bound to "C-X K".
        !            66:  */
        !            67: killbuffer(f, n)
        !            68: {
        !            69:        register BUFFER *bp;
        !            70:        register BUFFER *bp1;
        !            71:        register BUFFER *bp2;
        !            72:        register int    s;
        !            73:        uchar           bufn[NBUFN];
        !            74: 
        !            75:        if ((s=mlreply("Kill buffer: ", bufn, NBUFN)) != TRUE)
        !            76:                return (s);
        !            77: #if    GEM
        !            78:        fixname(bufn);
        !            79: #endif
        !            80:        if ((bp=bfind(bufn, FALSE, 0)) == NULL) /* Easy if unknown.     */
        !            81:                return (TRUE);
        !            82:        if (bp->b_nwnd != 0) {                  /* If on screen.        */
        !            83:                if (curbp == bp) {
        !            84:                        mlwrite("Buffer is current buffer");
        !            85:                        return (FALSE);
        !            86:                } else {
        !            87:                        if ((s = mlyesno("Buffer is displayed: Really kill"))
        !            88:                                        != TRUE)
        !            89:                                return (FALSE);
        !            90:                }
        !            91:        }
        !            92:        if ((s=bclear(bp)) != TRUE)             /* Blow text away.      */
        !            93:                return (s);
        !            94:        while (bp->b_nwnd != 0)                 /* Blow windows away.   */
        !            95:                zapbwind(bp);
        !            96:        free((char *) bp->b_linep);             /* Release header line. */
        !            97:        bp1 = NULL;                             /* Find the header.     */
        !            98:        bp2 = bheadp;
        !            99:        while (bp2 != bp) {
        !           100:                bp1 = bp2;
        !           101:                bp2 = bp2->b_bufp;
        !           102:        }
        !           103:        bp2 = bp2->b_bufp;                      /* Next one in chain.   */
        !           104:        if (bp1 == NULL)                        /* Unlink it.           */
        !           105:                bheadp = bp2;
        !           106:        else
        !           107:                bp1->b_bufp = bp2;
        !           108:        free((char *) bp);                      /* Release buffer block */
        !           109:        return (TRUE);
        !           110: }
        !           111: 
        !           112: /*
        !           113:  * List all of the active buffers. First update the special buffer that
        !           114:  * holds the list. Next make sure at least 1 window is displaying the
        !           115:  * buffer list, splitting the screen if this is what it takes.
        !           116:  * Lastly, repaint all of the windows that are displaying the list.
        !           117:  * Bound to "C-X C-B".
        !           118:  */
        !           119: listbuffers(f, n)
        !           120: {
        !           121:        register WINDOW *wp;
        !           122:        register BUFFER *bp;
        !           123:        register int    s;
        !           124: 
        !           125:        if ((s=makelist()) != TRUE)
        !           126:                return (s);
        !           127:        if (blistp->b_nwnd == 0) {              /* Not on screen yet.   */
        !           128:                if ((wp=wpopup()) == NULL)
        !           129:                        return (FALSE);
        !           130:                bp = wp->w_bufp;
        !           131:                if (--bp->b_nwnd == 0) {
        !           132:                        bp->b_dotp  = wp->w_dotp;
        !           133:                        bp->b_doto  = wp->w_doto;
        !           134:                        bp->b_markp = wp->w_markp;
        !           135:                        bp->b_marko = wp->w_marko;
        !           136:                }
        !           137:                wp->w_bufp  = blistp;
        !           138:                ++blistp->b_nwnd;
        !           139:        }
        !           140:        wp = wheadp;
        !           141:        while (wp != NULL) {
        !           142:                if (wp->w_bufp == blistp) {
        !           143:                        wp->w_linep = lforw(blistp->b_linep);
        !           144:                        wp->w_dotp  = lforw(blistp->b_linep);
        !           145:                        wp->w_doto  = 0;
        !           146:                        wp->w_markp = NULL;
        !           147:                        wp->w_marko = 0;
        !           148:                        wp->w_flag |= WFMODE|WFHARD;
        !           149:                }
        !           150:                wp = wp->w_wndp;
        !           151:        }
        !           152:        return (TRUE);
        !           153: }
        !           154: 
        !           155: /*
        !           156:  * This routine rebuilds the text in the special secret buffer that holds
        !           157:  * the buffer list. It is called by the list buffers command. Return TRUE
        !           158:  * if everything works. Return FALSE if there is an error
        !           159:  * (if there is no memory).
        !           160:  */
        !           161: makelist()
        !           162: {
        !           163:        register uchar  *cp1;
        !           164:        register uchar  *cp2;
        !           165:        register BUFFER *bp;
        !           166:        register LINE   *lp;
        !           167:        register long   nlines;
        !           168:        register long   nbytes;
        !           169:        register int    c;
        !           170:        uchar           b[6+1];
        !           171:        uchar           line[128];
        !           172: 
        !           173:        blistp->b_flag &= ~BFCHG;               /* Don't complain!      */
        !           174:        if ((c=bclear(blistp)) != TRUE)         /* Blow old text away   */
        !           175:                return (c);
        !           176:        strcpy(blistp->b_fname, "");
        !           177:        if (addline(blistp, "C   Size  Lines Buffer           File") == FALSE
        !           178:        ||  addline(blistp,"-   ----  ----- ------           ----") == FALSE)
        !           179:                return (FALSE);
        !           180:        bp = bheadp;                            /* For all buffers      */
        !           181:        while (bp != NULL) {
        !           182:                if ((bp->b_flag&BFTEMP) != 0) { /* Skip magic ones.     */
        !           183:                        bp = bp->b_bufp;
        !           184:                        continue;
        !           185:                }
        !           186:                cp1 = &line[0];                 /* Start at left edge   */
        !           187:                if ((bp->b_flag&BFCHG) != 0)    /* "*" if changed       */
        !           188:                        *cp1++ = '*';
        !           189:                else
        !           190:                        *cp1++ = ' ';
        !           191:                *cp1++ = ' ';                   /* Gap.                 */
        !           192:                nbytes = 0;                     /* Count bytes in buf.  */
        !           193:                nlines = 0;                     /* Count lines in buf.  */
        !           194:                lp = lforw(bp->b_linep);
        !           195:                while (lp != bp->b_linep) {
        !           196:                        nlines++;
        !           197:                        nbytes += llength(lp)+1;
        !           198:                        lp = lforw(lp);
        !           199:                }
        !           200:                ltoa(b, 6, nbytes);             /* 6 digit buffer size. */
        !           201:                cp2 = &b[0];
        !           202:                while ((c = *cp2++) != 0)
        !           203:                        *cp1++ = c;
        !           204:                *cp1++ = ' ';                   /* Gap.                 */
        !           205:                ltoa(b, 6, nlines);             /* 6 digit # of lines   */
        !           206:                cp2 = &b[0];
        !           207:                while ((c = *cp2++) != 0)
        !           208:                        *cp1++ = c;
        !           209:                *cp1++ = ' ';                   /* Gap.                 */
        !           210:                cp2 = &bp->b_bname[0];          /* Buffer name          */
        !           211:                while ((c = *cp2++) != 0)
        !           212:                        *cp1++ = c;
        !           213:                cp2 = &bp->b_fname[0];          /* File name            */
        !           214:                if (*cp2 != 0) {
        !           215:                        while (cp1 < &line[1+1+6+1+6+1+NBUFN+1])
        !           216:                                *cp1++ = ' ';           
        !           217:                        while ((c = *cp2++) != 0) {
        !           218:                                if (cp1 < &line[128-1])
        !           219:                                        *cp1++ = c;
        !           220:                        }
        !           221:                }
        !           222:                *cp1 = 0;                       /* Add to the buffer.   */
        !           223:                if (addline(blistp,line) == FALSE)
        !           224:                        return (FALSE);
        !           225:                bp = bp->b_bufp;
        !           226:        }
        !           227:        return (TRUE);                          /* All done             */
        !           228: }
        !           229: 
        !           230: ltoa(buf, width, num)
        !           231: register uchar buf[];
        !           232: register int   width;
        !           233: register long  num;
        !           234: {
        !           235:        buf[width] = 0;                         /* End of string.       */
        !           236:        while (num >= 10) {                     /* Conditional digits.  */
        !           237:                buf[--width] = (num%10) + '0';
        !           238:                num /= 10;
        !           239:        }
        !           240:        buf[--width] = num + '0';               /* Always 1 digit.      */
        !           241:        while (width != 0)                      /* Pad with blanks.     */
        !           242:                buf[--width] = ' ';
        !           243: }
        !           244: 
        !           245: /*
        !           246:  * The argument "text" points to a string. Append this line to the buffer
        !           247:  * specified. Handcraft the EOL on the end. Return TRUE if it worked and
        !           248:  * FALSE if you ran out of room.
        !           249:  */
        !           250: addline(bp, text)
        !           251: register BUFFER *bp;
        !           252: uchar  *text;
        !           253: {
        !           254:        register LINE   *lp;
        !           255:        register int    i;
        !           256:        register int    ntext;
        !           257: 
        !           258:        ntext = strlen(text);
        !           259:        if ((lp=lalloc(ntext)) == NULL)
        !           260:                return (FALSE);
        !           261:        for (i=0; i<ntext; ++i)
        !           262:                lputc(lp, i, text[i]);
        !           263:        lforw(lback(bp->b_linep)) = lp;         /* Hook onto the end    */
        !           264:        lp->l_bp = bp->b_linep->l_bp;
        !           265:        bp->b_linep->l_bp = lp;
        !           266:        lforw(lp) = bp->b_linep;
        !           267:        if (bp->b_dotp == bp->b_linep)          /* If "." is at the end */
        !           268:                bp->b_dotp = lp;                /* move it to new line  */
        !           269:        return (TRUE);
        !           270: }
        !           271: 
        !           272: /*
        !           273:  * Look through the list of buffers. Return TRUE if there are any changed
        !           274:  * buffers. Buffers that hold magic internal stuff are not considered;
        !           275:  * who cares if the list of buffer names is hacked.
        !           276:  * Return FALSE if no buffers have been changed.
        !           277:  */
        !           278: anycb()
        !           279: {
        !           280:        register BUFFER *bp;
        !           281: 
        !           282:        bp = bheadp;
        !           283:        while (bp != NULL) {
        !           284:                if ((bp->b_flag&(BFTEMP|BFNOWRT|BFERROR))==0
        !           285:                                && (bp->b_flag&BFCHG)!=0)
        !           286:                        return (TRUE);
        !           287:                bp = bp->b_bufp;
        !           288:        }
        !           289:        return (FALSE);
        !           290: }
        !           291: 
        !           292: /*
        !           293:  * Find a buffer, by name. Return a pointer to the BUFFER structure
        !           294:  * associated with it. If the named buffer is found, but is a TEMP buffer
        !           295:  * (like the buffer list) conplain. If the buffer is not found and the "cflag"
        !           296:  * is TRUE, create it. The "bflag" is the settings for the flags in in buffer.
        !           297:  */
        !           298: BUFFER *bfind(bname, cflag, bflag)
        !           299: register uchar *bname;
        !           300: {
        !           301:        register BUFFER *bp;
        !           302:        register LINE   *lp;
        !           303: 
        !           304:        bp = bheadp;
        !           305:        while (bp != NULL) {
        !           306:                if (strcmp(bname, bp->b_bname) == 0) {
        !           307:                        if ((bp->b_flag&BFTEMP) != 0) {
        !           308:                                mlwrite("Cannot select builtin buffer");
        !           309:                                return (NULL);
        !           310:                        }
        !           311:                        return (bp);
        !           312:                }
        !           313:                bp = bp->b_bufp;
        !           314:        }
        !           315:        if (cflag != FALSE) {
        !           316:                if ((bp=(BUFFER *)malloc(sizeof(BUFFER))) == NULL)
        !           317:                        return (NULL);
        !           318:                if ((lp=lalloc(0)) == NULL) {
        !           319:                        free((char *) bp);
        !           320:                        return (NULL);
        !           321:                }
        !           322:                bp->b_bufp  = bheadp;
        !           323:                bheadp = bp;
        !           324:                bp->b_dotp  = lp;
        !           325:                bp->b_doto  = 0;
        !           326:                bp->b_markp = NULL;
        !           327:                bp->b_marko = 0;
        !           328:                bp->b_flag  = bflag;
        !           329:                bp->b_nwnd  = 0;
        !           330:                bp->b_linep = lp;
        !           331:                strcpy(bp->b_fname, "");
        !           332:                strcpy(bp->b_bname, bname);
        !           333:                lforw(lp) = lp;
        !           334:                lp->l_bp = lp;
        !           335:        }
        !           336:        return (bp);
        !           337: }
        !           338: 
        !           339: /*
        !           340:  * This routine blows away all of the text in a buffer. If the buffer is
        !           341:  * marked as changed then we ask if it is ok to blow it away; this is
        !           342:  * to save the user the grief of losing text. The window chain is nearly
        !           343:  * always wrong if this gets called; the caller must arrange for the updates
        !           344:  * that are required. Return TRUE if everything looks good.
        !           345:  */
        !           346: bclear(bp)
        !           347: register BUFFER        *bp;
        !           348: {
        !           349:        register LINE   *lp;
        !           350:        register int    s;
        !           351:        
        !           352:        if ((bp->b_flag&BFTEMP) == 0            /* Not scratch buffer.  */
        !           353:        && (bp->b_flag&BFCHG) != 0              /* Something changed    */
        !           354:        && (s=mlyesno("Discard changes")) != TRUE)
        !           355:                return (s);
        !           356:        bp->b_flag  &= ~BFCHG;                  /* Not changed          */
        !           357:        while ((lp=lforw(bp->b_linep)) != bp->b_linep)
        !           358:                lfree(lp);
        !           359:        bp->b_dotp  = bp->b_linep;              /* Fix "."              */
        !           360:        bp->b_doto  = 0;
        !           361:        bp->b_markp = NULL;                     /* Invalidate "mark"    */
        !           362:        bp->b_marko = 0;
        !           363:        return (TRUE);
        !           364: }
        !           365: 
        !           366: #if    LIBHELP
        !           367: /*
        !           368:  * Put up a help window with the text pointed to by txt.
        !           369:  */
        !           370: helpwindow(tag)
        !           371: uchar *tag;
        !           372: {
        !           373:        register WINDOW *wp;
        !           374:        register BUFFER *bp;
        !           375:        register int    s;
        !           376: 
        !           377:        if ((s=makehelp(tag)) != TRUE) {
        !           378:                while (helpbp->b_nwnd != 0)     /* If on screen         */
        !           379:                        zaphelp(0, 0);          /* Delete windows       */
        !           380:                return (s);
        !           381:        }
        !           382:        if (helpbp->b_nwnd == 0) {              /* Not on screen yet.   */
        !           383:                if ((wp=wpopup(helpbp)) == NULL)
        !           384:                        return (FALSE);
        !           385:                bp = wp->w_bufp;
        !           386:                if (--bp->b_nwnd == 0) {
        !           387:                        bp->b_dotp  = wp->w_dotp;
        !           388:                        bp->b_doto  = wp->w_doto;
        !           389:                        bp->b_markp = wp->w_markp;
        !           390:                        bp->b_marko = wp->w_marko;
        !           391:                }
        !           392:                wp->w_bufp  = helpbp;
        !           393:                ++helpbp->b_nwnd;
        !           394:        }
        !           395:        wp = wheadp;
        !           396:        while (wp != NULL) {
        !           397:                if (wp->w_bufp == helpbp) {
        !           398:                        wp->w_linep = lforw(helpbp->b_linep);
        !           399:                        wp->w_dotp  = lforw(helpbp->b_linep);
        !           400:                        wp->w_doto  = 0;
        !           401:                        wp->w_markp = NULL;
        !           402:                        wp->w_marko = 0;
        !           403:                        wp->w_flag |= WFMODE|WFHARD;
        !           404:                }
        !           405:                wp = wp->w_wndp;
        !           406:        }
        !           407:        return (TRUE);
        !           408: }
        !           409: 
        !           410: /*
        !           411:  * Service routine for help...
        !           412:  */
        !           413: addhelp(str)
        !           414: uchar *str;
        !           415: {
        !           416:        addline(helpbp, str);
        !           417: }
        !           418: 
        !           419: /*
        !           420:  * This routine rebuilds the text in the special secret buffer that holds
        !           421:  * the help.  It is called by the help command.  Return TRUE if
        !           422:  * everything works.  Return FALSE if there is an error (if there is no memory
        !           423:  * or no help for the topic or file not found.)
        !           424:  */
        !           425: makehelp(tag)
        !           426: uchar *tag;
        !           427: {
        !           428:        extern uchar *helpfile;
        !           429:        register int c;
        !           430: 
        !           431:        helpbp->b_flag &= ~BFCHG;               /* Don't complain!      */
        !           432:        if ((c=bclear(helpbp)) != TRUE)         /* Blow old text away   */
        !           433:                return (c);
        !           434:        strcpy(helpbp->b_fname, tag);
        !           435: 
        !           436:        if ((c = help(tag, addhelp)) < 0)
        !           437:                mlwrite("[Can't open help file %s]", helpfile);
        !           438:        else if (c > 0)
        !           439:                mlwrite("[No help available for topic \"%s\"]", tag);
        !           440: 
        !           441:        return (c == 0);                /* All done             */
        !           442: }
        !           443: 
        !           444: /*
        !           445:  * Put up a help window with an index of matching topics
        !           446:  */
        !           447: topicwindow(tag)
        !           448: uchar *tag;
        !           449: {
        !           450:        register WINDOW *wp;
        !           451:        register BUFFER *bp;
        !           452:        register int    s;
        !           453: 
        !           454:        if ((s=makeindex(tag)) != TRUE) {
        !           455:                while (helpbp->b_nwnd != 0)     /* If on screen         */
        !           456:                        zaphelp(0, 0);          /* Delete windows       */
        !           457:                return (s);
        !           458:        }
        !           459:        if (helpbp->b_nwnd == 0) {              /* Not on screen yet.   */
        !           460:                if ((wp=wpopup(helpbp)) == NULL)
        !           461:                        return (FALSE);
        !           462:                bp = wp->w_bufp;
        !           463:                if (--bp->b_nwnd == 0) {
        !           464:                        bp->b_dotp  = wp->w_dotp;
        !           465:                        bp->b_doto  = wp->w_doto;
        !           466:                        bp->b_markp = wp->w_markp;
        !           467:                        bp->b_marko = wp->w_marko;
        !           468:                }
        !           469:                wp->w_bufp  = helpbp;
        !           470:                ++helpbp->b_nwnd;
        !           471:        }
        !           472:        wp = wheadp;
        !           473:        while (wp != NULL) {
        !           474:                if (wp->w_bufp == helpbp) {
        !           475:                        wp->w_linep = lforw(helpbp->b_linep);
        !           476:                        wp->w_dotp  = lforw(helpbp->b_linep);
        !           477:                        wp->w_doto  = 0;
        !           478:                        wp->w_markp = NULL;
        !           479:                        wp->w_marko = 0;
        !           480:                        wp->w_flag |= WFMODE|WFHARD;
        !           481:                }
        !           482:                wp = wp->w_wndp;
        !           483:        }
        !           484:        return (TRUE);
        !           485: }
        !           486: 
        !           487: /*
        !           488:  * This routine rebuilds the text in the special secret buffer that holds
        !           489:  * the help.  It is called by the help command.  Return TRUE if
        !           490:  * everything works.  Return FALSE if there is an error (if there is no memory
        !           491:  * or no help for the topic or file not found.)
        !           492:  */
        !           493: makeindex(tag)
        !           494: uchar *tag;
        !           495: {
        !           496:        extern uchar *helpfile;
        !           497:        register int c;
        !           498: 
        !           499:        helpbp->b_flag &= ~BFCHG;               /* Don't complain!      */
        !           500:        if ((c=bclear(helpbp)) != TRUE)         /* Blow old text away   */
        !           501:                return (c);
        !           502:        strcpy(helpbp->b_fname, "index for ");
        !           503:        strcat(helpbp->b_fname, tag);
        !           504: 
        !           505:        if ((c = indexhelp(tag, addhelp)) < 0)
        !           506:                mlwrite("[Can't open help file %s]", helpfile);
        !           507:        else if (c > 0)
        !           508:                mlwrite("[No entries matching \"%s\"]", tag);
        !           509: 
        !           510:        return (c == 0);                /* All done             */
        !           511: }
        !           512: #endif

unix.superglobalmegacorp.com

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