Annotation of researchv10no/cmd/lcc/c/main.c, revision 1.1.1.1

1.1       root        1: /* C compiler: main program */
                      2: 
                      3: #include "version.h"
                      4: #include "c.h"
                      5: 
                      6: Interface *IR;
                      7: 
                      8: int Aflag;                     /* >= 0 if -A specified */
                      9: int Pflag;                     /* != 0 if -P specified */
                     10: int glevel;                    /* == [0-9] if -g[0-9] specified */
                     11: int xref;                      /* != 0 for cross-reference data */
                     12: Symbol YYnull;                 /* symbol for _YYnull if -n specified */
                     13: 
                     14: static char *infile;           /* input file */
                     15: static char *outfile;          /* output file */
                     16: static char *progname;         /* argv[0] */
                     17: 
                     18: List loci, tables;             /* current (locus,table) lists */
                     19: 
                     20: dclproto(static void compile,(char *));
                     21: dclproto(static int doargs,(int, char **));
                     22: dclproto(static void emitYYnull,(void));
                     23: dclproto(static Type ftype,(Type, Type));
                     24: dclproto(static void typestab,(Symbol, Generic));
                     25: 
                     26: int main(argc, argv) char *argv[]; {
                     27:        Symbol symroot = 0;             /* root of the global symbols */
                     28:        static Events z;
                     29:        int i, infd = 0, outfd = 1;
                     30: 
                     31:        assert(MAXKIDS >= 2);
                     32:        assert(MAXSYMS >= 2);
                     33:        progname = argv[0];
                     34:        level = GLOBAL;
                     35:        IR = interfaces[0];
                     36:        for (i = 1; i < argc; i++)
                     37:                if (strncmp(argv[i], "target=", 7) == 0) {
                     38:                        int k;
                     39:                        for (k = 0; interfaces[k]; k++)
                     40:                                if (strcmp(&argv[i][7], interfaces[k]->target) == 0)
                     41:                                        break;
                     42:                        if (interfaces[k])
                     43:                                IR = interfaces[k];
                     44:                        else
                     45:                                fprint(2, "%s: unknown target `%s'\n", argv[0], &argv[i][7]);
                     46:                }
                     47:        assert(IR);
                     48:        typeInit();
                     49:        assert(inttype->size >= voidptype->size);
                     50:        argc = doargs(argc, argv);
                     51:        if (infile && *infile != '-') {
                     52:                close(infd);
                     53:                if ((infd = open(infile, 0)) < 0) {
                     54:                        fprint(2, "%s: can't read %s\n", argv[0], infile);
                     55:                        exit(1);
                     56:                }
                     57:        }
                     58:        if (outfile && *outfile != '-') {
                     59:                close(outfd);
                     60:                if ((outfd = creat(outfile, 0666)) < 0) {
                     61:                        fprint(2, "%s: can't write %s\n", argv[0], outfile);
                     62:                        exit(1);
                     63:                }
                     64:        }
                     65:        inputInit(infd);
                     66:        outputInit(outfd);
                     67:        t = gettok();
                     68:        (*IR->progbeg)(argc, argv);
                     69:        if (glevel && IR->stabinit)
                     70:                (*IR->stabinit)(firstfile, argc, argv);
                     71:        program();
                     72:        if (events.end)
                     73:                apply(events.end, (Generic)0, (Generic)0);
                     74:        events = z;
                     75:        emitYYnull();
                     76:        finalize();
                     77:        if (glevel || xref) {
                     78:                Coordinate src;
                     79:                foreach(types, GLOBAL, typestab, (Generic)&symroot);
                     80:                foreach(identifiers, GLOBAL, typestab, (Generic)&symroot);
                     81:                src.file = firstfile;
                     82:                src.x = 0;
                     83:                src.y = lineno;
                     84:                if ((glevel > 2 || xref) && IR->stabend)
                     85:                        (*IR->stabend)(&src, symroot, (Coordinate **)ltoa(append((Generic)0, loci), 0),
                     86:                                (Symbol *)ltoa(append((Generic)0, tables), 0),
                     87:                                symbols ? (Symbol *)ltoa(symbols, 0) : (Symbol *)0);
                     88:                else if (IR->stabend)
                     89:                        (*IR->stabend)(&src, 0, 0, 0, 0);
                     90:        }
                     91:        (*IR->progend)();
                     92:        outflush();
                     93:        exit(errcnt > 0);
                     94:        return 0;
                     95: }
                     96: 
                     97: /* compile - compile str */
                     98: static void compile(str) char *str; {
                     99:        inputstring(str);
                    100:        t = gettok();
                    101:        program();
                    102: }
                    103: 
                    104: /* doargs - process program arguments, removing top-half arguments from argv */
                    105: static int doargs(argc, argv) char *argv[]; {
                    106:        char *s;
                    107:        int i, j, x;
                    108:        Symbol p;
                    109: 
                    110:        for (i = j = 1; i < argc; i++)
                    111:                if (strcmp(argv[i], "-g") == 0)
                    112:                        glevel = 2;
                    113:                else if (strncmp(argv[i], "-g", 2) == 0
                    114:                && argv[i][2] && argv[i][2] >= '0' && argv[i][2] <= '9')
                    115:                        glevel = argv[i][2] - '0';
                    116:                else if (strcmp(argv[i], "-x") == 0)
                    117:                        xref++;
                    118:                else if (strcmp(argv[i], "-A") == 0)
                    119:                        Aflag++;
                    120:                else if (strcmp(argv[i], "-P") == 0)
                    121:                        Pflag++;
                    122:                else if (strcmp(argv[i], "-w") == 0)
                    123:                        wflag++;
                    124:                else if (strcmp(argv[i], "-b") == 0 || strcmp(argv[i], "-C") == 0
                    125:                || strncmp(argv[i], "-a", 2) == 0)
                    126:                        bbinit(argv[i]);
                    127:                else if (strcmp(argv[i], "-n") == 0) {
                    128:                        if (!YYnull) {
                    129:                                YYnull = mksymbol(EXTERN, "_YYnull", ftype(voidtype, inttype));
                    130:                                YYnull->sclass = STATIC;
                    131:                        }
                    132:                } else if (strncmp(argv[i], "-t", 2) == 0)
                    133:                        traceinit(&argv[i][2]);
                    134:                else if (strcmp(argv[i], "-v") == 0)
                    135:                        fprint(2, "%s target='%s' version %d.%d\n", progname, IR->target,
                    136:                                VERSION>>8, VERSION&0xff);
                    137:                else if (strncmp(argv[i], "-s", 2) == 0)
                    138:                        density = strtod(&argv[i][2], (char **)0);
                    139:                else if (strncmp(argv[i], "-e", 2) == 0) {
                    140:                        if ((x = strtol(&argv[i][2], (char **)0, 0)) > 0)
                    141:                                errlimit = x;
                    142:                } else if (strncmp(argv[i], "target=", 7) == 0)
                    143:                        ;
                    144:                else if (strcmp(argv[i], "-nodag") == 0)
                    145:                        IR->no_dag = !IR->no_dag;
                    146:                else if (strcmp(argv[i], "-") == 0 || *argv[i] != '-') {
                    147:                        if (infile == 0)
                    148:                                infile = argv[i];
                    149:                        else if (outfile == 0)
                    150:                                outfile = argv[i];
                    151:                        else
                    152:                                argv[j++] = argv[i];
                    153:                } else {
                    154:                        if (strcmp(argv[i], "-XP") == 0)
                    155:                                argv[i] = "-p";
                    156:                        else if (strncmp(argv[i], "-X", 2) == 0)
                    157:                                *++argv[i] = '-';
                    158:                        argv[j++] = argv[i];
                    159:                }
                    160:        argv[j] = 0;
                    161:        return j;
                    162: }
                    163: 
                    164: /* emitYYnull - compile definition for _YYnull, if referenced */
                    165: static void emitYYnull() {
                    166:        if (YYnull && YYnull->ref) {
                    167:                Aflag = 0;
                    168:                YYnull->defined = 0;
                    169:                YYnull = 0;
                    170:                compile(stringf("static char *_YYfile = \"%s\";\n", file));
                    171:                compile("static void _YYnull(int line,...) {\n\
                    172:        char buf[200];\n\
                    173:        sprintf(buf, \"null pointer dereferenced @%s:%d\\n\", _YYfile, line);\n\
                    174:        write(2, buf, strlen(buf));\n\
                    175:        abort();\n\
                    176: }\n");
                    177:        } else if (YYnull)
                    178:                YYnull->ref = 1;
                    179: }
                    180: 
                    181: /* ftype - return a function type for `rty function (ty,...)' */
                    182: static Type ftype(rty, ty) Type rty, ty; {
                    183:        List list = append(ty, 0);
                    184: 
                    185:        list = append(voidtype, list);
                    186:        return func(rty, (Type *)ltoa(list, (Generic *)alloc((length(list) + 1)*sizeof (Type))), 0);
                    187: }
                    188: 
                    189: /* mkstr - make a string constant */
                    190: Symbol mkstr(str) char *str; {
                    191:        Value v;
                    192:        Symbol p;
                    193: 
                    194:        v.p = str;
                    195:        p = constant(array(chartype, strlen(v.p) + 1, 0), v);
                    196:        if (p->u.c.loc == 0)
                    197:                p->u.c.loc = genident(STATIC, p->type, GLOBAL);
                    198:        return p;
                    199: }
                    200: 
                    201: /* mksymbol - make a symbol for name, install in &globals if sclass==EXTERN */
                    202: Symbol mksymbol(sclass, name, ty) char *name; Type ty; {
                    203:        Symbol p;
                    204: 
                    205:        if (sclass == EXTERN)
                    206:                p = install(string(name), &globals, 1);
                    207:        else {
                    208:                p = (Symbol)alloc(sizeof *p);
                    209:                BZERO(p, struct symbol);
                    210:                p->name = string(name);
                    211:                p->scope = GLOBAL;
                    212:        }
                    213:        p->sclass = sclass;
                    214:        p->type = ty;
                    215:        (*IR->defsymbol)(p);
                    216:        p->defined = 1;
                    217:        return p;
                    218: }
                    219: 
                    220: /* typestab - emit stab entries for p */
                    221: static void typestab(p, cl) Symbol p; Generic cl; {
                    222:        if (*(Symbol *)cl == 0 && p->sclass && p->sclass != TYPEDEF)
                    223:                *(Symbol *)cl = p;
                    224:        if ((p->sclass == TYPEDEF || p->sclass == 0) && IR->stabtype)
                    225:                (*IR->stabtype)(p);
                    226: }
                    227: 
                    228: struct callsite {
                    229:        char *file, *name;
                    230:        union coordinate {
                    231:                unsigned int coord;
                    232:                struct { unsigned int y:16,x:10,index:6; } le;
                    233:                struct { unsigned int index:6,x:10,y:16; } be;
                    234:        } u;
                    235: };
                    236: struct func {
                    237:        struct func *link;
                    238:        struct caller *callers;
                    239:        char *name;
                    240:        union coordinate src;
                    241: };
                    242: struct map {           /* source code map; 200 coordinates/map */
                    243:        int size;
                    244:        union coordinate u[200];
                    245: };
                    246: int npoints;           /* # of execution points if -b specified */
                    247: int ncalled = -1;      /* #times prof.out says current function was called */
                    248: static Symbol YYlink;  /* symbol for file's struct _bbdata */
                    249: static Symbol YYcounts;        /* symbol for _YYcounts if -b specified */
                    250: static List maplist;   /* list of struct map *'s */
                    251: static List filelist;  /* list of file names */
                    252: static Symbol funclist;        /* list of struct func *'s */
                    253: static Symbol afunc;   /* current function's struct func */
                    254: 
                    255: dclproto(static void bbcall,(Symbol, Coordinate *, Tree *));
                    256: dclproto(static void bbentry,(Symbol, Symbol));
                    257: dclproto(static void bbexit,(Symbol, Symbol, Tree));
                    258: dclproto(static int bbfile,(char *));
                    259: dclproto(static void bbfunc,(Symbol, Symbol));
                    260: dclproto(static void bbincr,(Symbol, Coordinate *, Tree *));
                    261: dclproto(static void bbvars,(Symbol));
                    262: 
                    263: /* bbcall - build tree to set _callsite at call site *cp, emit call site data */
                    264: static void bbcall(yycounts, cp, e) Symbol yycounts; Coordinate *cp; Tree *e; {
                    265:        static Symbol caller;
                    266:        Value v;
                    267:        union coordinate u;
                    268:        Symbol p = genident(STATIC, array(voidptype, 0, 0), GLOBAL);
                    269: 
                    270:        defglobal(p, LIT);
                    271:        defpointer(cp->file ? mkstr(cp->file)->u.c.loc : (Symbol)0);
                    272:        defpointer(mkstr(cfunc->name)->u.c.loc);
                    273:        if (IR->little_endian) {
                    274:                u.le.x = cp->x;
                    275:                u.le.y = cp->y;
                    276:        } else {
                    277:                u.be.x = cp->x;
                    278:                u.be.y = cp->y;
                    279:        }
                    280:        (*IR->defconst)(U, (v.u = u.coord, v));
                    281:        if (caller == 0)
                    282:                caller = mksymbol(EXTERN, "_caller", ptr(voidptype));
                    283:        *e = right(asgn(caller, idnode(p)), *e);
                    284: }
                    285: 
                    286: /* bbentry - return tree for `_prologue(&afunc, &YYlink)' */
                    287: static void bbentry(yylink, f) Symbol yylink, f; {
                    288:        static Symbol p;
                    289:        
                    290:        afunc = genident(STATIC, array(voidptype, 4, 0), GLOBAL);
                    291:        if (p == 0)
                    292:                p = mksymbol(EXTERN, "_prologue", ftype(inttype, voidptype));
                    293:        walk(callnode(pointer(idnode(p)), freturn(p->type),
                    294:                tree(ARG+P, ptr(unsignedtype), idnode(yylink),
                    295:                tree(ARG+P, ptr(unsignedtype), idnode(afunc), 0))), 0, 0);
                    296: }
                    297: 
                    298: /* bbexit - return tree for `_epilogue(&afunc)' */
                    299: static void bbexit(yylink, f, e) Symbol yylink, f; Tree e; {
                    300:        static Symbol p;
                    301:        
                    302:        if (p == 0)
                    303:                p = mksymbol(EXTERN, "_epilogue", ftype(inttype, voidptype));
                    304:        walk(callnode(pointer(idnode(p)), freturn(p->type),
                    305:                tree(ARG+P, ptr(unsignedtype), idnode(afunc), 0)), 0, 0);
                    306: }
                    307: 
                    308: /* bbfile - add file to list of file names, return its index */
                    309: static int bbfile(file) char *file; {
                    310:        if (file) {
                    311:                List lp;
                    312:                int i = 1;
                    313:                if (lp = filelist)
                    314:                        do {
                    315:                                lp = lp->link;
                    316:                                if (((Symbol)lp->x)->u.c.v.p == file)
                    317:                                        return i;
                    318:                                i++;
                    319:                        } while (lp != filelist);
                    320:                filelist = append(mkstr(file), filelist);
                    321:                return i;
                    322:        }
                    323:        return 0;
                    324: }
                    325: 
                    326: /* bbfunc - emit function name and src coordinates */
                    327: static void bbfunc(yylink, f) Symbol yylink, f; {
                    328:        Value v;
                    329:        union coordinate u;
                    330: 
                    331:        defglobal(afunc, DATA);
                    332:        defpointer(funclist);
                    333:        defpointer(0);
                    334:        defpointer(mkstr(f->name)->u.c.loc);
                    335:        if (IR->little_endian) {
                    336:                u.le.x = f->u.f.pt[2].x;
                    337:                u.le.y = f->u.f.pt[2].y;
                    338:                u.le.index = bbfile(f->u.f.pt[2].file);
                    339:        } else {
                    340:                u.be.x = f->u.f.pt[2].x;
                    341:                u.be.y = f->u.f.pt[2].y;
                    342:                u.be.index = bbfile(f->u.f.pt[2].file);
                    343:        }
                    344:        (*IR->defconst)(U, (v.u = u.coord, v));
                    345:        funclist = afunc;
                    346: }
                    347: 
                    348: /* bbincr - build tree to increment execution point at *cp */
                    349: static void bbincr(yycounts, cp, e) Symbol yycounts; Coordinate *cp; Tree *e; {
                    350:        struct map *mp = (struct map *)maplist->x;
                    351: 
                    352:        /* append *cp to source map */
                    353:        if (mp->size >= sizeof mp->u/sizeof mp->u[0]) {
                    354:                mp = (struct map *)alloc(sizeof *mp);
                    355:                mp->size = 0;
                    356:                maplist = append((Generic *)mp, maplist);
                    357:        }
                    358:        if (IR->little_endian) {
                    359:                mp->u[mp->size].le.x = cp->x;
                    360:                mp->u[mp->size].le.y = cp->y;
                    361:                mp->u[mp->size++].le.index = bbfile(cp->file);
                    362:        } else {
                    363:                mp->u[mp->size].be.x = cp->x;
                    364:                mp->u[mp->size].be.y = cp->y;
                    365:                mp->u[mp->size++].be.index = bbfile(cp->file);
                    366:        }
                    367:        *e = right(incr('+', rvalue((*opnode['+'])(ADD, pointer(idnode(yycounts)),
                    368:                constnode(npoints++, inttype))), constnode(1, inttype)), *e);
                    369: }
                    370: 
                    371: /* bbinit - initialize basic block counting options */
                    372: void bbinit(opt) char *opt; {
                    373:        if (strncmp(opt, "-a", 2) == 0) {
                    374:                if (ncalled == -1 && process(opt[2] ? &opt[2] : "prof.out") > 0)
                    375:                        ncalled = 0;
                    376:        } else if ((strcmp(opt, "-b") == 0 || strcmp(opt, "-C") == 0) && YYlink == 0) {
                    377:                YYlink = genident(STATIC, array(unsignedtype, 0, 0), GLOBAL);
                    378:                attach((Apply)bbentry, (Generic)YYlink, &events.entry);
                    379:                attach((Apply)bbexit,  (Generic)YYlink, &events.returns);
                    380:                attach((Apply)bbfunc,  (Generic)YYlink, &events.exit);
                    381:                attach((Apply)bbvars,  (Generic)YYlink, &events.end);
                    382:                if (strcmp(opt, "-b") == 0) {
                    383:                        YYcounts = genident(STATIC, array(unsignedtype, 0, 0), GLOBAL);
                    384:                        maplist = append((Generic)alloc(sizeof(struct map)), maplist);
                    385:                        ((struct map *)maplist->x)->size = 0;
                    386:                        attach((Apply)bbcall, (Generic)YYcounts, &events.calls);
                    387:                        attach((Apply)bbincr, (Generic)YYcounts, &events.points);
                    388:                }
                    389:        }
                    390: }
                    391: 
                    392: /* bbvars - emit definition for basic block counting data */
                    393: static void bbvars(yylink) Symbol yylink; {
                    394:        int i, j, n = npoints;
                    395:        Value v;
                    396:        struct map **mp;
                    397:        Symbol coords, files, *p;
                    398: 
                    399:        if (!YYcounts && !yylink)
                    400:                return;
                    401:        if (YYcounts) {
                    402:                if (n <= 0)
                    403:                        n = 1;
                    404:                defglobal(YYcounts, BSS);
                    405:                (*IR->space)(n*YYcounts->type->type->size);
                    406:        }
                    407:        files = genident(STATIC, array(ptr(chartype), 1, 0), GLOBAL);
                    408:        defglobal(files, LIT);
                    409:        for (p = (Symbol *)ltoa(filelist, 0); *p; p++)
                    410:                defpointer((*p)->u.c.loc);
                    411:        defpointer(0);
                    412:        coords = genident(STATIC, array(unsignedtype, n, 0), GLOBAL);
                    413:        defglobal(coords, LIT);
                    414:        for (i = n, mp = (struct map **)ltoa(maplist, 0); *mp; i -= (*mp)->size, mp++)
                    415:                for (j = 0; j < (*mp)->size; j++)
                    416:                        (*IR->defconst)(U, (v.u = (*mp)->u[j].coord, v));
                    417:        if (i > 0)
                    418:                (*IR->space)(i*coords->type->type->size);
                    419:        defpointer(0);
                    420:        defglobal(yylink, DATA);
                    421:        defpointer(0);
                    422:        (*IR->defconst)(U, (v.u = n, v));
                    423:        defpointer(YYcounts);
                    424:        defpointer(coords);
                    425:        defpointer(files);
                    426:        defpointer(funclist);
                    427: }
                    428: 
                    429: static char *fmt, *fp, *fmtend;        /* format string, current & limit pointer */
                    430: static Tree args;              /* printf arguments */
                    431: static Symbol frameno;         /* local holding frame number */
                    432: 
                    433: dclproto(static void appendstr,(char *));
                    434: dclproto(static void tracecall,(Symbol, Symbol));
                    435: dclproto(static void tracefinis,(Symbol));
                    436: dclproto(static void tracereturn,(Symbol, Symbol, Tree));
                    437: dclproto(static void tracevalue,(Tree, int));
                    438: 
                    439: /* appendstr - append str to the evolving format string, expanding it if necessary */
                    440: static void appendstr(str) char *str; {
                    441:        do
                    442:                if (fp == fmtend)
                    443:                        if (fp) {
                    444:                                char *s = (char *)talloc(2*(fmtend - fmt));
                    445:                                strncpy(s, fmt, fmtend - fmt);
                    446:                                fp = s + (fmtend - fmt);
                    447:                                fmtend = s + 2*(fmtend - fmt);
                    448:                                fmt = s;
                    449:                        } else {
                    450:                                fp = fmt = (char *)talloc(80);
                    451:                                fmtend = fmt + 80;
                    452:                        }
                    453:        while (*fp++ = *str++);
                    454:        fp--;
                    455: }
                    456: 
                    457: /* tracecall - generate code to trace entry to f */
                    458: static void tracecall(printer, f) Symbol printer, f; {
                    459:        int i;
                    460:        Symbol counter = genident(STATIC, inttype, GLOBAL);
                    461: 
                    462:        defglobal(counter, BSS);
                    463:        (*IR->space)(counter->type->size);
                    464:        frameno = genident(AUTO, inttype, level);
                    465:        addlocal(frameno);
                    466:        appendstr(f->name); appendstr("#");
                    467:        tracevalue(asgn(frameno, incr(INCR, idnode(counter), constnode(1, inttype))), 0);
                    468:        appendstr("(");
                    469:        for (i = 0; f->u.f.callee[i]; i++) {
                    470:                if (i)
                    471:                        appendstr(",");
                    472:                appendstr(f->u.f.callee[i]->name); appendstr("=");
                    473:                tracevalue(idnode(f->u.f.callee[i]), 0);
                    474:        }
                    475:        if (variadic(f->type))
                    476:                appendstr(",...");
                    477:        appendstr(") called\n");
                    478:        tracefinis(printer);
                    479: }
                    480: 
                    481: /* tracefinis - complete & generate the trace call to print */
                    482: static void tracefinis(printer) Symbol printer; {
                    483:        Tree *ap;
                    484:        Symbol p;
                    485: 
                    486:        *fp = 0;
                    487:        p = mkstr(string(fmt));
                    488:        for (ap = &args; *ap; ap = &(*ap)->kids[1])
                    489:                ;
                    490:        *ap = tree(ARG+P, ptr(chartype), pointer(idnode(p->u.c.loc)), 0);
                    491:        walk(callnode(pointer(idnode(printer)), freturn(printer->type), args), 0, 0);
                    492:        args = 0;
                    493:        fp = fmtend = 0;
                    494: }
                    495: 
                    496: /* traceinit - initialize for tracing */
                    497: void traceinit(print) char *print; {
                    498:        static Symbol printer;
                    499: 
                    500:        if (!printer) {
                    501:                printer = mksymbol(STATIC, print && *print ? print : "printf",
                    502:                        ftype(voidtype, ptr(chartype)));
                    503:                printer->sclass = EXTERN;
                    504:                attach((Apply)tracecall,   (Generic)printer, &events.entry);
                    505:                attach((Apply)tracereturn, (Generic)printer, &events.returns);
                    506:        }
                    507: }
                    508: 
                    509: /* tracereturn - generate code to trace return e */
                    510: static void tracereturn(printer, f, e) Symbol printer, f; Tree e; {
                    511:        appendstr(f->name); appendstr("#");
                    512:        tracevalue(idnode(frameno), 0);
                    513:        appendstr(" returned");
                    514:        if (freturn(f->type) != voidtype && e) {
                    515:                appendstr(" ");
                    516:                tracevalue(e, 0);
                    517:        }
                    518:        appendstr("\n");
                    519:        tracefinis(printer);
                    520: }
                    521: 
                    522: /* tracevalue - append format and argument to print the value of e */
                    523: static void tracevalue(e, lev) Tree e; {
                    524:        Type ty = unqual(e->type);
                    525: 
                    526:        switch (ty->op) {
                    527:        case CHAR:
                    528:                appendstr("'\\x%2x'");
                    529:                break;
                    530:        case SHORT:
                    531:                if (ty == unsignedshort)
                    532:                        appendstr("0x%x");
                    533:                else /* fall thru */
                    534:        case INT:
                    535:                        appendstr("%d");
                    536:                break;
                    537:        case UNSIGNED:
                    538:                appendstr("0x%x");
                    539:                break;
                    540:        case FLOAT: case DOUBLE:
                    541:                appendstr("%g");
                    542:                break;
                    543:        case POINTER:
                    544:                if (unqual(ty->type) == chartype) {
                    545:                        static Symbol null;
                    546:                        if (null == 0)
                    547:                                null = mkstr("(null)");
                    548:                        tracevalue(constnode(0, unsignedtype), lev + 1);
                    549:                        appendstr(" \"%s\"");
                    550:                        e = condnode(e, e, pointer(idnode(null->u.c.loc)));
                    551:                } else {
                    552:                        appendstr("("); appendstr(typestring(ty, "")); appendstr(")0x%x");
                    553:                }
                    554:                break;
                    555:        case STRUCT: {
                    556:                Field q;
                    557:                appendstr("("); appendstr(typestring(ty, "")); appendstr("){");
                    558:                for (q = ty->u.sym->u.s.flist; q; q = q->link) {
                    559:                        appendstr(q->name); appendstr("=");
                    560:                        tracevalue(field(addrof(e), q->name), lev + 1);
                    561:                        if (q->link)
                    562:                                appendstr(",");
                    563:                }
                    564:                appendstr("}");
                    565:                return;
                    566:                }
                    567:        case UNION:
                    568:                appendstr("("); appendstr(typestring(ty, "")); appendstr("){...}");
                    569:                return;
                    570:        case ARRAY:
                    571:                if (lev && ty->type->size > 0) {
                    572:                        int i;
                    573:                        e = pointer(e);
                    574:                        appendstr("{");
                    575:                        for (i = 0; i < ty->size/ty->type->size; i++) {
                    576:                                Tree p = (*opnode['+'])(ADD, e, constnode(i, inttype));
                    577:                                if (isptr(p->type) && isarray(p->type->type))
                    578:                                        p = retype(p, p->type->type);
                    579:                                else
                    580:                                        p = rvalue(p);
                    581:                                if (i)
                    582:                                        appendstr(",");
                    583:                                tracevalue(p, lev + 1);
                    584:                        }
                    585:                        appendstr("}");
                    586:                } else
                    587:                        appendstr(typestring(ty, ""));
                    588:                return;
                    589:        default:
                    590:                assert(0);
                    591:        }
                    592:        if (ty == floattype)
                    593:                e = cast(e, doubletype);
                    594:        else if ((isint(ty) || isenum(ty)) && ty->size != inttype->size)
                    595:                e = cast(e, promote(ty));
                    596:        args = tree(ARG + widen(e->type), e->type, e, args);
                    597: }
                    598: Events events;
                    599: 
                    600: struct entry {
                    601:        Apply func;
                    602:        Generic cl;
                    603: };
                    604: 
                    605: void attach(func, cl, list) Apply func; Generic cl; List *list; {
                    606:        struct entry *p = (struct entry *)alloc(sizeof *p);
                    607: 
                    608:        p->func = func;
                    609:        p->cl = cl;
                    610:        *list = append((Generic)p, *list);
                    611: }
                    612: void apply(list, arg1, arg2) List list; Generic arg1, arg2; {
                    613:        if (list) {
                    614:                List lp = list;
                    615:                do {
                    616:                        struct entry *p = (struct entry *)lp->x;
                    617:                        (*p->func)(p->cl, arg1, arg2);
                    618:                        lp = lp->link;
                    619:                } while (lp != list);
                    620:        }
                    621: }

unix.superglobalmegacorp.com

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