Annotation of 43BSD/contrib/B/src/bed/bobj.c, revision 1.1.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.