Annotation of 43BSDTahoe/new/B/src/bed/bobj.c, revision 1.1

1.1     ! root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
        !             2: static char rcsid[] = "$Header: bobj.c,v 2.5 85/08/22 15:59:59 timo Exp $";
        !             3: 
        !             4: /*
        !             5:  * B editor -- A shrunken version of the B interpreter's run-time system.
        !             6:  */
        !             7: 
        !             8: #include "b.h"
        !             9: #include "bobj.h"
        !            10: #include "node.h"
        !            11: 
        !            12: #define COMPOUNDS
        !            13: 
        !            14: string malloc();
        !            15: string calloc();
        !            16: string realloc();
        !            17: string strcpy();
        !            18: 
        !            19: extern bool dflag;
        !            20: 
        !            21: struct head {
        !            22:        char type;
        !            23:        intlet refcnt;
        !            24:        intlet len;
        !            25: };
        !            26: #define Intsize (sizeof(int))
        !            27: #define Hsize (sizeof(struct head))
        !            28: #define Headsize (((Hsize-1)/Intsize + 1) * Intsize)
        !            29: 
        !            30: #define Field(v, i) (((value *)&(v)->cts)[i])
        !            31: 
        !            32: #ifndef NDEBUG
        !            33: 
        !            34: /* Statistics on allocation/sharing */
        !            35: 
        !            36: int nobjs;
        !            37: int nrefs;
        !            38: 
        !            39: #define Increfs ++nrefs
        !            40: #define Decrefs --nrefs
        !            41: 
        !            42: #else NDEBUG
        !            43: 
        !            44: #define Increfs 
        !            45: #define Decrefs 
        !            46: 
        !            47: #endif NDEBUG
        !            48: 
        !            49: 
        !            50: #define Copy(v) if ((v) && Refcnt(v) < Maxintlet) { ++Refcnt(v); Increfs; }
        !            51: #define Release(v) if (!(v) || Refcnt(v) == Maxintlet) ; else RRelease(v)
        !            52: #define RRelease(v) \
        !            53:        if (Refcnt(v) > 1) { --Refcnt(v); Decrefs; } else release(v)
        !            54: 
        !            55: 
        !            56: /*
        !            57:  * Allocate a value with nbytes of data after the usual type, len, refcnt
        !            58:  * fields.
        !            59:  */
        !            60: 
        !            61: value
        !            62: grabber(nbytes)
        !            63:        register int nbytes;
        !            64: {
        !            65:        register value v = (value) malloc((unsigned) (Headsize + nbytes));
        !            66: 
        !            67:        if (!v)
        !            68:                syserr("grabber: malloc");
        !            69: #ifndef NDEBUG
        !            70:        if (dflag)
        !            71:                newval(v);
        !            72: #endif
        !            73: #ifndef NDEBUG
        !            74:        ++nobjs;
        !            75: #endif
        !            76:        Increfs;
        !            77:        v->refcnt = 1;
        !            78:        return v;
        !            79: }
        !            80: 
        !            81: 
        !            82: /*
        !            83:  * Reallocate a value with nbytes of data after the usual type, len, refcnt
        !            84:  * fields.
        !            85:  */
        !            86: 
        !            87: value
        !            88: regrabber(v, nbytes)
        !            89:        register value v;
        !            90:        register int nbytes;
        !            91: {
        !            92:        Assert(v && v->refcnt == 1);
        !            93:        v = (value) realloc((char*)v, (unsigned) (Headsize + nbytes));
        !            94:        if (!v)
        !            95:                syserr("regrabber: realloc");
        !            96:        return v;
        !            97: }
        !            98: 
        !            99: 
        !           100: /*
        !           101:  * Set an object's refcnt to infinity, so it will never be released.
        !           102:  */
        !           103: 
        !           104: fix(v)
        !           105:        register value v;
        !           106: {
        !           107:        register int i;
        !           108:        register node n;
        !           109:        register path p;
        !           110: 
        !           111:        Assert(v->refcnt > 0);
        !           112: #ifndef NDEBUG
        !           113:        if (v->refcnt < Maxintlet)
        !           114:                nrefs -= v->refcnt;
        !           115: #endif
        !           116:        v->refcnt = Maxintlet;
        !           117: #if OBSOLETE
        !           118:        switch (v->type) {
        !           119:        case Tex:
        !           120:                break;
        !           121:        case Nod:
        !           122:                n = (node)v;
        !           123:                for (i = v->len - 1; i >= 0; --i)
        !           124:                        if (n->n_child[i])
        !           125:                                fix((value)(n->n_child[i]));
        !           126:                break;
        !           127:        case Pat:
        !           128:                p = (path)v;
        !           129:                if (p->p_parent)
        !           130:                        fix((value)(p->p_parent));
        !           131:                if (p->p_tree)
        !           132:                        fix((value)(p->p_tree));
        !           133:                break;
        !           134: #ifdef COMPOUNDS
        !           135:        case Com:
        !           136:                for (i = v->len-1; i >= 0; --i)
        !           137:                        if (Field(v, i))
        !           138:                                fix(Field(v, i));
        !           139:                break;
        !           140: #endif COMPOUNDS
        !           141: #ifdef SLOW_INTS
        !           142:        case Num:
        !           143: #endif SLOW_INTS
        !           144:        default:
        !           145:                Abort();
        !           146:        }
        !           147: #endif OBSOLETE
        !           148: }
        !           149: 
        !           150: 
        !           151: #ifdef COMPOUNDS
        !           152: /*
        !           153:  * Allocate a compound with n fields.
        !           154:  */
        !           155: 
        !           156: Visible value
        !           157: grab_com(n)
        !           158:        int n;
        !           159: {
        !           160:        value v = grabber(n*sizeof(value));
        !           161: 
        !           162:        v->type = Com;
        !           163:        v->len = n;
        !           164:        for (--n; n >= 0; --n)
        !           165:                Field(v, n) = Vnil;
        !           166:        return v;
        !           167: }
        !           168: #endif COMPOUNDS
        !           169: 
        !           170: 
        !           171: /*
        !           172:  * Allocate a node with nch children.
        !           173:  */
        !           174: 
        !           175: node
        !           176: grab_node(nch)
        !           177:        register int nch;
        !           178: {
        !           179:        register node n = (node) grabber(
        !           180:                        sizeof(struct node) - Headsize +
        !           181:                        sizeof(value) * (nch-1));
        !           182:        register int i;
        !           183: 
        !           184:        n->type = Nod;
        !           185:        n->len = nch;
        !           186:        n->n_marks = 0;
        !           187:        n->n_width = 0;
        !           188:        n->n_symbol = 0;
        !           189:        for (i = nch-1; i >= 0; --i)
        !           190:                n->n_child[i] = Nnil;
        !           191:        return n;
        !           192: }
        !           193: 
        !           194: 
        !           195: /*
        !           196:  * Allocate a path.
        !           197:  */
        !           198: 
        !           199: path
        !           200: grab_path()
        !           201: {
        !           202:        register path p = (path) grabber(
        !           203:                        sizeof(struct path) - Headsize);
        !           204: 
        !           205:        p->type = Pat;
        !           206:        p->p_parent = Pnil;
        !           207:        p->p_tree = Nnil;
        !           208:        p->p_ichild = 0;
        !           209:        p->p_ycoord = 0;
        !           210:        p->p_xcoord = 0;
        !           211:        p->p_level = 0;
        !           212:        p->p_addmarks = 0;
        !           213:        p->p_delmarks = 0;
        !           214:        return p;
        !           215: }
        !           216: 
        !           217: 
        !           218: #ifdef SLOW_INTS
        !           219: /*
        !           220:  * Make an integer.
        !           221:  */
        !           222: 
        !           223: value
        !           224: mk_integer(i)
        !           225:        int i;
        !           226: {
        !           227:        value v;
        !           228:        static value tab[128];
        !           229: 
        !           230:        if (!i)
        !           231:                return Vnil;
        !           232:        if (!(i&~127) && tab[i])
        !           233:                return tab[i];
        !           234: 
        !           235:        v = grabber(sizeof(value));
        !           236:        v->type = Num;
        !           237:        Field(v, 0) = (value) i;
        !           238:        if (!(i&~127)) {
        !           239:                tab[i] = v;
        !           240:                v->refcnt = Maxintlet;
        !           241:        }
        !           242:        return v;
        !           243: }
        !           244: #endif SLOW_INTS
        !           245: 
        !           246: 
        !           247: /*
        !           248:  * Make a text object out of a C string.
        !           249:  */
        !           250: 
        !           251: value
        !           252: mk_text(str)
        !           253:        register string str;
        !           254: {
        !           255:        register int len = strlen(str);
        !           256:        register value v = grabber(len+1);
        !           257: 
        !           258:        v->type = Tex;
        !           259:        v->len = len;
        !           260:        strcpy(Str(v), str);
        !           261:        return v;
        !           262: }
        !           263: 
        !           264: 
        !           265: /*
        !           266:  * Concatenate a C string to a text object (at the end).
        !           267:  */
        !           268: 
        !           269: concato(pv, str)
        !           270:        register value *pv;
        !           271:        register string str;
        !           272: {
        !           273:        register value v = *pv;
        !           274:        register int vlen = v->len;
        !           275:        register int len = strlen(str);
        !           276: 
        !           277:        Assert(v && v->refcnt > 0);
        !           278:        if (!len)
        !           279:                return;
        !           280: 
        !           281:        len += vlen;
        !           282:        if (v->refcnt == 1)
        !           283:                v = regrabber(v, len+1);
        !           284:        else {
        !           285:                v = grabber(len+1);
        !           286:                v->type = Tex;
        !           287:                strcpy(Str(v), Str(*pv));
        !           288:                Release(*pv);
        !           289:        }
        !           290:        strcpy(Str(v) + vlen, str);
        !           291:        v->len = len;
        !           292:        *pv = v;
        !           293: }
        !           294: 
        !           295: 
        !           296: /*
        !           297:  * Return a substring (trim) of a text object.
        !           298:  */
        !           299: 
        !           300: value
        !           301: trim(v, behead, curtail)
        !           302:        register value v;
        !           303:        register int behead;
        !           304:        register int curtail;
        !           305: {
        !           306:        register value w;
        !           307:        register int c;
        !           308: 
        !           309:        Assert(v && v->refcnt > 0);
        !           310:        Assert(behead >= 0 && curtail >= 0 && behead+curtail <= v->len);
        !           311:        if (behead + curtail == 0) {
        !           312:                Copy(v);
        !           313:                return v;
        !           314:        }
        !           315: 
        !           316:        c = Str(v)[v->len - curtail];
        !           317:        Str(v)[v->len - curtail] = 0; /* TEMPORARILY */
        !           318:        w = mk_text(Str(v) + behead);
        !           319:        Str(v)[v->len - curtail] = c;
        !           320:        return w;
        !           321: }
        !           322: 
        !           323: 
        !           324: #ifdef SLOW_INTS
        !           325: /*
        !           326:  * Return the C value if an integer object.
        !           327:  */
        !           328: 
        !           329: int
        !           330: intval(v)
        !           331:        register value v;
        !           332: {
        !           333:        if (!v)
        !           334:                return 0;
        !           335:        return (int) Field(v, 0);
        !           336: }
        !           337: #endif SLOW_INTS
        !           338: 
        !           339: 
        !           340: /*
        !           341:  * Make sure a location (pointer variable) contains a unique object.
        !           342:  */
        !           343: 
        !           344: uniql(pv)
        !           345:        register value *pv;
        !           346: {
        !           347:        register value v = *pv;
        !           348:        register value w;
        !           349:        register path p;
        !           350:        register node n;
        !           351:        register int i;
        !           352: 
        !           353:        Assert(v && v->refcnt > 0);
        !           354:        if (v->refcnt == 1)
        !           355:                return;
        !           356: 
        !           357:        switch (v->type) {
        !           358: 
        !           359:        case Nod:
        !           360:                n = grab_node(v->len);
        !           361:                for (i = v->len - 1; i >= 0; --i) {
        !           362:                        w = (value) (n->n_child[i] = ((node)v)->n_child[i]);
        !           363:                        Copy(w); /* This is ugly */
        !           364:                }
        !           365:                n->n_marks = ((node)v)->n_marks;
        !           366:                n->n_width = ((node)v)->n_width;
        !           367:                n->n_symbol = ((node)v)->n_symbol;
        !           368:                w = (value)n;
        !           369:                break;
        !           370: 
        !           371:        case Pat:
        !           372:                p = grab_path();
        !           373:                p->p_parent = ((path)v)->p_parent;
        !           374:                Copy(p->p_parent);
        !           375:                p->p_tree = ((path)v)->p_tree;
        !           376:                Copy(p->p_tree);
        !           377:                p->p_ichild = ((path)v)->p_ichild;
        !           378:                p->p_ycoord = ((path)v)->p_ycoord;
        !           379:                p->p_xcoord = ((path)v)->p_xcoord;
        !           380:                p->p_level = ((path)v)->p_level;
        !           381:                w = (value)p;
        !           382:                break;
        !           383: 
        !           384: #ifdef SLOW_INTS
        !           385:        case Num:
        !           386:                w = mk_integer(intval(v));
        !           387:                break;
        !           388: #endif SLOW_INTS
        !           389: 
        !           390: #ifdef COMPOUNDS
        !           391:        case Com:
        !           392:                w = grab_com(v->len);
        !           393:                for (i = v->len - 1; i >= 0; --i) {
        !           394:                        n = (node) (Field(w, i) = Field(v, i));
        !           395:                        Copy(n); /* This is uglier */
        !           396:                }
        !           397:                break;
        !           398: #endif COMPOUNDS
        !           399: 
        !           400:        case Tex:
        !           401:                w = mk_text(Str(v));
        !           402:                break;
        !           403: 
        !           404:        default:
        !           405:                Abort();
        !           406: 
        !           407:        }
        !           408:        Release(v);
        !           409:        *pv = w;
        !           410: }
        !           411: 
        !           412: 
        !           413: /*
        !           414:  * Increase the reference count of an object, unless it is infinite.
        !           415:  */
        !           416: 
        !           417: value
        !           418: copy(v)
        !           419:        value v;
        !           420: {
        !           421:        if (!v)
        !           422:                return v;
        !           423: 
        !           424:        Assert(v->refcnt > 0);
        !           425:        if (v->refcnt < Maxintlet) {
        !           426:                ++v->refcnt;
        !           427:                Increfs;
        !           428:        }
        !           429:        return v;
        !           430: }
        !           431: 
        !           432: 
        !           433: /*
        !           434:  * Decrease the reference count of an object, unless it is infinite.
        !           435:  * If it reaches zero, free the storage occupied by the object.
        !           436:  */
        !           437: 
        !           438: release(v)
        !           439:        register value v;
        !           440: {
        !           441:        register int i;
        !           442:        register value w;
        !           443: 
        !           444:        if (!v)
        !           445:                return;
        !           446:        Assert(v->refcnt > 0);
        !           447:        if (v->refcnt == Maxintlet)
        !           448:                return;
        !           449: 
        !           450:        Decrefs;
        !           451:        --v->refcnt;
        !           452:        if (v->refcnt == 0) {
        !           453:                switch (v->type) {
        !           454: #ifdef SLOW_INTS
        !           455:                case Num:
        !           456: #endif SLOW_INTS
        !           457:                case Tex:
        !           458:                        break;
        !           459: #ifdef COMPOUNDS
        !           460:                case Com:
        !           461:                        for (i = v->len - 1; i >= 0; --i) {
        !           462:                                w = Field(v, i);
        !           463:                                Release(w);
        !           464:                        }
        !           465:                        break;
        !           466: #endif COMPOUNDS
        !           467:                case Nod:
        !           468:                        for (i = v->len - 1; i >= 0; --i) {
        !           469:                                w = (value)(((node)v)->n_child[i]);
        !           470:                                Release(w);
        !           471:                        }
        !           472:                        break;
        !           473:                case Pat:
        !           474:                        w = (value)(((path)v)->p_parent);
        !           475:                        Release(w);
        !           476:                        w = (value)(((path)v)->p_tree);
        !           477:                        Release(w);
        !           478:                        break;
        !           479:                default:
        !           480:                        Abort();
        !           481:                }
        !           482: #ifndef NDEBUG
        !           483:                if (dflag)
        !           484:                        delval(v);
        !           485:                --nobjs;
        !           486: #endif NDEBUG
        !           487:                free((string)v);
        !           488:        }
        !           489: }
        !           490: 
        !           491: objstats()
        !           492: {
        !           493: #ifndef NDEBUG
        !           494:        fprintf(stderr, "*** Object statistics: %d objects, %d references\n",
        !           495:                nobjs, nrefs);
        !           496: #ifdef MSTATS
        !           497:        mstats("(at end)"); /* A routine which some malloc versions have to print
        !           498:                     memory statistics. Remove if your malloc hasn't. */
        !           499: #endif MSTATS
        !           500: #endif NDEBUG
        !           501: }
        !           502: 
        !           503: #ifndef NDEBUG
        !           504: valdump(v)
        !           505:        value v;
        !           506: {
        !           507:        if (!v)
        !           508:                fputs("(nil)", stderr);
        !           509:        else {
        !           510:                fprintf(stderr, "v=0x%x, type='%c', len=%d, refcnt=",
        !           511:                        v, v->type, v->len);
        !           512:                if (v->refcnt == Maxintlet)
        !           513:                        putc('*', stderr);
        !           514:                else
        !           515:                        fprintf(stderr, "%d", v->refcnt);
        !           516:                fputs(": ", stderr);
        !           517:                wrval(v);
        !           518: 
        !           519:        }
        !           520:        putc('\n', stderr);
        !           521: }
        !           522: 
        !           523: #define QUOTE '\''
        !           524: 
        !           525: wrval(v)
        !           526:        value v;
        !           527: {
        !           528:        register string cp;
        !           529:        register int c;
        !           530: 
        !           531:        if (!v) {
        !           532:                fputs("nil", stderr);
        !           533:                return;
        !           534:        }
        !           535: 
        !           536:        switch (v->type) {
        !           537: 
        !           538: #ifdef SLOW_INTS
        !           539:        case Num:
        !           540:                fprintf(stderr, "%d", intval(v));
        !           541:                break;
        !           542: #endif SLOW_INTS
        !           543: 
        !           544:        case Tex:
        !           545:                putc(QUOTE, stderr);
        !           546:                for (cp = Str(v); c = *cp; ++cp) {
        !           547:                        if (' ' <= c && c < 0177) {
        !           548:                                putc(c, stderr);
        !           549:                                if (c == QUOTE)
        !           550:                                        putc(c, stderr);
        !           551:                        }
        !           552:                        else if (0 <= c && c < ' ')
        !           553:                                putc('^', stderr), putc(c + '@', stderr);
        !           554:                        else
        !           555:                                fprintf(stderr, "\\%03o", c);
        !           556:                }
        !           557:                putc(QUOTE, stderr);
        !           558:                break;
        !           559: 
        !           560: #ifdef COMPOUNDS
        !           561:        case Com:
        !           562:          {
        !           563:                int i;
        !           564:                value f;
        !           565:                putc('(', stderr);
        !           566:                for (i = 0; i < v->len; ++i) {
        !           567:                        if (i)
        !           568:                                putc(',', stderr), putc(' ', stderr);
        !           569:                        f = Field(v, i);
        !           570:                        if (!f || f->refcnt == 1 || f->type != Com) {
        !           571:                                if (f && f->type == Com)
        !           572:                                        fprintf(stderr, "0x%x=", f);
        !           573:                                wrval(f);
        !           574:                        }
        !           575:                        else
        !           576:                                fprintf(stderr, "0x%x", f);
        !           577:                }
        !           578:                putc(')', stderr);
        !           579:                break;
        !           580:          }
        !           581: #endif COMPOUNDS
        !           582: 
        !           583:        default:
        !           584:                fprintf(stderr, "0x%x", v);
        !           585: 
        !           586:        }
        !           587: }
        !           588: 
        !           589: static struct list {
        !           590:        struct list *link;
        !           591:        value val;
        !           592: } head;
        !           593: #endif NDEBUG
        !           594: 
        !           595: objdump()
        !           596: {
        !           597: #ifndef NDEBUG
        !           598:        struct list *l;
        !           599: 
        !           600:        for (l = head.link; l; l = l->link)
        !           601:                valdump(l->val);
        !           602: #endif NDEBUG
        !           603: }
        !           604: 
        !           605: objcheck()
        !           606: {
        !           607: #ifndef NDEBUG
        !           608:        struct list *l;
        !           609: 
        !           610:        for (l = head.link; l; l = l->link)
        !           611:                if (l->val->refcnt != Maxintlet)
        !           612:                        valdump(l->val);
        !           613: #endif NDEBUG
        !           614: }
        !           615: 
        !           616: #ifndef NDEBUG
        !           617: newval(v)
        !           618:        register value v;
        !           619: {
        !           620:        register struct list *l =
        !           621:                        (struct list *) malloc((unsigned) sizeof(struct list));
        !           622: 
        !           623:        if (!l)
        !           624:                syserr("newval: malloc");
        !           625:        l->link = head.link;
        !           626:        l->val = v;
        !           627:        head.link = l;
        !           628: }
        !           629: 
        !           630: delval(v)
        !           631:        register value v;
        !           632: {
        !           633:        register struct list *l;
        !           634:        register struct list *p;
        !           635: 
        !           636:        for (p = &head, l = head.link; l; p = l, l = l->link) {
        !           637:                if (l->val == v) {
        !           638:                        p->link = l->link;
        !           639:                        free((string)l);
        !           640:                        return;
        !           641:                }
        !           642:        }
        !           643:        Abort();
        !           644: }
        !           645: #endif NDEBUG

unix.superglobalmegacorp.com

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