Annotation of coherent/b/bin/c/n0/gdecl.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * n0/gdecl.c
                      3:  * Read in declarators and build up the DIM and INFO structures.
                      4:  */
                      5: 
                      6: #ifdef   vax
                      7: #include "INC$LIB:cc0.h"
                      8: #else
                      9: #include "cc0.h"
                     10: #endif
                     11: 
                     12: /*
                     13:  * Read declarator.
                     14:  * The arg "tdp" is the dimensions from a typedef.
                     15:  * The storage class is passed since
                     16:  * it determines the lexic level of the lookup.
                     17:  */
                     18: gdecl(asp, adp, tdp, c, ls)
                     19: SYM    **asp;
                     20: DIM    **adp, *tdp;
                     21: int    c, ls;
                     22: {
                     23:        register SYM    *sp;
                     24:        DIM             *dp;
                     25:        int             ll;     /* Lexical level */
                     26:        int             aok;    /* Args are OK flag */
                     27:        sizeof_t        bound;  /* Array bound */
                     28: 
                     29:        aok = (llex==LL_EXT && (c==C_GDEF || c==C_GREF || c==C_SEX) && nargs==0);
                     30:        while (s == CONST || s == VOLATILE) {
                     31:                /* Ignore these for now.  They should be treated as MUL */
                     32:                /* They can appear before the type-name as well */
                     33:                lex();
                     34:        }
                     35:        if (s == MUL) {
                     36:                lex();
                     37:                if (gdecl(asp, adp, NULL, c, ls) == 0)
                     38:                        return 0;
                     39:                *adp = tackdim(*adp, D_PTR, (sizeof_t)0);
                     40:                while (tdp != NULL) {
                     41:                        *adp = tackdim(*adp, tdp->d_type, tdp->d_bound);
                     42:                        tdp = tdp->d_dp;
                     43:                }
                     44:                return 1;
                     45:        }
                     46:        if (s == LPAREN) {
                     47:                lex();
                     48:                if (gdecl(asp, adp, NULL, c, ls) == 0)
                     49:                        return 0;
                     50:                mustbe(RPAREN);
                     51:                sp = *asp;
                     52:                dp = *adp;
                     53:                if (nargs != 0)
                     54:                        aok = 0;
                     55:        } else if (s == ID) {
                     56:                if (c==C_ARG || c==C_PAUTO || c==C_PREG)
                     57:                        ll = LL_ARG;
                     58:                else if (c==C_GDEF || c==C_GREF)
                     59:                        ll = LL_EXT;
                     60:                else
                     61:                        ll = llex;
                     62:                sp = deflookup(ls, ll);
                     63:                dp = NULL;
                     64:                lex();
                     65:        } else {
                     66:                cerror("declarator syntax");
                     67:                while (s!=EOF && s!=COMMA && s!=SEMI)
                     68:                        skip();
                     69:                return 0;
                     70:        }
                     71: again:
                     72:        if (s == LPAREN) {
                     73:                lex();
                     74:                garglist(&aok, &dp);
                     75:                mustbe(RPAREN);
                     76:                goto again;
                     77:        }
                     78:        if (s == LBRACK) {
                     79:                lex();
                     80:                bound = 0;
                     81:                if (s != RBRACK)
                     82:                        bound = getbound();
                     83:                mustbe(RBRACK);
                     84:                dp = tackdim(dp, D_ARRAY, bound);
                     85:                goto again;
                     86:        }
                     87:        while (tdp != NULL) {
                     88:                dp = tackdim(dp, tdp->d_type, tdp->d_bound);
                     89:                tdp = tdp->d_dp;
                     90:        }
                     91:        *asp = sp;
                     92:        *adp = dp;
                     93:        return 1;
                     94: }
                     95: 
                     96: /*
                     97:  * This routine generates tags for tagless struct/union/enum
                     98:  * declarations.  This makes life easier for csd.
                     99:  */
                    100: SYM *newtag(ll) int ll;
                    101: {
                    102:        sprintf(id, ".%d", newlab());
                    103:        setid(id);
                    104:        return deflookup(SL_TAG, ll);
                    105: }
                    106: 
                    107: /*
                    108:  * This routine processes structure and union declarations.
                    109:  * The type and INFO data gets passed back indirectly through the
                    110:  * "call by reference" parameters.
                    111:  * The storage class is passed so that local extern structure
                    112:  * definitions get entered at the correct (global) lexical level.
                    113:  */
                    114: gstruct(sc, at, aip)
                    115: int    sc, *at;
                    116: INFO   **aip;
                    117: {
                    118:        int     c, dt, i, j, mc, t, tc, w, rf, ls, ll, nbpstrg;
                    119:        SYM     *tsp, *msp, *mp;
                    120:        DIM     *dp,  **mdp;
                    121:        INFO    *ip, *nip;
                    122:        TOK     *oidp;
                    123:        unsigned long   ofs, max, bitsize;
                    124: 
                    125:        ll = (sc == C_GREF) ? LL_EXT : llex;
                    126:        ls = lsym;
                    127:        if (notvariant(VSINU))
                    128:                lsym += 1;
                    129:        dt = T_STRUCT;
                    130:        tc = C_STAG;
                    131:        mc = C_MOS;
                    132:        if (s == UNION) {
                    133:                dt = T_UNION;
                    134:                tc = C_UTAG;
                    135:                mc = C_MOU;
                    136:        }
                    137:        tsp = NULL;
                    138:        lex();
                    139:        if (s == ID) {
                    140:                tsp = reflookup(SL_TAG);
                    141:                if (tsp == NULL)
                    142:                        tsp = deflookup(SL_TAG, ll);
                    143:                oidp = idp;             /* save idp, lex() may clobber it */
                    144:                lex();
                    145:                if (s != LBRACE) {
                    146:                        c = tsp->s_class;
                    147:                        if (c == C_NONE) {
                    148:                                *at = dt+1;     /* Forward */
                    149:                                *aip = tsp;
                    150:                                return;
                    151:                        }
                    152:                        if (c==C_STAG || c==C_UTAG) {
                    153:                                if (c != tc)
                    154:                                        tagmismatch(tsp);
                    155:                                *at = dt;
                    156:                                *aip = tsp->s_ip;
                    157:                                ++tsp->s_ip->i_refc;
                    158:                                return;
                    159:                        }
                    160:                        cerror("\"%s\" is not a tag", tsp->s_id);
                    161:                        *at = T_INT;
                    162:                        *aip = NULL;
                    163:                        return;
                    164:                }
                    165:                idp = oidp;             /* restore idp for deflookup() */
                    166:                tsp = deflookup(SL_TAG, ll);
                    167:        } else
                    168:                tsp = newtag(ll);
                    169:        mustbe(LBRACE);
                    170:        nip = (INFO *) new(sizeof(INFO));
                    171:        nip->i_refc = 1;
                    172:        nip->i_nsp = 0;
                    173:        ofs = 0;
                    174:        max = 0;
                    175:        while (s!=EOF && s!=RBRACE) {
                    176:                gcandt(&c, &t, &dp, &ip, &rf);
                    177:                if (t == T_NONE) {
                    178:                        if (s == ID)
                    179:                                cerror("\"%s\" is not a typedef name", id);
                    180:                        else
                    181:                                cerror("missing type in structure body");
                    182:                        while (s!=EOF && s!=RBRACE && s!=SEMI)
                    183:                                lex();
                    184:                        if (s == SEMI)
                    185:                                lex();
                    186:                        continue;
                    187:                }
                    188:                if (rf != 0 || c != C_NONE)
                    189:                        cerror("class not allowed in structure body");
                    190:                if (isvariant(VSINU)) {
                    191:                /*
                    192:                 * Handle the "struct" in "union" rule.
                    193:                 * A series of unnamed structures within a union are united
                    194:                 * into a set of named/typed offsets within the union.
                    195:                 * Basically, we add the unique members of the
                    196:                 * new structure to the members of the current union.
                    197:                 * Not strictly part of C, and only works if all MOS in
                    198:                 * same level of symbol table.
                    199:                 */
                    200:                        if (dt==T_UNION && t==T_STRUCT && s==SEMI) {
                    201:                                notbook();
                    202:                                lex();
                    203:                                bitsize = (unsigned long)ip->i_size*NBPBYTE;
                    204:                                if (bitsize > max)
                    205:                                        max = bitsize;
                    206:                                for (i=0; i<ip->i_nsp; ++i) {
                    207:                                        mp = ip->i_sp[i];
                    208:                                        j = nip->i_nsp;
                    209:                                        while (--j >= 0)
                    210:                                                if (nip->i_sp[j] == mp)
                    211:                                                        break;
                    212:                                        if (j < 0) {
                    213:                                                nip = newinfo(nip, mp);
                    214:                                                if (tsp != NULL)
                    215:                                                        mp->s_flag |= S_TAG;
                    216:                                        }
                    217:                                }
                    218:                                continue;
                    219:                        }
                    220:                }
                    221:                for (;;) {
                    222:                        if (s == COLON) {
                    223:                                lex();
                    224:                                newtree(sizeof(TREE));
                    225:                                ++ininit;
                    226:                                w = iconexpr();
                    227:                                --ininit;
                    228:                                if (w < 0)
                    229:                                        cerror("bad filler field width");
                    230:                                ofs = fieldalign(t, NULL, ip, w, ofs) + w;
                    231:                        } else if (gdecl(&msp, &mdp, dp, mc, ls)) {
                    232:                                if (sc == C_GREF)
                    233:                                        msp->s_level = LL_EXT;
                    234:                                w = 0;
                    235:                                if (s == COLON) {
                    236:                                        lex();
                    237:                                        newtree(sizeof(TREE));
                    238:                                        ++ininit;
                    239:                                        w = iconexpr();
                    240:                                        --ininit;
                    241:                                        if (w <= 0)
                    242:                                                cerror("bad field width");
                    243:                                }
                    244:                                ofs = fieldalign(t, mdp, ip, w, ofs);
                    245:                                msp = declare(msp, mc, t, mdp, ip, rf, w, ofs);
                    246:                                nip = newinfo(nip, msp);
                    247:                                if (tsp != NULL)
                    248:                                        msp->s_flag |= S_TAG;
                    249:                                if (w == 0)
                    250:                                    ofs += (unsigned long)ssize(msp)*NBPBYTE;
                    251:                                else
                    252:                                    ofs += w;
                    253:                        }
                    254:                        if (dt == T_UNION) {
                    255:                                if (ofs > max)
                    256:                                        max = ofs;
                    257:                                ofs = 0;
                    258:                        }
                    259:                        if (s != COMMA)
                    260:                                break;
                    261:                        lex();
                    262:                }
                    263:                xdropinfo(t, ip);
                    264:                mustbe(SEMI);
                    265:        }
                    266:        mustbe(RBRACE);
                    267:        if (dt == T_STRUCT)
                    268:                max = ofs;
                    269:        nbpstrg = saligntype(nip) * NBPBYTE;
                    270:        if (nbpstrg == 0)
                    271:                nbpstrg = NBPBYTE;
                    272:        max = (max + nbpstrg - 1) / nbpstrg;
                    273:        max = max * nbpstrg / NBPBYTE;
                    274:        if (max > MAXESIZE) {
                    275:                cerror("size of %s too large",
                    276:                        (dt==T_STRUCT) ? "struct" : "union");
                    277:                max = 0;
                    278:        }
                    279:        nip->i_size = max;
                    280:        if (tsp != NULL)
                    281:                tsp = declare(tsp, tc, 0, NULL, nip, 0);
                    282:        *at = dt;
                    283:        *aip = nip;
                    284: }
                    285: 
                    286: /*
                    287:  * Read an enumeration.
                    288:  */
                    289: genum(sc, at, aip)
                    290: int    sc, *at;
                    291: INFO   **aip;
                    292: {
                    293:        register SYM    *sp, *tsp;
                    294:        INFO            *ip;
                    295:        TOK             *oidp;
                    296:        int             c, emv, emvmax, emvmin, ll;
                    297: 
                    298:        ll = (sc == C_GREF) ? LL_EXT : llex;
                    299:        tsp = NULL;
                    300:        lex();
                    301:        if (s == ID) {
                    302:                tsp = reflookup(SL_TAG);
                    303:                oidp = idp;             /* save idp, lex() may clobber it */
                    304:                lex();
                    305:                if (s != LBRACE) {
                    306:                        if (tsp == NULL)
                    307:                                tsp = deflookup(SL_TAG, ll);
                    308:                        c = tsp->s_class;
                    309:                        if (c == C_NONE) {
                    310:                                *at = T_FENUM;
                    311:                                *aip = tsp;
                    312:                                return;
                    313:                        }
                    314:                        if (c == C_ETAG) {
                    315:                                *at = T_ENUM;
                    316:                                *aip = tsp->s_ip;
                    317:                                ++tsp->s_ip->i_refc;
                    318:                                return;
                    319:                        }
                    320:                        cerror("\"%s\" is not an \"enum\" tag",
                    321:                                         tsp->s_id);
                    322:                        *at = T_INT;
                    323:                        *aip = NULL;
                    324:                        return;
                    325:                }
                    326:                idp = oidp;             /* restore idp for deflookup() */
                    327:                tsp = deflookup(SL_TAG, ll);
                    328:        } else
                    329:                tsp = newtag(ll);
                    330:        mustbe(LBRACE);
                    331:        ip = (INFO *) new(sizeof(INFO));
                    332:        ip->i_refc = 1;
                    333:        ip->i_nsp = 0;
                    334:        emvmax = emvmin = emv = 0;
                    335:        for (;;) {
                    336:                if (s==EOF || (s==RBRACE && ip->i_nsp == 0)) {
                    337:                        cerror("unexpected end of enumeration list");
                    338:                        break;
                    339:                } else if (s==RBRACE) {
                    340:                        cwarn("trailing ',' in enumeration list");
                    341:                        break;
                    342:                } else if (s != ID) {
                    343:                        cerror("error in enumeration list syntax");
                    344:                        skip();
                    345:                        continue;
                    346:                }
                    347:                sp = deflookup(SL_VAR, ll);
                    348:                lex();
                    349:                if (s == ASSIGN) {
                    350:                        lex();
                    351:                        newtree(sizeof(TREE));
                    352:                        ++ininit;
                    353:                        emv = iconexpr();
                    354:                        --ininit;
                    355:                }
                    356:                if (emv > emvmax)
                    357:                        emvmax = emv;
                    358:                if (emv < emvmin)
                    359:                        emvmin = emv;
                    360:                ip = newinfo(ip, sp);
                    361:                sp = declare(sp, C_MOE, 0, NULL, NULL, 0, emv);
                    362:                ++emv;
                    363:                if (s == RBRACE)
                    364:                        break;
                    365:                mustbe(COMMA);
                    366:        }
                    367:        if (s == RBRACE)
                    368:                lex();
                    369:        ip->i_type = (emvmax>MAXUCE || emvmin<0) ? T_INT : T_UCHAR;
                    370:        if (tsp != NULL)
                    371:                tsp = declare(tsp, C_ETAG, 0, NULL, ip, 0);
                    372:        *at = T_ENUM;
                    373:        *aip = ip;
                    374: }
                    375: 
                    376: /*
                    377:  * Read an old-style K&R function argument list.
                    378:  * '*aokp' indicates whether the storage class of the parent declarator
                    379:  * and the position of the parenthesized list is appropriate for the
                    380:  * formal parameter list of an actual function definition.
                    381:  * '*adp' is where the function prototype DIM should be stored.
                    382:  */
                    383: garglist(aokp, adp) register int *aokp; register DIM **adp;
                    384: {
                    385:        register SYM *ap;
                    386: 
                    387:        if (*aokp==1) {
                    388:                nargs = 0;
                    389:                if (s != RPAREN)
                    390:                        for (;;) {
                    391:                                if (s != ID) {
                    392:                                        cerror("argument list has incorrect syntax");
                    393:                                        break;
                    394:                                }
                    395:                                if (nargs >= NARGS)
                    396:                                        cfatal("too many arguments");
                    397:                                ap = deflookup(SL_VAR, LL_ARG);
                    398:                                ap = declare(ap, C_ARG, T_INT,
                    399:                                                   NULL, NULL, 0);
                    400:                                args[nargs++] = ap;
                    401:                                lex();
                    402:                                if (s != COMMA)
                    403:                                        break;
                    404:                                lex();
                    405:                        }
                    406:                *aokp = 0;
                    407:        }
                    408:        *adp = tackdim(*adp, D_FUNC, (sizeof_t)0);
                    409: }
                    410: 
                    411: /*
                    412:  * Tack a DIM structure onto the end
                    413:  * of the dimension list associated with "dp".
                    414:  */
                    415: DIM *
                    416: tackdim(dp, t, b)
                    417: DIM    *dp;
                    418: int    t;
                    419: sizeof_t b;
                    420: {
                    421:        register DIM    *dp1, *dp2;
                    422: 
                    423:        dp1 = (struct dim *) new(sizeof(struct dim));
                    424:        dp1->d_dp = NULL;
                    425:        dp1->d_type = t;
                    426:        dp1->d_bound = b;
                    427:        if ((dp2 = dp) == NULL)
                    428:                return dp1;
                    429:        while (dp2->d_dp != NULL)
                    430:                dp2 = dp2->d_dp;
                    431:        dp2->d_dp = dp1;
                    432:        return dp;
                    433: }
                    434: 
                    435: /*
                    436:  * Release a DIM chain.
                    437:  */
                    438: dropdim(dp)
                    439: register DIM   *dp;
                    440: {
                    441:        if (dp != NULL) {
                    442:                dropdim(dp->d_dp);
                    443:                free((char *) dp);
                    444:        }
                    445: }
                    446: 
                    447: /*
                    448:  * Duplicate a DIM chain.
                    449:  */
                    450: DIM *
                    451: dupldim(dp)
                    452: register DIM   *dp;
                    453: {
                    454:        register DIM    *np;
                    455: 
                    456:        if (dp == NULL)
                    457:                return NULL;
                    458:        np = (struct dim *) new(sizeof(struct dim));
                    459:        np->d_dp = dupldim(dp->d_dp);
                    460:        np->d_type = dp->d_type;
                    461:        np->d_bound = dp->d_bound;
                    462:        return np;
                    463: }
                    464: 
                    465: /*
                    466:  * Append a symbol to a struct/union/enum information array.
                    467:  * Grow the array if necessary and possible.
                    468:  */
                    469: INFO *
                    470: newinfo(ip, sp)
                    471: register INFO  *ip;
                    472: SYM    *sp;
                    473: {
                    474:        register INFO   *tip;
                    475:        register int    i;
                    476: 
                    477:        i = ip->i_nsp;
                    478:        if ((i % 16) == 0) {
                    479:                tip = ip;
                    480:                ip = (INFO *) new(sizeof(INFO) + (i+16) * sizeof(SYM *));
                    481:                ip->i_refc = tip->i_refc;
                    482:                ip->i_data = tip->i_data;
                    483:                ip->i_nsp = i;
                    484:                while (--i >= 0)
                    485:                        ip->i_sp[i] = tip->i_sp[i];
                    486:                free((char *) tip);
                    487:                i = ip->i_nsp;
                    488:        }
                    489:        ip->i_sp[i] = sp;
                    490:        ip->i_nsp += 1;
                    491:        return ip;
                    492: }
                    493: 
                    494: /*
                    495:  * Read an array bound.
                    496:  * An array bound is a constant expression.
                    497:  * It may be inside a cast, so save and restore the tree allocate pointer.
                    498:  * If signed, give an error if the bound is less than 0.
                    499:  * Call the machine dependent size check routine for upper bound check.
                    500:  */
                    501: sizeof_t getbound()
                    502: {
                    503:        register TREE   *tp;
                    504:        extern TREE     *expr();
                    505:        register int    t;
                    506:        register long   bound;
                    507:        TREE            *tmp;
                    508: 
                    509:        tmp = talloc();
                    510:        tp = expr();
                    511:        treset(tmp);
                    512:        if (tp->t_op == ICON)
                    513:                bound = tp->t_ival;
                    514:        else if (tp->t_op == LCON)
                    515:                bound = tp->t_lval;
                    516:        else if (tp->t_op == ZCON)
                    517:                bound = tp->t_zval;
                    518:        else {
                    519:                cerror("array bound must be a constant");
                    520:                return 0;
                    521:        }
                    522:        t = tltype(tp);
                    523:        if ((t==T_CHAR || t==T_SHORT || t==T_INT || t==T_LONG)
                    524:        && bound < 0) {
                    525:                cerror("array bound must be positive");
                    526:                return 0;
                    527:        }
                    528:        return szcheck(bound, 1, "array bound");
                    529: }
                    530: 
                    531: /*
                    532:  * The SYM 'sp' has storage class C_STAG or C_UTAG.
                    533:  * A new declaration has been encountered which is of the wrong class.
                    534:  * Print a diagnostic giving the name of the tag and its previous class.
                    535:  */
                    536: tagmismatch(sp)
                    537: register SYM   *sp;
                    538: {
                    539:        register char   *p;
                    540: 
                    541:        p = (sp->s_class == C_UTAG) ? "union" : "structure";
                    542:        cerror("\"%s\" is a %s tag", sp->s_id, p);
                    543: }
                    544: 
                    545: /*
                    546:  * Read a cast.
                    547:  * Return a pointer to a CAST tree node,
                    548:  * or NULL if not a legal cast.
                    549:  */
                    550: TREE *
                    551: cast()
                    552: {
                    553:        register TREE   *tp;
                    554:        DIM             *dp;
                    555:        INFO            *ip;
                    556:        DIM             *cast1();
                    557:        int             rf;
                    558:        int             c, t;
                    559: 
                    560:        gcandt(&c, &t, &dp, &ip, &rf);
                    561:        if (c==C_NONE && t==T_NONE && rf==0)
                    562:                return NULL;
                    563:        if (rf != 0 || c != C_NONE)
                    564:                cerror("storage class not allowed in cast");
                    565:        if (t == T_NONE) {
                    566:                cerror("type required in cast");
                    567:                t = T_INT;
                    568:        }
                    569:        dp = cast1(dp);
                    570:        if (t==T_VOID && dp!=NULL && !isfunction(dp)) {
                    571:                cerror("illegal use of void type in cast");
                    572:                t = T_INT;
                    573:        }
                    574:        mustbe(RPAREN);
                    575:        tp = talloc();
                    576:        tp->t_op = CAST;
                    577:        tp->t_type = t;
                    578:        tp->t_dp = dp;
                    579:        tp->t_ip = ip;
                    580:        xdropinfo(t, ip);
                    581:        return tp;
                    582: }
                    583: 
                    584: /* this is the cast version of gdecl() */
                    585: DIM *
                    586: cast1(tdp)
                    587: DIM    *tdp;
                    588: {
                    589:        register DIM    *dp;
                    590:        register sizeof_t b;
                    591:        DIM             *cast2();
                    592: 
                    593:        while (s == CONST || s == VOLATILE) {
                    594:                lex();
                    595:        }
                    596:        if (s == MUL) {
                    597:                lex();
                    598:                dp = cast2(cast1(NULL), D_PTR, (sizeof_t)0);
                    599:        } else {
                    600:                dp = NULL;
                    601:                if (s == LPAREN) {
                    602:                        lex();
                    603:                        if (s != RPAREN) {
                    604:                                dp = cast1(NULL);
                    605:                                mustbe(RPAREN);
                    606:                        } else {
                    607:                                lex();
                    608:                                dp = cast2(dp, D_FUNC, (sizeof_t)0);
                    609:                        }
                    610:                }
                    611:        again:
                    612:                if (s == LPAREN) {
                    613:                        DIM *tdp;
                    614:                        lex();
                    615:                        tdp = dp;
                    616:                        cproto(&tdp);
                    617:                        dp = tdp;
                    618:                        mustbe(RPAREN);
                    619:                        goto again;
                    620:                }
                    621:                if (s == LBRACK) {
                    622:                        lex();
                    623:                        b = 0;
                    624:                        if (s != RBRACK)
                    625:                                b = getbound();
                    626:                        mustbe(RBRACK);
                    627:                        dp = cast2(dp, D_ARRAY, b);
                    628:                        goto again;
                    629:                }
                    630:        }
                    631:        while (tdp != NULL) {
                    632:                dp = cast2(dp, tdp->d_type, tdp->d_bound);
                    633:                tdp = tdp->d_dp;
                    634:        }
                    635:        return dp;
                    636: }
                    637: 
                    638: /* this is the cast version of tackdim() */
                    639: DIM *
                    640: cast2(dp, t, b)
                    641: DIM    *dp;
                    642: int    t;
                    643: sizeof_t b;
                    644: {
                    645:        register DIM    *dp1, *dp2;
                    646: 
                    647:        dp1 = (struct dim *) talloc();
                    648:        dp1->d_dp = NULL;
                    649:        dp1->d_type = t;
                    650:        dp1->d_bound = b;
                    651:        if ((dp2 = dp) == NULL)
                    652:                return dp1;
                    653:        while (dp2->d_dp != NULL)
                    654:                dp2 = dp2->d_dp;
                    655:        dp2->d_dp = dp1;
                    656:        return dp;
                    657: }
                    658: 
                    659: cproto(adp) DIM **adp;
                    660: {
                    661:        *adp = cast2(*adp, D_FUNC, (sizeof_t)0);
                    662: }
                    663: 
                    664: /* end of n0/gdecl.c */

unix.superglobalmegacorp.com

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