Annotation of coherent/g/usr/bin/me/buffer.c, revision 1.1.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.