2html.c (11130B)
1 #include <assert.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <time.h> 6 #include "c.h" 7 #include "rcc.h" 8 #if WIN32 9 #include <fcntl.h> 10 #include <io.h> 11 #endif 12 13 14 static void do_int(int x) { 15 printf("%d", x); 16 } 17 18 static void do_scope(int x) { 19 #define xx(c) if (x == c) { printf(#c); return; } 20 xx(CONSTANTS) 21 xx(LABELS) 22 xx(GLOBAL) 23 xx(PARAM) 24 xx(LOCAL) 25 #undef xx 26 if (x > LOCAL) 27 printf("LOCAL+%d", x-LOCAL); 28 else 29 do_int(x); 30 } 31 32 static void do_sclass(int x) { 33 #define xx(c) if (x == c) { printf(#c); return; } 34 xx(REGISTER) 35 xx(AUTO) 36 xx(EXTERN) 37 xx(STATIC) 38 xx(TYPEDEF) 39 #undef xx 40 do_int(x); 41 } 42 43 static void do_flags(int x) { 44 char *bar = ""; 45 #define xx(f,n) if ((x>>n)&1) { printf("%s" #f, bar); bar = "|"; } 46 xx(structarg,0) 47 xx(addressed,1) 48 xx(computed,2) 49 xx(temporary,3) 50 xx(generated,4) 51 #undef xx 52 if (*bar == '\0') 53 do_int(x); 54 } 55 56 static void do_seg(int x) { 57 #define xx(s) if (x == s) { printf(#s); return; } 58 xx(CODE) 59 xx(BSS) 60 xx(DATA) 61 xx(LIT) 62 #undef xx 63 do_int(x); 64 } 65 66 #define xx(ptr,field,type) do { printf("<li>" #field " = "); do_##type(ptr->field); printf("</li>\n"); } while (0) 67 68 static void do_op(int x) { 69 static char *opnames[] = { 70 "", 71 "CNST", 72 "ARG", 73 "ASGN", 74 "INDIR", 75 "CVC", 76 "CVD", 77 "CVF", 78 "CVI", 79 "CVP", 80 "CVS", 81 "CVU", 82 "NEG", 83 "CALL", 84 "*LOAD*", 85 "RET", 86 "ADDRG", 87 "ADDRF", 88 "ADDRL", 89 "ADD", 90 "SUB", 91 "LSH", 92 "MOD", 93 "RSH", 94 "BAND", 95 "BCOM", 96 "BOR", 97 "BXOR", 98 "DIV", 99 "MUL", 100 "EQ", 101 "GE", 102 "GT", 103 "LE", 104 "LT", 105 "NE", 106 "JUMP", 107 "LABEL", 108 "AND", 109 "NOT", 110 "OR", 111 "COND", 112 "RIGHT", 113 "FIELD" 114 }; 115 int op = opindex(x); 116 if (op < 1 || op >= sizeof opnames/sizeof opnames[0]) 117 printf("%d", x); 118 else 119 printf("%s", opnames[op]); 120 } 121 122 static void do_define_uid(int x) { 123 printf("<strong id=uid%d>%d</strong>", x, x); 124 } 125 126 static void do_define_label(int x) { 127 printf("<strong id=ll%d>%d</strong>", x, x); 128 } 129 130 static void do_uid(int x) { 131 printf("<a href='#%d'>%d</a>", x, x, x); 132 } 133 134 static void do_label(int x) { 135 printf("<a href='#L%d'>%d</a>", x, x, x); 136 } 137 138 static int nextid; 139 140 static void do_list(list_ty x, void do_one(void *), char *type, char *listhtml, char *separator) { 141 int count = Seq_length(x); 142 143 if (count == 0) 144 printf("<em>empty %s list</em>\n", type); 145 else { 146 int i; 147 printf("<em>%s list</em>", type); 148 if (listhtml != NULL) 149 printf("<%s>\n", listhtml); 150 for (i = 0; i < count; i++) { 151 if (listhtml != NULL) 152 printf("<li>"); 153 printf(separator); 154 do_one(Seq_get(x, i)); 155 if (listhtml != NULL) 156 printf("</li>\n"); 157 } 158 if (listhtml != NULL) 159 printf("</%s>\n", listhtml); 160 } 161 } 162 163 static void do_uid_list(list_ty x) { 164 int i, count = Seq_length(x); 165 166 if (count == 0) 167 printf("<em>empty int list</em>\n"); 168 else { 169 int i; 170 printf("<em>int list</em>"); 171 for (i= 0; i < count; i++) { 172 printf(" "); 173 do_uid(*(int *)Seq_get(x, i)); 174 } 175 } 176 } 177 178 static void do_identifier(const char *x) { 179 printf("%s", x); 180 } 181 182 static void do_real(rcc_real_ty x) { 183 double d; 184 unsigned *p = (unsigned *)&d; 185 static union { int x; char endian; } little = { 1 }; 186 187 p[1-little.endian] = x->msb; 188 p[little.endian] = x->lsb; 189 printf("(%#X,%#X) = %g", x->msb, x->lsb, d); 190 } 191 192 static void do_suffix(int x) { 193 static char suffixes[] = "0F234IUPVB"; 194 195 if (x < 0 || x >= (sizeof suffixes/sizeof suffixes[0]) - 1) 196 printf("%d", x); 197 else 198 printf("%c", suffixes[x]); 199 } 200 201 static void do_enum(void *x) { 202 rcc_enum__ty e = x; 203 204 do_identifier(e->id); 205 printf("="); 206 do_int(e->value); 207 } 208 209 static void do_enum_list(list_ty x) { 210 do_list(x, do_enum, "enum", NULL, " "); 211 } 212 213 static void do_field(void *x) { 214 rcc_field_ty f = x; 215 216 printf("<em>field</em><ul>\n"); 217 xx(f,id,identifier); 218 xx(f,type,uid); 219 xx(f,offset,int); 220 xx(f,bitsize,int); 221 xx(f,lsb,int); 222 printf("</ul>\n"); 223 } 224 225 static void do_field_list(list_ty x) { 226 do_list(x, do_field, "field", "ol", ""); 227 } 228 229 static void do_symbol(rcc_symbol_ty x) { 230 printf("<em>symbol</em><ul>\n"); 231 xx(x,id,identifier); 232 xx(x,type,uid); 233 xx(x,scope,scope); 234 xx(x,sclass,sclass); 235 xx(x,ref,int); 236 xx(x,flags,flags); 237 printf("</ul>\n"); 238 } 239 240 #define caselabel(kind) case rcc_##kind##_enum: \ 241 printf("<strong>" #kind "</strong> : <em>%s</em>", typename); \ 242 printf("<ul>\n"); attributes 243 #define yy(kind,field,type) xx((&x->v.rcc_##kind),field,type) 244 245 static void do_type(rcc_type_ty x) { 246 #define attributes xx(x,size,int); xx(x,align,int) 247 switch (x->kind) { 248 static char *typename = "type"; 249 caselabel(INT); break; 250 caselabel(UNSIGNED); break; 251 caselabel(FLOAT); break; 252 caselabel(VOID); break; 253 caselabel(POINTER); 254 yy(POINTER,type,uid); 255 break; 256 caselabel(ENUM); 257 yy(ENUM,tag,identifier); 258 yy(ENUM,ids,enum_list); 259 break; 260 caselabel(STRUCT); 261 yy(STRUCT,tag,identifier); 262 yy(STRUCT,fields,field_list); 263 break; 264 caselabel(UNION); 265 yy(UNION,tag,identifier); 266 yy(UNION,fields,field_list); 267 break; 268 caselabel(ARRAY); 269 yy(ARRAY,type,uid); 270 break; 271 caselabel(FUNCTION); 272 yy(FUNCTION,type,uid); 273 yy(FUNCTION,formals,uid_list); 274 break; 275 caselabel(CONST); 276 yy(CONST,type,uid); 277 break; 278 caselabel(VOLATILE); 279 yy(VOLATILE,type,uid); 280 break; 281 default: assert(0); 282 } 283 #undef attributes 284 printf("</ul>\n"); 285 } 286 287 static void do_item(rcc_item_ty x) { 288 printf("<a name='%d'>", x->uid); 289 #define attributes xx(x,uid,define_uid) 290 printf("</a>"); 291 switch (x->kind) { 292 static char *typename = "item"; 293 caselabel(Symbol); 294 yy(Symbol,symbol,symbol); 295 break; 296 caselabel(Type); 297 yy(Type,type,type); 298 break; 299 default: assert(0); 300 } 301 #undef attributes 302 printf("</ul>\n"); 303 } 304 305 static void do_item_list(list_ty x) { 306 int count = Seq_length(x); 307 308 if (count == 0) 309 printf("<em>empty item list</em>\n"); 310 else { 311 int i; 312 printf("<em>item list</em>"); 313 printf("<ol>\n"); 314 for (i = 0; i < count; i++) { 315 rcc_item_ty item = Seq_get(x, i); 316 printf("<li value=%d>", item->uid); 317 do_item(item); 318 printf("</li>\n"); 319 } 320 printf("</ol>\n"); 321 } 322 } 323 324 static void do_string(string_ty x) { 325 printf("%d,<code>'%s'</code>", x.len, x.str); 326 } 327 328 static void do_generic_string(void *x) { 329 do_string(*(string_ty *)x); 330 } 331 332 static void do_string_list(list_ty x) { 333 do_list(x, do_generic_string, "string", "ol", ""); 334 } 335 336 static void do_node(void *y) { 337 rcc_node_ty x = y; 338 339 if (x->kind == rcc_LABEL_enum) 340 printf("<a name='L%d'></a>", x->v.rcc_LABEL.label); 341 #define attributes xx(x,suffix,suffix); xx(x,size,int) 342 switch (x->kind) { 343 static char *typename = "node"; 344 caselabel(CNST); 345 yy(CNST,value,int); 346 break; 347 caselabel(CNSTF); 348 yy(CNSTF,value,real); 349 break; 350 caselabel(ARG); 351 yy(ARG,left,node); 352 yy(ARG,len,int); 353 yy(ARG,align,int); 354 break; 355 caselabel(ASGN); 356 yy(ASGN,left,node); 357 yy(ASGN,right,node); 358 yy(ASGN,len,int); 359 yy(ASGN,align,int); 360 break; 361 caselabel(CVT); 362 yy(CVT,op,op); 363 yy(CVT,left,node); 364 yy(CVT,fromsize,int); 365 break; 366 caselabel(CALL); 367 yy(CALL,left,node); 368 yy(CALL,type,uid); 369 break; 370 caselabel(CALLB); 371 yy(CALLB,left,node); 372 yy(CALLB,right,node); 373 yy(CALLB,type,uid); 374 break; 375 caselabel(RET); break; 376 caselabel(ADDRG); 377 yy(ADDRG,uid,uid); 378 break; 379 caselabel(ADDRL); 380 yy(ADDRL,uid,uid); 381 break; 382 caselabel(ADDRF); 383 yy(ADDRF,uid,uid); 384 break; 385 caselabel(Unary); 386 yy(Unary,op,op); 387 yy(Unary,left,node); 388 break; 389 caselabel(Binary); 390 yy(Binary,op,op); 391 yy(Binary,left,node); 392 yy(Binary,right,node); 393 break; 394 caselabel(Compare); 395 yy(Compare,op,op); 396 yy(Compare,left,node); 397 yy(Compare,right,node); 398 yy(Compare,label,label); 399 break; 400 caselabel(LABEL); 401 yy(LABEL,label,define_label); 402 break; 403 caselabel(BRANCH); 404 yy(BRANCH,label,label); 405 break; 406 caselabel(CSE); 407 yy(CSE,uid,uid); 408 yy(CSE,node,node); 409 break; 410 default: assert(0); 411 } 412 #undef attributes 413 printf("</ul>"); 414 } 415 416 static void do_node_list(list_ty x) { 417 do_list(x, do_node, "node", "ol", ""); 418 } 419 420 static void do_interface(void *); 421 422 static void do_interface_list(list_ty x) { 423 do_list(x, do_interface, "interface", "ol", ""); 424 } 425 426 static void do_interface(void *y) { 427 rcc_interface_ty x = y; 428 429 if (x->kind == rcc_Address_enum) 430 printf("<a name='%d'></a>", x->v.rcc_Address.uid); 431 else if (x->kind == rcc_Local_enum) 432 printf("<a name='%d'></a>", x->v.rcc_Local.uid); 433 #define attributes 434 switch (x->kind) { 435 static char *typename = "interface"; 436 caselabel(Export); 437 yy(Export,p,uid); 438 break; 439 caselabel(Import); 440 yy(Import,p,uid); 441 break; 442 caselabel(Global); 443 yy(Global,p,uid); 444 yy(Global,seg,seg); 445 break; 446 caselabel(Local); 447 yy(Local,uid,define_uid); 448 yy(Local,p,symbol); 449 break; 450 caselabel(Address); 451 yy(Address,uid,define_uid); 452 yy(Address,q,symbol); 453 yy(Address,p,uid); 454 yy(Address,n,int); 455 break; 456 caselabel(Segment); 457 yy(Segment,seg,seg); 458 break; 459 caselabel(Defaddress); 460 yy(Defaddress,p,uid); 461 break; 462 caselabel(Deflabel); 463 yy(Deflabel,label,label); 464 break; 465 caselabel(Defconst); 466 yy(Defconst,suffix,suffix); 467 yy(Defconst,size,int); 468 yy(Defconst,value,int); 469 break; 470 caselabel(Defconstf); 471 yy(Defconstf,size,int); 472 yy(Defconstf,value,real); 473 break; 474 caselabel(Defstring); 475 yy(Defstring,s,string); 476 break; 477 caselabel(Space); 478 yy(Space,n,int); 479 break; 480 caselabel(Function); 481 yy(Function,f,uid); 482 yy(Function,caller,uid_list); 483 yy(Function,callee,uid_list); 484 yy(Function,ncalls,int); 485 yy(Function,codelist,interface_list); 486 break; 487 caselabel(Forest); 488 yy(Forest,nodes,node_list); 489 break; 490 case rcc_Blockbeg_enum: printf("<strong>Blockbeg</strong> : <em>%s</em>", typename); return; 491 case rcc_Blockend_enum: printf("<strong>Blockend</strong> : <em>%s</em>", typename); return; 492 default: assert(0); 493 } 494 #undef attributes 495 printf("</ul>\n"); 496 } 497 498 static void do_program(rcc_program_ty x) { 499 printf("<ul>\n"); 500 xx(x,nuids,int); 501 xx(x,nlabels,int); 502 xx(x,items,item_list); 503 xx(x,interfaces,interface_list); 504 xx(x,argc,int); 505 xx(x,argv,string_list); 506 printf("</ul>\n"); 507 } 508 509 int main(int argc, char *argv[]) { 510 int i, version; 511 float stamp = (assert(strstr(rcsid, ",v")), strtod(strstr(rcsid, ",v")+2, NULL)) 512 ; 513 char *infile = NULL, *outfile = NULL; 514 rcc_program_ty pickle; 515 516 for (i = 1; i < argc; i++) 517 if (*argv[i] != '-' || strcmp(argv[i], "-") == 0) { 518 if (infile == NULL) 519 infile = argv[i]; 520 else if (outfile == NULL) 521 outfile = argv[i]; 522 } 523 if (infile != NULL && strcmp(infile, "-") != 0 524 && freopen(infile, "rb", stdin) == NULL) { 525 fprintf(stderr, "%s: can't read `%s'\n", argv[0], infile); 526 exit(EXIT_FAILURE); 527 } 528 if (infile == NULL || strcmp(infile, "-") == 0) 529 infile = "Standard Input"; 530 #if WIN32 531 else 532 _setmode(_fileno(stdin), _O_BINARY); 533 #endif 534 if (outfile != NULL && strcmp(outfile, "-") != 0 535 && freopen(outfile, "w", stdout) == NULL) { 536 fprintf(stderr, "%s: can't write `%s'\n", argv[0], outfile); 537 exit(EXIT_FAILURE); 538 } 539 version = read_int(stdin); 540 assert(version/100 == (int)stamp); 541 pickle = rcc_read_program(stdin); 542 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\"\n"); 543 printf("<html><head><title>%s</title>\n" 544 "<link rev=made href=\"mailto:drh@microsoft.com\">\n" 545 "</head><body>\n<h1>%s</h1>\n", infile, infile); 546 printf("<p>version = %d.%d</p>", version/100, version%100); 547 do_program(pickle); 548 { 549 time_t t; 550 time(&t); 551 printf("<hr><address>%s</address>\n", ctime(&t)); 552 } 553 printf("</body></html>\n"); 554 return EXIT_SUCCESS; 555 }