Annotation of researchv9/X11/src/X.V11R1/clients/xedit/ps.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char rcs_id[] = "$Header: ps.c,v 1.8 87/09/11 08:22:10 toddb Exp $";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  *                       COPYRIGHT 1987
        !             7:  *                DIGITAL EQUIPMENT CORPORATION
        !             8:  *                    MAYNARD, MASSACHUSETTS
        !             9:  *                     ALL RIGHTS RESERVED.
        !            10:  *
        !            11:  * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
        !            12:  * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
        !            13:  * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
        !            14:  * ANY PURPOSE.  IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
        !            15:  *
        !            16:  * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS,
        !            17:  * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT
        !            18:  * SET FORTH ABOVE.
        !            19:  *
        !            20:  *
        !            21:  * Permission to use, copy, modify, and distribute this software and its
        !            22:  * documentation for any purpose and without fee is hereby granted, provided
        !            23:  * that the above copyright notice appear in all copies and that both that
        !            24:  * copyright notice and this permission notice appear in supporting documentation,
        !            25:  * and that the name of Digital Equipment Corporation not be used in advertising
        !            26:  * or publicity pertaining to distribution of the software without specific, 
        !            27:  * written prior permission.
        !            28:  */
        !            29: 
        !            30: /* J. Gringorten */
        !            31: 
        !            32: #include <sys/types.h>
        !            33: #include <sys/stat.h>
        !            34: #include <sys/file.h>
        !            35: #include <ctype.h>
        !            36: #include "xedit.h"
        !            37: 
        !            38: XtTextPosition PSgetLastPos();
        !            39: 
        !            40: #define PieceSize(qp)  (qp->endPos - qp->begPos)
        !            41: 
        !            42: typedef struct _qp{
        !            43:     struct _qp *flink, *blink;
        !            44:     XtTextSource **src;
        !            45:     int begPos, endPos;
        !            46: } PieceQueueElement;
        !            47: 
        !            48: typedef struct _cb{
        !            49:     struct _cb *flink, *blink;
        !            50:     PieceQueueElement *retiredQHead, *retiredQTail;
        !            51:     PieceQueueElement *addedPtrFirst, *addedPtrLast, *where, *Rptr, *Lptr;
        !            52:     XtTextPosition Rfix, Lfix, deletedPos;
        !            53: }ChangeBlock;
        !            54: 
        !            55: typedef struct {
        !            56:     XtTextSource *ro, *ao;
        !            57:     PieceQueueElement *PTQHead, *PTQTail, *lastAddedPiece, *LocatedPiece;
        !            58:     int endPos;
        !            59:     XtTextPosition aoPos, lastReplaceEndPos, LocatedPiecePos;
        !            60:     ChangeBlock *CQHead, *CQTail, *LastUndid;
        !            61: } PSContext;
        !            62: 
        !            63: static PieceQueueElement *getQp()
        !            64: {
        !            65:     return((PieceQueueElement *)calloc(sizeof(PieceQueueElement), 1));
        !            66: }
        !            67: 
        !            68: static PieceQueueElement *remqueue(head, tail, this)
        !            69:   PieceQueueElement **head, **tail, *this;
        !            70: {
        !            71:   PieceQueueElement *prev = this->blink;
        !            72:   PieceQueueElement *next = this->flink;
        !            73:        if (this == *head){
        !            74:          if(this == *tail) {
        !            75:            *head = 0;
        !            76:            *tail = 0;
        !            77:          } else {
        !            78:            *head = next;
        !            79:            next->blink = 0;
        !            80:          }
        !            81:        } else {
        !            82:          if(this == *tail){
        !            83:            *tail = prev;
        !            84:            prev->flink = 0;   
        !            85:          } else {
        !            86:            prev->flink = next;
        !            87:            next->blink = prev;
        !            88:          }
        !            89:        }
        !            90:        this->blink = 0;
        !            91:        this->flink = 0;
        !            92:        return (this);
        !            93: }
        !            94: 
        !            95: static freeQp(this)
        !            96:   PieceQueueElement* this;
        !            97: {
        !            98:     free((int*)this);
        !            99: }
        !           100: 
        !           101: /*
        !           102:  * insert 'new' queue element on 'where'
        !           103:  */
        !           104: static PieceQueueElement *insert(head, tail, new, where)
        !           105:   PieceQueueElement **head, **tail, *new, *where;
        !           106: {
        !           107:        if(!where){
        !           108:            new->flink = *head;
        !           109:            *head = new;
        !           110:        } else {
        !           111:            new->flink = where->flink;
        !           112:            new->blink = where;
        !           113:            where->flink = new;
        !           114:        }
        !           115:        if(new->flink == 0)
        !           116:            *tail = new;
        !           117:        else
        !           118:            new->flink->blink = new;
        !           119:        return(new);
        !           120: }
        !           121: 
        !           122: retire(ctx, qp)
        !           123:   PSContext *ctx;
        !           124:   PieceQueueElement *qp;
        !           125: {
        !           126:        remqueue(&ctx->PTQHead, &ctx->PTQTail, qp);
        !           127:        insert(&(ctx->CQTail->retiredQHead), &(ctx->CQTail->retiredQTail),
        !           128:                qp, ctx->CQTail->retiredQTail);
        !           129:        ctx->endPos -= (PieceSize(qp));
        !           130: }
        !           131: static total;
        !           132: static PieceQueueElement *locate(ctx, skew, pos)
        !           133:   XtTextPosition pos;
        !           134:   int *skew;
        !           135:   PSContext *ctx;
        !           136: {
        !           137: /* referential locality  optimizations go here */
        !           138:   XtTextPosition t;
        !           139:   PieceQueueElement *qp;
        !           140: /*printf("locate %d  %d\n", total++, pos); */
        !           141:     if ((pos == ctx->endPos) && (ctx->PTQTail)){
        !           142:        qp = ctx->PTQTail;
        !           143:        *skew = PieceSize(qp);
        !           144:         ctx->LocatedPiece = qp;
        !           145:         ctx->LocatedPiecePos = pos - *skew;
        !           146:        return qp;
        !           147:        }
        !           148:     if(        (ctx->LocatedPiece) && 
        !           149:        (qp = ctx->LocatedPiece->flink) &&
        !           150:        (pos >= (t = ctx->LocatedPiecePos + PieceSize(ctx->LocatedPiece))) && 
        !           151:        (pos < PieceSize(qp) + t)){
        !           152:            /* do nothing more! */
        !           153:     } else {
        !           154:          t = 0;
        !           155:         for(qp = ctx->PTQHead; qp; qp = qp->flink){
        !           156:            if (t + PieceSize(qp) > pos)
        !           157:                break;
        !           158:            t += (PieceSize(qp));
        !           159:         }
        !           160:     }
        !           161:     *skew = pos - t;
        !           162:     ctx->LocatedPiece = qp; 
        !           163:     ctx->LocatedPiecePos = t;
        !           164:     return qp;
        !           165: }
        !           166: 
        !           167: /*
        !           168:  * split begin and end pieces and delete if necessary unused pieces. 
        !           169:  * return queue pointer of position to be inserted in back of.
        !           170:  */
        !           171: PieceQueueElement *deleteRange(ctx, startPos, endPos)
        !           172:   PSContext *ctx;
        !           173:   XtTextPosition startPos, endPos;
        !           174: {
        !           175:   PieceQueueElement *qp, *beg, *end, *victim;
        !           176:   XtTextPosition t, skew, range = endPos - startPos;
        !           177:   ChangeBlock *cb = ctx->CQTail;
        !           178:     if(endPos == 0)
        !           179:        return 0;
        !           180:     qp = locate(ctx, &skew, startPos);
        !           181:     t = startPos - skew;
        !           182:     if (!skew){
        !           183:        if( t + PieceSize(qp) == endPos){
        !           184:            /* desired range is contained in the one piece exactly */
        !           185:            beg = qp->blink;
        !           186:            retire(ctx, qp);                
        !           187:            return beg;
        !           188:        } else if( t + PieceSize(qp) > endPos){
        !           189:            /* desired range is front portion of one piece */
        !           190:            beg = qp->blink;
        !           191:            cb->Rptr = qp;
        !           192:            cb->Rfix = qp->begPos;
        !           193:            qp->begPos += range;          
        !           194:            ctx->endPos -= range;
        !           195:            return beg;
        !           196:        }
        !           197:     } else { 
        !           198:        if( t + PieceSize(qp) == endPos){
        !           199:            /* range is the back portion of one piece */
        !           200:            cb->Lptr = qp;
        !           201:            cb->Lfix = qp->endPos;
        !           202:            qp->endPos -= range;
        !           203:            ctx->endPos -= range;
        !           204:            return qp;
        !           205:        }
        !           206:     }
        !           207:     if(skew){
        !           208:        if( t + PieceSize(qp) < endPos){
        !           209:            /* deleted range extends off this piece, so lop off end of it */
        !           210:            t += PieceSize(qp);
        !           211:            beg = qp->flink;
        !           212:            cb->Lptr = qp;
        !           213:            cb->Lfix = qp->endPos;
        !           214:            ctx->endPos -= PieceSize(qp) - skew;
        !           215:            qp->endPos = qp->begPos + skew;
        !           216:        } else {
        !           217:            /*      enter a new piece by splitting the first piece */
        !           218:            beg = insert(&ctx->PTQHead, &ctx->PTQTail, getQp(), qp);
        !           219:            beg->endPos = qp->endPos;
        !           220:            cb->Lfix = qp->endPos;
        !           221:            cb->Lptr = qp;
        !           222:            qp->endPos = qp->begPos + (startPos - t);
        !           223:            beg->begPos = qp->endPos;
        !           224:            beg->src = qp->src;
        !           225:            cb->addedPtrFirst = cb->addedPtrLast = beg;
        !           226:             if (!range)
        !           227:                return (qp);
        !           228:             t += PieceSize(qp); /* bump 't' up to beg*/
        !           229:             if( t + PieceSize(beg) > endPos){
        !           230:                /* range size < sizof(beg) */
        !           231:                 ctx->endPos -= (endPos - t);
        !           232:                 beg->begPos += (endPos - t);
        !           233:                return qp;
        !           234:            }
        !           235:        }
        !           236:     } else 
        !           237:        beg = qp;
        !           238: /* locate queue entry that contains the last position, deleting others on the way*/
        !           239:     victim = 0;
        !           240:     for(qp = beg; qp;  qp = qp->flink){
        !           241:        if (victim){
        !           242:            retire(ctx, victim);
        !           243:            victim = 0;
        !           244:        }
        !           245:        if( t + (PieceSize(qp)) >= endPos) 
        !           246:            break;
        !           247:        t  += (PieceSize(qp));
        !           248:        victim = qp;
        !           249:     }
        !           250:     if( t + (PieceSize(qp)) == endPos){
        !           251:        end = qp->blink;
        !           252:        retire(ctx, qp);
        !           253:        return (end);
        !           254:     }
        !           255: /* implied split and delete first half of last piece */
        !           256:     cb->Rfix = qp->begPos; 
        !           257:     cb->Rptr = qp;
        !           258:     ctx->endPos -= (endPos - t);
        !           259:     qp->begPos += (endPos - t);
        !           260:     return (qp->blink);
        !           261: }
        !           262: 
        !           263: 
        !           264: static PSContext *ctx_public;  /* debug hack **************************XXX */
        !           265: 
        !           266: DoQ()
        !           267: {
        !           268:   XtTextBlock t, *text;
        !           269:   int i;
        !           270:   char c;
        !           271:   int end, count;
        !           272:     PieceQueueElement *qp;
        !           273:     PSContext *ctx = ctx_public;
        !           274:     text = &t;
        !           275:     text->length = 1;
        !           276:     text->firstPos = 0;
        !           277:     count = 0;
        !           278:     for(qp = ctx->PTQHead; qp; qp = qp->flink){
        !           279:         printf("%d\t%d\t%s\t", qp->begPos, qp->endPos, (*qp->src == ctx-> ao) ?
        !           280:         "ao":"ro", *qp->src);
        !           281:         end = (PieceSize(qp)>20)?(qp->begPos)+20:qp->endPos;
        !           282:         for(i=qp->begPos; i<end; i++){
        !           283:            (*(*qp->src)->read)(*qp->src, i, text, 1);
        !           284:            c = text->ptr[0];
        !           285:            if (isprint(c))
        !           286:                putchar(c);
        !           287:            else
        !           288:                printf("/%d/", c);
        !           289:         }
        !           290:     printf("\n");
        !           291:     count++;
        !           292:     }
        !           293:     printf("%d  piece%c\n", count, (count>1)?'s':' ');
        !           294:     if(!fork()) 
        !           295:        abort();
        !           296: }
        !           297: 
        !           298: 
        !           299: #define RightPiece(qp, s2Pos)          \
        !           300: {                                      \
        !           301:     s2Pos += (PieceSize(qp)); \
        !           302:     qp = qp->flink;                    \
        !           303: }
        !           304: 
        !           305: #define LeftPiece(qp, s2Pos)           \
        !           306: {                                      \
        !           307:     qp = qp->blink;                    \
        !           308:     s2Pos -= (PieceSize(qp));  \
        !           309: }
        !           310: static XtTextPosition PSscan (src, pos, sType, dir, count, include)
        !           311:   XtTextSource *src;
        !           312:   XtTextPosition pos;
        !           313:   ScanType sType;
        !           314:   ScanDirection dir;
        !           315:   int count, include;
        !           316: {
        !           317:   int skew, index, ddir,i;
        !           318:   XtTextPosition  s2Pos, rightmost, leftmost;
        !           319:   PSContext *ctx = (PSContext *)src->data;
        !           320:   PieceQueueElement *qp;
        !           321:     index = pos;
        !           322:     if(sType == XtstPositions){
        !           323:         ddir = (dir == XtsdRight) ? 1 : -1;
        !           324:         if (!include && count > 0)
        !           325:             count--;
        !           326:         index = (index + count * ddir);
        !           327:         index = (index < 0) ? 0 : ((index > ctx->endPos) ? ctx->endPos : index);
        !           328:         return index;
        !           329:     }
        !           330:     if(sType == XtstFile){
        !           331:         if(dir == XtsdRight)
        !           332:            return  PSgetLastPos(src);
        !           333:        else
        !           334:            return 0;
        !           335:     }
        !           336:     qp = locate(ctx, &skew, pos);
        !           337:     s2Pos = pos - skew;
        !           338:     if(dir == XtsdRight){
        !           339:        for(i=0; i<count; i++){
        !           340:            if(!qp)
        !           341:                return(ctx->endPos);
        !           342:            if (!scan_right(&s2Pos, &skew, &leftmost, &rightmost, &qp, sType)){
        !           343:                rightmost = leftmost = ctx->endPos;
        !           344:            }
        !           345:        }
        !           346:         return ((include) ? rightmost : leftmost);
        !           347:     } else {
        !           348:        if(!qp)
        !           349:            return 0;
        !           350:        if(!skew){
        !           351:            LeftPiece(qp, s2Pos);
        !           352:                if(!qp)
        !           353:                    return 0;
        !           354:            skew = PieceSize(qp);
        !           355:        }
        !           356:        for(i=0; i<count; i++){
        !           357:            if(!qp)
        !           358:                return(0);
        !           359:            if (!scan_left(&s2Pos, &skew, &leftmost, &rightmost, &qp, sType)){
        !           360:                rightmost = leftmost = 0;
        !           361:            }
        !           362:        }
        !           363:         return ((!include) ? rightmost : leftmost);
        !           364:     }
        !           365: }
        !           366: 
        !           367: scan_right(_s2Pos, _skew, _leftmost, _rightmost, _qp, sType)
        !           368:   XtTextPosition  *_s2Pos;     /* s2 pos of begin this qp         (bi)  */
        !           369:   XtTextPosition  *_skew;      /* offset of actual s2 loc into qp (bi)  */
        !           370:   XtTextPosition  *_rightmost;         /* s2 pos of end of target+1       (ret) */  
        !           371:   XtTextPosition  *_leftmost;          /* s2 pos of begin this qp         (ret) */
        !           372:   PieceQueueElement **_qp;        /* piece to start at.                         */
        !           373:    ScanType sType;
        !           374: {
        !           375:   PieceQueueElement *qp = *_qp;     
        !           376:   XtTextPosition  s2Pos = *_s2Pos;
        !           377:   XtTextPosition  leftmost = *_leftmost;
        !           378:   XtTextPosition  rightmost = *_rightmost;
        !           379:   XtTextPosition  skew = *_skew;       
        !           380:   XtTextPosition  actual, ppos, res;
        !           381:     ppos = qp->begPos + skew;
        !           382:     while(qp){
        !           383:         res = (*(*qp->src)->scan)(*qp->src, ppos, sType, XtsdRight, 1, 0);
        !           384:         if(res < qp->endPos){
        !           385:             break;
        !           386:         }
        !           387:        RightPiece(qp, s2Pos);
        !           388:        if(qp)
        !           389:            ppos = qp->begPos;
        !           390:        else
        !           391:            return(0);
        !           392:     }          
        !           393:     leftmost = s2Pos + (res - qp->begPos);
        !           394:     res = (*(*qp->src)->scan)(*qp->src, ppos, sType, XtsdRight, 1, 1);
        !           395:     if(res < qp->endPos){
        !           396:         rightmost = s2Pos + (res - qp->begPos);
        !           397:        skew = (res - qp->begPos);
        !           398:     } else {
        !           399:         RightPiece(qp, s2Pos);
        !           400:         while(qp){
        !           401:             res = (*(*qp->src)->scan)(*qp->src, qp->begPos, sType, XtsdRight, 1, 0);
        !           402:             if(res != qp->begPos){
        !           403:                 rightmost = s2Pos;
        !           404:                skew = 0;
        !           405:                break;
        !           406:            }
        !           407:            res = (*(*qp->src)->scan)(*qp->src, qp->begPos, sType, XtsdRight, 1, 1);
        !           408:             if(res < qp->endPos){
        !           409:                 rightmost = s2Pos + (res - qp->begPos);
        !           410:                skew = (res - qp->begPos);
        !           411:                break;
        !           412:            }
        !           413:            RightPiece(qp, s2Pos);
        !           414:            rightmost = s2Pos;
        !           415:        }
        !           416:     }
        !           417:     *_s2Pos = s2Pos;
        !           418:     *_skew = skew;
        !           419:     *_leftmost = leftmost;
        !           420:     *_rightmost = rightmost;
        !           421:     *_qp = qp;
        !           422:     return 1;
        !           423: }
        !           424: 
        !           425: 
        !           426: scan_left(_s2Pos, _skew, _leftmost, _rightmost, _qp, sType)
        !           427:   XtTextPosition  *_s2Pos;     /* s2 pos of begin this qp         (bi)  */
        !           428:   XtTextPosition  *_skew;      /* offset of actual s2 loc into qp (bi)  */
        !           429:   XtTextPosition  *_rightmost;         /* s2 pos of end of target+1       (ret) */  
        !           430:   XtTextPosition  *_leftmost;          /* s2 pos of begin this qp         (ret) */
        !           431:   PieceQueueElement **_qp;        /* piece to start at.                         */
        !           432:    ScanType sType;
        !           433: {
        !           434:   PieceQueueElement *qp = *_qp;     
        !           435:   XtTextPosition  s2Pos = *_s2Pos;
        !           436:   XtTextPosition  leftmost = *_leftmost;
        !           437:   XtTextPosition  rightmost = *_rightmost;
        !           438:   XtTextPosition  skew = *_skew;       
        !           439:   XtTextPosition  ppos, res;
        !           440:     leftmost = 0;
        !           441:     ppos = qp->begPos + skew;
        !           442:     while(qp){
        !           443:         res = (*(*qp->src)->scan)(*qp->src, ppos, sType, XtsdLeft, 1, 0);
        !           444:         if(res > qp->begPos){
        !           445:             break;
        !           446:         }
        !           447:        LeftPiece(qp, s2Pos);
        !           448:        if(qp)
        !           449:            ppos = qp->endPos;
        !           450:        else
        !           451:            return(0);
        !           452:     }          
        !           453:     rightmost = s2Pos + (res - qp->begPos);
        !           454:     res = (*(*qp->src)->scan)(*qp->src, ppos, sType, XtsdLeft, 1, 1);
        !           455:     if(res > qp->begPos){
        !           456:         leftmost = s2Pos + (res - qp->begPos);
        !           457:        skew = (res - qp->begPos);
        !           458:     } else {
        !           459:         LeftPiece(qp, s2Pos);
        !           460:         while(qp){
        !           461:             res = (*(*qp->src)->scan)(*qp->src, qp->endPos, sType, XtsdLeft, 1, 0);
        !           462:             if(res != qp->endPos){
        !           463:                 leftmost  = s2Pos + (PieceSize(qp));
        !           464:                skew = (PieceSize(qp));
        !           465:                break;
        !           466:            }
        !           467:            res = (*(*qp->src)->scan)(*qp->src, qp->endPos, sType, XtsdLeft, 1, 1);
        !           468:             if(res > qp->begPos){
        !           469:                 leftmost = s2Pos + (res - qp->begPos);
        !           470:                skew = (res - qp->begPos);
        !           471:                break;
        !           472:            }
        !           473:            leftmost = s2Pos;
        !           474:            LeftPiece(qp, s2Pos);
        !           475:        }
        !           476:     }
        !           477:     *_s2Pos = s2Pos;
        !           478:     *_skew = skew;
        !           479:     *_leftmost = leftmost;
        !           480:     *_rightmost = rightmost;
        !           481:     *_qp = qp;
        !           482:     return 1;
        !           483: }
        !           484: 
        !           485: static int PSread (src, pos, text, maxRead)
        !           486:   XtTextSource *src;
        !           487:   int pos;
        !           488:   XtTextBlock *text;
        !           489:   int maxRead;
        !           490: {
        !           491:   int pieceSize, skew;
        !           492:   PSContext *ctx = (PSContext *)src->data;  
        !           493:   PieceQueueElement *qp;
        !           494:     if (maxRead == 0){
        !           495:        text->length = 0;
        !           496:        return(pos);
        !           497:     }
        !           498:     qp = locate(ctx, &skew, pos);
        !           499:     if (!qp){
        !           500:        text->length = 0;
        !           501:        return pos;
        !           502:     }
        !           503:     pieceSize = (PieceSize(qp)) - skew;
        !           504:     if (pieceSize == 0){ 
        !           505:        text->length = 0;
        !           506:        return pos;
        !           507:     }
        !           508:     text->length = (maxRead > pieceSize) ? pieceSize : maxRead;
        !           509:     (*(*qp->src)->read)(*qp->src, (qp->begPos)+skew, text, text->length);
        !           510:     text->firstPos = pos;
        !           511:     return(pos + text->length);
        !           512: }
        !           513: 
        !           514: 
        !           515: static ChangeBlock *getChangeBlock()
        !           516: {
        !           517:     return((ChangeBlock *)calloc(sizeof(ChangeBlock), 1));
        !           518: }
        !           519: 
        !           520: XtTextPosition backoutChange(ctx, change)
        !           521:   ChangeBlock  *change;
        !           522:   PSContext *ctx;
        !           523: {
        !           524:   ChangeBlock  *newcb;
        !           525:   PieceQueueElement *where, *qp, *next;
        !           526:      if(!change)
        !           527:        return -1;
        !           528:     newcb = (ChangeBlock*)
        !           529:        insert(&ctx->CQHead, &ctx->CQTail, getChangeBlock(), ctx->CQTail);
        !           530:     newcb->where = change->where;
        !           531:     newcb->deletedPos = change->deletedPos;
        !           532:     qp = change->addedPtrFirst;
        !           533:     while(qp){
        !           534:        next = qp->flink;
        !           535:        retire(ctx, qp);
        !           536:        if(qp == change->addedPtrLast)
        !           537:            break;
        !           538:        qp = next;
        !           539:     }
        !           540: /* where is the PieceQueue element to put the old stuff back in after */
        !           541:     where = change->where;
        !           542: /* remqueue the deleted pieces of the retired list, and queue 'em back in PieceQ*/
        !           543:     if(change->Lptr){
        !           544:        ctx->endPos += change->Lfix - change->Lptr->endPos;
        !           545:        newcb->Lfix = change->Lptr->endPos;
        !           546:        change->Lptr->endPos = change->Lfix;
        !           547:        newcb->Lptr = change->Lptr;
        !           548:     }
        !           549:     qp = change->retiredQHead;
        !           550:     while(qp){
        !           551:        next = qp->flink;
        !           552:        where = insert(&ctx->PTQHead, &ctx->PTQTail, qp, where);
        !           553:        if(!newcb->addedPtrFirst)
        !           554:            newcb->addedPtrFirst = where;
        !           555:        ctx->endPos += PieceSize(qp);
        !           556:         if(qp == change->retiredQTail)
        !           557:            break;
        !           558:        qp = next;
        !           559:     }
        !           560:     if(change->Rptr){
        !           561:            ctx->endPos += change->Rptr->begPos - change->Rfix;
        !           562:            newcb->Rfix = change->Rptr->begPos;
        !           563:            change->Rptr->begPos = change->Rfix;
        !           564:            newcb->Rptr = change->Rptr;
        !           565:     }
        !           566:     if(newcb->addedPtrFirst)
        !           567:         newcb->addedPtrLast = where;
        !           568:     return(change->deletedPos);
        !           569: }
        !           570: 
        !           571: static int PSreplace(src, startPos, endPos, text, delta)
        !           572:   XtTextSource *src;
        !           573:   XtTextPosition startPos, endPos;
        !           574:   XtTextBlock *text;
        !           575:   int *delta;
        !           576: {
        !           577:   int wrote, delLength = endPos - startPos;
        !           578:   PSContext *ctx = (PSContext *)src->data;  
        !           579:   PieceQueueElement *here;
        !           580:   ChangeBlock  *cb;
        !           581:     ctx->LocatedPiece = 0;
        !           582:     if(startPos < 0){
        !           583:         if(!ctx->CQTail)
        !           584:             return -1;
        !           585:         ctx->LastUndid = ctx->CQTail;
        !           586:         return(backoutChange(ctx, ctx->CQTail));
        !           587:     } else if(endPos < 0){
        !           588:        if(!ctx->LastUndid)
        !           589:            return -1;
        !           590:        ctx->LastUndid = ctx->LastUndid->blink;
        !           591:        return(backoutChange(ctx, ctx->LastUndid));
        !           592:     }
        !           593: /*
        !           594:     switch (ctx->editMode) {
        !           595:         case XttextAppend:
        !           596:             if (startPos != endPos != data->length)
        !           597:                 return (POSITIONERROR);
        !           598:             break;
        !           599:         case XttextRead:
        !           600:             return (EDITERROR);
        !           601:         case XttextEdit:
        !           602:             break;
        !           603:         default:
        !           604:             return (EDITERROR);
        !           605:     }
        !           606: */
        !           607:     *delta = 0;
        !           608:     if(startPos > ctx->endPos)
        !           609:         return (EDITERROR);
        !           610:     ctx->LastUndid = 0;
        !           611:     if(text->length)
        !           612:         (*ctx->ao->replace)(ctx->ao, ctx->aoPos, ctx->aoPos, text, &wrote);
        !           613:     else {
        !           614:        wrote = 0;
        !           615:        if(!endPos)
        !           616:            return 0;
        !           617:     }
        !           618:     if((!delLength)&& (startPos==ctx->lastReplaceEndPos) && (ctx->lastAddedPiece)){
        !           619:        here = ctx->lastAddedPiece;
        !           620:         if(!((here->endPos == ctx->aoPos) && (here->src == &ctx->ao)))
        !           621:            printf("replace optimize panic 1 \n");
        !           622:        here->endPos += wrote;
        !           623:     } else {
        !           624:         cb = (ChangeBlock*)insert(&ctx->CQHead, &ctx->CQTail, getChangeBlock(), ctx->CQTail);
        !           625:         cb->deletedPos = startPos;
        !           626:         here = deleteRange(ctx, startPos, endPos);
        !           627:        cb->where = here;
        !           628:         if(text->length == 0){
        !           629:            *delta =  (startPos - endPos);
        !           630:            return (EDITDONE);
        !           631:         }
        !           632:        here = insert(&ctx->PTQHead, &ctx->PTQTail, getQp(), here);
        !           633:        ctx->lastAddedPiece = here;
        !           634:         here->begPos = ctx->aoPos;
        !           635:         here->endPos = ctx->aoPos + wrote;
        !           636:         here->src = &ctx->ao;
        !           637:        cb->addedPtrFirst = here;
        !           638:        if(!cb->addedPtrLast)
        !           639:            cb->addedPtrLast = here;
        !           640:     } 
        !           641:     ctx->lastReplaceEndPos = startPos + wrote;
        !           642:     ctx->aoPos += wrote;
        !           643:     ctx->endPos += wrote;
        !           644:     *delta = wrote - delLength;
        !           645:     return (EDITDONE);
        !           646: }
        !           647: 
        !           648: static XtTextPosition PSgetLastPos(src)
        !           649:   XtTextSource *src;
        !           650: {
        !           651:   PSContext *ctx = (PSContext *)src->data;
        !           652: /*
        !           653:   int t;
        !           654:   PieceQueueElement *qp;
        !           655:     t = 0;
        !           656:     for(qp = ctx->PTQHead; qp; qp = qp->flink){
        !           657:        t += (PieceSize(qp));
        !           658:     }
        !           659:     if (t != ctx->endPos){
        !           660:        printf("piece queue length discrepancy %d <> %d\n", t, ctx->endPos);
        !           661:        ctx->endPos = t;
        !           662:     }
        !           663:     return t;
        !           664: */
        !           665:     return ctx->endPos;
        !           666: }
        !           667: 
        !           668: static PSsetLastPos(src, lastPos)
        !           669:   XtTextSource *src;
        !           670:   XtTextPosition lastPos;
        !           671: {
        !           672:     PSContext *ctx = (PSContext *)src->data;
        !           673:     ctx->endPos = lastPos;
        !           674: }
        !           675: 
        !           676: static InitPieceTable(ctx)
        !           677:   PSContext *ctx;
        !           678: {
        !           679:   XtTextSource **ro = &(ctx->ro);
        !           680:   PieceQueueElement *qp;
        !           681:   XtTextPosition beg, end;
        !           682:     beg = (*(*ro)->scan)(*ro, 0, XtstFile, XtsdLeft,  0,0);
        !           683:     end = (*(*ro)->scan)(*ro, 0, XtstFile, XtsdRight, 0,0);
        !           684:     if(beg != end){
        !           685:         qp = insert(&ctx->PTQHead, &ctx->PTQTail, getQp(), 0);
        !           686:         qp->begPos = beg;
        !           687:         qp->endPos = end;
        !           688:         qp->src = ro;
        !           689:         ctx->endPos = PieceSize(qp);
        !           690:     }
        !           691: }
        !           692: static XtEditType PSGetEditType(src)
        !           693:   XtTextSource *src;
        !           694: {
        !           695: /*
        !           696:     StringSourcePtr data;
        !           697:     data = (StringSourcePtr) src->data;
        !           698:     return(data->editMode);
        !           699: */
        !           700:     return(XttextEdit);
        !           701: }
        !           702: 
        !           703: /*** Public routines ***/
        !           704: 
        !           705: XtTextSource *CreatePSource (ro, ao)
        !           706:   XtTextSource *ro, *ao;
        !           707: {
        !           708:   XtTextSource *src;
        !           709:   PSContext *ctx;
        !           710:   int     i;
        !           711:     src = (XtTextSource *) malloc(sizeof(XtTextSource));
        !           712:     src->read = PSread;
        !           713:     src->replace = PSreplace; 
        !           714:     src->getLastPos = PSgetLastPos;
        !           715:     src->setLastPos = PSsetLastPos;
        !           716:     src->scan = PSscan;
        !           717:     src->editType = PSGetEditType;
        !           718:     ctx = (PSContext *)(calloc(sizeof(PSContext),1));
        !           719:     ctx->ro = ro;
        !           720:     ctx->ao = ao;
        !           721:     InitPieceTable(ctx);
        !           722:     src->data = (int *)ctx;
        !           723: ctx_public = ctx;
        !           724:     return src;
        !           725: }
        !           726: 
        !           727: PSsetROsource(src, ro)
        !           728:   XtTextSource *src, *ro;
        !           729: {
        !           730:     PSContext *ctx = (PSContext *)src->data;
        !           731:     ctx->ro = ro;
        !           732: }
        !           733: 
        !           734: 
        !           735: DestroyPSource(src)
        !           736:   XtTextSource *src;
        !           737: {
        !           738: PieceQueueElement *qp, *qp_victim;
        !           739: ChangeBlock *cb, *cb_victim;
        !           740:     PSContext *ctx = (PSContext *)src->data;
        !           741:     cb = ctx->CQHead;
        !           742:     while(cb){
        !           743:         qp = cb->retiredQHead;
        !           744:        while(qp){
        !           745:            qp_victim = qp;
        !           746:            qp = qp->flink;
        !           747:                free(qp_victim);
        !           748:        }
        !           749:        cb_victim = cb;
        !           750:        cb = cb->flink;
        !           751:        free(cb_victim);
        !           752:     }
        !           753:     qp = ctx->PTQHead;
        !           754:     while(qp){
        !           755:        qp_victim = qp;
        !           756:        qp = qp->flink;
        !           757:        free(qp_victim);
        !           758:     }
        !           759:     free(ctx);
        !           760:     free(src);
        !           761: }
        !           762: 
        !           763: PSchanges(src)
        !           764:   XtTextSource *src;
        !           765: {
        !           766:   PSContext   *ctx = (PSContext *)src->data;
        !           767:   ChangeBlock *cb = ctx->CQHead;
        !           768:   int i;
        !           769:     i = 0;
        !           770:     while(cb){
        !           771:         i++;
        !           772:        cb = cb->flink;
        !           773:     }
        !           774:     return i;
        !           775: }
        !           776: PSbreakInput(src)
        !           777:   XtTextSource *src;
        !           778: {
        !           779:   PSContext   *ctx = (PSContext *)src->data;
        !           780:        ctx->lastReplaceEndPos = -1;
        !           781: }
        !           782: 
        !           783: 
        !           784:  

unix.superglobalmegacorp.com

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