00001 #define TRACE
00002 #undef TRACE
00003 #define DEBUG
00004 #undef DEBUG
00005
00006
00007 # ifdef TRACE
00008 # define IFTRACE(x) x
00009 # else
00010 # define IFTRACE(x)
00011 # endif
00012
00013 # include "parm.h"
00014 # include <stdio.h>
00015 # include <a.out.h>
00016 # include "stree/ststructs.mh"
00017 # include "pass3/is_local.h"
00018 # define FMTERR 7
00019 # define MAXLISTELMTS 100000
00020
00021 char FMTMSG[] = "Bad signature format for %s (not compiled with -c?)\n";
00022
00023 extern FILE * unparse_file;
00024
00025 char * Sinf_name;
00026
00027 extern boolean Gflag;
00028
00029 extern boolean OOflag;
00030
00031
00032 # define fs_nil ((struct File_Sigs *) 0)
00033 struct File_Sigs {
00034 char * fs_name;
00035 NODE * fs_signature;
00036 struct File_Sigs * fs_next;
00037 } *file_sigs = fs_nil;
00038
00039
00040 struct decl_entry {
00041 NODE * de_decl;
00042 int de_number;
00043 struct decl_entry * de_next;
00044 } *decl_nums;
00045
00046
00047
00048 static int decl_num = 0;
00049
00050
00051 # define add_decl(decl) { \
00052 struct decl_entry * o = (struct decl_entry *) \
00053 malloc(sizeof (struct decl_entry)); \
00054 o -> de_number = (++decl_num); \
00055 o -> de_decl = decl; \
00056 o -> de_next = decl_nums; \
00057 decl_nums = o; \
00058 }
00059
00060 # define NONE (NODE *)(-1)
00061
00062
00063 static NODE * get_decl(decl_num)
00064 int decl_num;
00065 {
00066 struct decl_entry *p = decl_nums;
00067
00068 while (p != NIL ) {
00069 if (decl_num == p -> de_number) {
00070 return(p -> de_decl);
00071 }
00072 p = p -> de_next;
00073 }
00074 return(NONE);
00075 }
00076
00077
00078 static free_decls()
00079 {
00080 struct decl_entry *p = decl_nums;
00081 struct decl_entry *q;
00082
00083 while (p != NIL ) {
00084 q = p;
00085 p = p -> de_next;
00086 free(q);
00087 }
00088 }
00089
00090 NODE * sig_in1();
00091
00092 extern char tokenbuf[1000];
00093
00094
00095
00096
00097
00098
00099
00100 char * get_string(Sinfile)
00101 FILE * Sinfile;
00102 {
00103 int len = 0;
00104 char c;
00105 char * result;
00106
00107 while((c = getc(Sinfile)) != 0) {
00108 if (ferror(Sinfile) || feof(Sinfile) || len >= (sizeof tokenbuf)-1) {
00109 fprintf(stderr, FMTMSG, Sinf_name);
00110 # ifdef TRACE
00111 printf("bad string\n");
00112 abort();
00113 # endif
00114 exit(FMTERR);
00115 }
00116 tokenbuf[len++] = c;
00117 }
00118 tokenbuf[len] = 0;
00119 if (len == 1 && tokenbuf[0] == '\377') {
00120 return(NIL);
00121 }
00122 result = (char *)malloc(len+1);
00123 strcpy(result, tokenbuf);
00124 return(result);
00125 }
00126
00127
00128 int readw(Sinfile)
00129 FILE * Sinfile;
00130 {
00131 int result;
00132
00133 if (ferror(Sinfile) || feof(Sinfile)) {
00134 fprintf(stderr, FMTMSG, Sinf_name);
00135 # ifdef TRACE
00136 printf("readw: read error\n");
00137 abort();
00138 # endif
00139 exit(FMTERR);
00140 }
00141 result = getw(Sinfile);
00142 if (ferror(Sinfile)) {
00143 fprintf(stderr, FMTMSG, Sinf_name);
00144 # ifdef TRACE
00145 printf("readw: read error\n");
00146 abort();
00147 # endif
00148 exit(FMTERR);
00149 }
00150 return(result);
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 # define LOCALREP 0
00164 # define GLOBALREP 1
00165 # define SELECTREP 2
00166
00167
00168
00169 NODE * get_name(Sinfile,kindno)
00170 FILE *Sinfile;
00171 int kindno;
00172 {
00173 unsigned string_index;
00174 int rep;
00175 NODE * selt = NIL;
00176 NODE * last_def = NIL;
00177 NODE * result;
00178 int decl_number;
00179
00180 # ifdef DEBUG
00181 if (kindno != LETTERID && kindno != OPRID) {
00182 dbgmsg("get_name: bad node kind\n");
00183 abort();
00184 }
00185 # endif
00186 rep = readw(Sinfile);
00187 switch(rep) {
00188 case SELECTREP:
00189 selt = sig_in1(Sinfile);
00190 break;
00191 case GLOBALREP:
00192 last_def = (NODE *)readw(Sinfile);
00193 break;
00194 case LOCALREP:
00195 decl_number = readw(Sinfile);
00196 last_def = get_decl(decl_number);
00197 if (last_def == NONE) {
00198 fprintf(stderr, FMTMSG, Sinf_name);
00199 # ifdef TRACE
00200 printf("No declaration %d\n", decl_number);
00201 abort();
00202 # endif
00203 exit(FMTERR);
00204 }
00205 break;
00206 }
00207 # ifdef DEBUG
00208 if (last_def != NIL &&
00209 last_def -> kind != DECLARATION &&
00210 last_def -> kind != PARAMETER &&
00211 last_def -> kind != TYPESIGNATURE &&
00212 last_def -> kind != PRODCONSTRUCTION &&
00213 last_def -> kind != UNIONCONSTRUCTION &&
00214 last_def -> kind != MODPRIMARY) {
00215 dbgmsg("get_name: bad definition %X\n", last_def);
00216 abort();
00217 }
00218 # endif
00219
00220 {
00221 int len = 0;
00222 char c;
00223
00224 while((c = getc(Sinfile)) != 0) {
00225 if (ferror(Sinfile) || feof(Sinfile) || len >= (sizeof tokenbuf)-1) {
00226 fprintf(stderr, FMTMSG, Sinf_name);
00227 # ifdef TRACE
00228 printf("error reading id name \n");
00229 abort();
00230 # endif
00231 exit(FMTERR);
00232 }
00233 tokenbuf[len++] = c;
00234 }
00235 tokenbuf[len] = 0;
00236 if (len == 0) {
00237 string_index = -1;
00238 } else {
00239 # ifdef TRACE
00240 printf("getname: read identifier name: %s\n", tokenbuf);
00241 # endif
00242 string_index = stt_enter(tokenbuf, len+1);
00243 }
00244 }
00245 result = mknode(kindno, string_index);
00246 result -> id_last_definition = last_def;
00247 initfld(&(result -> sel_type), selt);
00248 result -> id_def_found = TRUE;
00249 return(result);
00250 }
00251
00252
00253
00254
00255 NODE * list_in(Sinfile)
00256 FILE * Sinfile;
00257 {
00258 int nelements = readw(Sinfile);
00259 int i;
00260 NODE * result = emptylist();
00261
00262 if (((unsigned) nelements) > MAXLISTELMTS) {
00263 fprintf(stderr, FMTMSG, Sinf_name);
00264 # ifdef TRACE
00265 printf("absurdly long list\n");
00266 abort();
00267 # endif
00268 exit(FMTERR);
00269 }
00270 for (i = 0; i < nelements; i++) {
00271 addright(result, sig_in1(Sinfile));
00272 }
00273 return(result);
00274 }
00275
00276
00277
00278
00279
00280
00281
00282 NODE * sig_in(Sinfile, name)
00283 FILE * Sinfile;
00284 char * name;
00285 {
00286 NODE * result;
00287
00288 char * old_Sinf_name = Sinf_name;
00289 struct decl_entry * old_decl_nums = decl_nums;
00290 long old_decl_num = decl_num;
00291
00292 decl_nums = NIL;
00293 decl_num = 0;
00294 Sinf_name = name;
00295 result = sig_in1(Sinfile);
00296 # ifdef TRACE
00297 printf("Read signature\n");
00298 unparse_file = stdout;
00299 unparse(result);
00300 printf("\n");
00301 # endif
00302 free_decls();
00303
00304 Sinf_name = old_Sinf_name;
00305 decl_nums = old_decl_nums;
00306 decl_num = old_decl_num;
00307 return(result);
00308 }
00309
00310
00311
00312
00313
00314
00315
00316 NODE * read_signature(fn)
00317 char *fn;
00318 {
00319 int name_length = strlen(fn);
00320 FILE * extern_file;
00321 char * ext_fname;
00322 NODE * result;
00323 struct File_Sigs * p;
00324 extern char etext;
00325
00326
00327
00328 for (p = file_sigs; p != fs_nil; p = p -> fs_next) {
00329 if (strcmp(fn, p -> fs_name) == 0) {
00330 return(p -> fs_signature);
00331 }
00332 }
00333
00334 ext_fname = (char *) malloc(name_length+3);
00335
00336 strcpy(ext_fname, fn);
00337 ext_fname[name_length] = '.';
00338 ext_fname[name_length+1] = 'o';
00339 ext_fname[name_length+2] = 0;
00340
00341 if ((extern_file = fopen(ext_fname, "r")) == NULL) {
00342 fprintf(stderr, "Couldn't open %s\n", ext_fname);
00343 yyperror("Cant open external Russell object file");
00344 result = mknode (REXTERNDEF, NIL, NIL);
00345 } else {
00346 unsigned long strsize;
00347 struct exec header;
00348 extern FILE * optfile;
00349 unsigned long optsize;
00350 int c;
00351
00352
00353 fread(&header, sizeof (struct exec), 1, extern_file);
00354 fseek(extern_file, N_STROFF(header), 0);
00355 fread(&strsize, sizeof (long), 1, extern_file);
00356 fseek(extern_file, N_STROFF(header) + strsize, 0);
00357
00358 # if defined(SUN) && defined(EXTRA_MAGIC)
00359
00360 {
00361 struct extra_sections es;
00362
00363 fread(&es, sizeof (struct extra_sections), 1, extern_file);
00364 if (es.extra_magic != EXTRA_MAGIC) {
00365 fprintf(stderr, "Bad secondary magic number in %s (%s)\n",
00366 ext_fname, "Not compiled with -c?");
00367 exit(1);
00368 }
00369 if (es.extra_nsects != 1) {
00370 fprintf(stderr, "Unrecognized extra sections in executable %s\n",
00371 ext_fname);
00372 exit(1);
00373 }
00374
00375 (void) getw(extern_file);
00376 }
00377 # endif
00378
00379
00380 optsize = getw(extern_file);
00381 for (; optsize > 0; optsize--) {
00382 if ((c = getc(extern_file)) == EOF) {
00383 fprintf(stderr, "Bad optimization info in %s (not compiled with -c?)\n",
00384 ext_fname);
00385 exit(1);
00386 }
00387 if (OOflag) {
00388 putc(c, optfile);
00389 }
00390 }
00391
00392
00393
00394 if ((char *)(getw(extern_file)) != &etext) {
00395 fprintf(stderr, "Outdated executable %s - must be recompiled\n",
00396 ext_fname);
00397 exit(1);
00398 }
00399
00400
00401
00402
00403
00404
00405 {
00406 extern char str_code_buf[];
00407 char *p;
00408 extern void add_objfile();
00409 int c;
00410
00411 do {
00412
00413 p = str_code_buf;
00414 do {
00415 c = getc(extern_file);
00416 if (c == '\n') {
00417 *p = '\0';
00418 } else if (c == EOF) {
00419 fprintf(stderr, "%s has bad format\n",
00420 ext_fname);
00421 yyperror("Bad external object file");
00422 exit(1);
00423 } else {
00424 *p++ = c;
00425 }
00426 } while (c != '\n');
00427 if (p != str_code_buf) {
00428 add_objfile(str_code_buf);
00429 }
00430 } while (p != str_code_buf);
00431 }
00432
00433
00434 result = sig_in(extern_file, ext_fname);
00435
00436 fclose(extern_file);
00437 }
00438 free(ext_fname);
00439
00440 p = (struct File_Sigs *) malloc(sizeof (struct File_Sigs));
00441 p -> fs_next = file_sigs;
00442 p -> fs_name = fn;
00443 p -> fs_signature = lock(result);
00444 file_sigs = p;
00445
00446 return(result);
00447 }
00448
00449 NODE * sig_in1(Sinfile)
00450 FILE * Sinfile;
00451 {
00452 register NODE * result;
00453 int kindno;
00454
00455 # ifdef TRACE
00456 printf("sig_in: position = %d\n", ftell(Sinfile));
00457 # endif
00458 kindno = readw(Sinfile);
00459 if (feof(Sinfile)) {
00460 # ifdef TRACE
00461 printf("End of file\n");
00462 abort();
00463 # endif
00464 fprintf(stderr, FMTMSG, Sinf_name);
00465 exit(FMTERR);
00466 }
00467 # ifdef TRACE
00468 printf("sig_in: kind = %d(%s)\n", kindno, kindname(kindno));
00469 # endif
00470
00471 switch ( kindno ) {
00472
00473 case -1:
00474 return(NIL);
00475
00476 case DECLARATION:
00477 {
00478 NODE * id;
00479 NODE * sig;
00480 NODE * den;
00481 int sig_transp;
00482 NODE * result;
00483
00484 id = sig_in1(Sinfile);
00485 sig_transp = readw(Sinfile);
00486 sig = sig_in1(Sinfile);
00487 den = sig_in1(Sinfile);
00488 result = mknode(DECLARATION, id, den, sig);
00489 result -> decl_sig_transp = sig_transp;
00490 return(result);
00491 }
00492
00493 case BLOCKDENOTATION:
00494 {
00495 NODE * decl_l;
00496 NODE * den_s;
00497 int len_decl_l = readw(Sinfile);
00498 int i;
00499 NODE * v;
00500
00501 if (((unsigned) len_decl_l) > MAXLISTELMTS) {
00502 fprintf(stderr, FMTMSG, Sinf_name);
00503 # ifdef TRACE
00504 printf("declaration list too long\n");
00505 abort();
00506 # endif
00507 exit(FMTERR);
00508 }
00509 decl_l = emptylist();
00510
00511 for (i = 0; i < len_decl_l; i++) {
00512 v = mknode(DECLARATION, NIL, NIL, NIL);
00513 addright(decl_l, v);
00514 add_decl(v);
00515 # ifdef TRACE
00516 printf("Added explicit declaration number %d\n",
00517 decl_num);
00518 # endif
00519 }
00520 maplist(v, decl_l, {
00521 int decl_kind;
00522 NODE * id;
00523 NODE * sig;
00524 NODE * den;
00525
00526 decl_kind = readw(Sinfile);
00527 if (decl_kind != DECLARATION) {
00528 fprintf(stderr, FMTMSG, Sinf_name);
00529 IFTRACE(
00530 printf("bad declaration\n");
00531 abort();
00532 )
00533 exit(FMTERR);
00534 }
00535 id = sig_in1(Sinfile);
00536 sig = sig_in1(Sinfile);
00537 den = sig_in1(Sinfile);
00538 initfld(&(v -> decl_id), id);
00539 initfld(&(v -> decl_denotation), den);
00540 initfld(&(v -> decl_signature), sig);
00541 });
00542 den_s = list_in(Sinfile);
00543 return(mknode(BLOCKDENOTATION, decl_l, den_s));
00544 }
00545
00546 case APPLICATION:
00547 {
00548 NODE * op;
00549 NODE * args;
00550
00551 op = sig_in1(Sinfile);
00552 args = list_in(Sinfile);
00553 return(mknode(APPLICATION, op, args));
00554 }
00555
00556 case LOOPDENOTATION:
00557 case GUARDEDLIST:
00558 return(mknode(kindno, list_in(Sinfile)));
00559
00560 case GUARDEDELEMENT:
00561 {
00562 NODE * guard;
00563 NODE * element;
00564
00565 guard = sig_in1(Sinfile);
00566 element = sig_in1(Sinfile);
00567 return(mknode(GUARDEDELEMENT, guard, element));
00568 }
00569
00570 case OPRID:
00571 case LETTERID:
00572 return(get_name(Sinfile, kindno));
00573
00574 case FUNCCONSTR:
00575 {
00576 NODE * sig;
00577 NODE * body;
00578
00579 sig = sig_in1(Sinfile);
00580 body = sig_in1(Sinfile);
00581 return(mknode(FUNCCONSTR, sig, body));
00582 }
00583
00584 case USELIST:
00585 {
00586 NODE * type_list;
00587 NODE * den_seq;
00588
00589 type_list = list_in(Sinfile);
00590 den_seq = list_in(Sinfile);
00591 return(mknode(USELIST, type_list, den_seq));
00592 }
00593
00594 case MODPRIMARY:
00595 {
00596 NODE * result = mknode(MODPRIMARY, NIL, NIL);
00597
00598 add_decl(result);
00599 # ifdef TRACE
00600 printf("Added mp declaration number %d\n",
00601 decl_num);
00602 # endif
00603 initfld(&(result -> mp_primary),
00604 sig_in1(Sinfile));
00605 initfld(&(result -> mp_type_modifier),
00606 sig_in1(Sinfile));
00607 return(result);
00608 }
00609
00610 case PRODCONSTRUCTION:
00611 case UNIONCONSTRUCTION:
00612 {
00613 NODE * result = mknode(kindno, NIL, NIL);
00614
00615 add_decl(result);
00616 # ifdef TRACE
00617 printf("Added type c. declaration number %d\n",
00618 decl_num);
00619 # endif
00620 initfld(&(result -> prod_local_type_id),
00621 sig_in1(Sinfile));
00622 initfld(&(result -> prod_components),
00623 list_in(Sinfile));
00624 return(result);
00625 }
00626
00627 case WORDELSE:
00628 return(mknode(WORDELSE));
00629
00630 case PARAMETER:
00631 {
00632 NODE * id;
00633 NODE * sig;
00634
00635 id = sig_in1(Sinfile);
00636 sig = sig_in1(Sinfile);
00637 return(mknode(PARAMETER, id, sig));
00638 }
00639
00640 case FUNCSIGNATURE:
00641 {
00642 NODE * param_list = emptylist();
00643 int nparams;
00644 int i, param_kind;
00645 int constr_info;
00646 NODE * constr;
00647 int spcl;
00648
00649 spcl = readw(Sinfile);
00650 result = mknode(FUNCSIGNATURE,
00651 (Gflag?
00652 (char *) get_RIC(Sinfile)
00653
00654 : get_string(Sinfile)),
00655 NIL, NIL);
00656 result -> fsig_special = spcl;
00657
00658
00659
00660 nparams = readw(Sinfile);
00661 if (((unsigned) nparams) > MAXLISTELMTS) {
00662 fprintf(stderr, FMTMSG, Sinf_name);
00663 # ifdef TRACE
00664 printf("Too many parameters\n");
00665 # endif
00666 exit(FMTERR);
00667 }
00668 for (i = 0; i < nparams; i++) {
00669 NODE * v;
00670
00671 v = mknode(PARAMETER, NIL, NIL);
00672 addright(param_list, v);
00673 add_decl(v);
00674 # ifdef TRACE
00675 printf("Added parameter declaration number %d\n",
00676 decl_num);
00677 # endif
00678 }
00679
00680
00681 maplist(v, param_list, {
00682 param_kind = readw(Sinfile);
00683 if (param_kind != PARAMETER) {
00684 fprintf(stderr, FMTMSG, Sinf_name);
00685 IFTRACE(
00686 printf("bad parameter\n");
00687 abort();
00688 )
00689 exit(FMTERR);
00690 }
00691 initfld(&(v -> par_id), sig_in1(Sinfile));
00692 initfld(&(v -> par_signature), sig_in1(Sinfile));
00693 });
00694
00695 initfld(&(result -> fsig_param_list), param_list);
00696 initfld(&(result -> fsig_result_sig), sig_in1(Sinfile));
00697
00698 # define CONSTR_UNKNOWN 0
00699 # define CONSTR_AVAIL 1
00700 # define SLINK_AVAIL 2
00701 constr_info = readw(Sinfile);
00702 switch (constr_info) {
00703 case CONSTR_UNKNOWN:
00704 break;
00705
00706 case SLINK_AVAIL:
00707 result -> fsig_slink_known = TRUE;
00708
00709
00710 case CONSTR_AVAIL:
00711 constr = mknode(FUNCCONSTR,
00712 result,
00713 mknode(EXTERNDEF,NIL));
00714 lock(constr);
00715 result -> fsig_construction = constr;
00716 constr -> fc_complexity = readw(Sinfile);
00717 constr -> fc_code_label = get_string(Sinfile);
00718 constr -> ar_static_level = readw(Sinfile);
00719 constr -> ar_size = readw(Sinfile);
00720 # ifdef TRACE
00721 printf("Construction=%X, label=%s, compl=%d\n",
00722 constr, constr -> fc_code_label,
00723 constr -> fc_complexity);
00724 # endif
00725 }
00726 return(result);
00727 }
00728
00729 case VALSIGNATURE:
00730 case VARSIGNATURE:
00731 return(mknode(kindno, sig_in1(Sinfile)));
00732
00733 case SIGNATURESIG:
00734 return(mknode(SIGNATURESIG));
00735
00736 case TYPESIGNATURE:
00737 result = mknode(TYPESIGNATURE, NIL, NIL, NIL, NIL, NIL);
00738 add_decl(result);
00739 # ifdef TRACE
00740 printf("Added type sig. declaration number %d\n",
00741 decl_num);
00742 # endif
00743 initfld(&(result -> ts_local_type_id), sig_in1(Sinfile));
00744 initfld(&(result -> ts_clist), list_in(Sinfile));
00745
00746 result -> ts_const_code = get_string(Sinfile);
00747 result -> ts_string_code = get_string(Sinfile);
00748 result -> ts_element_code = get_string(Sinfile);
00749 result -> ts_string_max = readw(Sinfile);
00750 result -> ts_simple_type = readw(Sinfile);
00751 return(result);
00752
00753 case TSCOMPONENT:
00754 {
00755 NODE * id;
00756 NODE * sig;
00757
00758 id = sig_in1(Sinfile);
00759 sig = sig_in1(Sinfile);
00760 return(mknode(TSCOMPONENT, id, sig));
00761 }
00762
00763 case DEFCHARSIGS:
00764 {
00765 int i;
00766 unsigned * base;
00767
00768 result = mknode(DEFCHARSIGS, 0, 0, 0, 0);
00769 base = &(result -> dcs_0);
00770 for(i = 0; i < NVECTORS; i++) {
00771 base[i] = readw(Sinfile);
00772 }
00773 return(result);
00774 }
00775
00776 case REXTERNDEF:
00777 {
00778 char * name = get_string(Sinfile);
00779 NODE * sig = read_signature(name);
00780
00781 result = mknode(REXTERNDEF, sig, name);
00782 result -> sig_done = SIG_DONE;
00783 return(result);
00784 }
00785
00786 case RECORDCONSTRUCTION:
00787 case EXTENSION:
00788 case ENUMERATION:
00789 case RECORDELEMENT:
00790 case WITHLIST:
00791 case EXPORTLIST:
00792 case HIDELIST:
00793 case EXPORTELEMENT:
00794 dbgmsg("Signature input can't handle %s yet\n",
00795 kindname(kindno));
00796 return(NIL);
00797
00798 case QSTR:
00799 case UQSTR:
00800 case LISTHEADER:
00801 case FREEVARNODE:
00802 case WORDCAND:
00803 case WORDCOR:
00804 case EXTERNDEF:
00805 default:
00806 # ifdef TRACE
00807 printf("Bad kind\n");
00808 abort();
00809 # endif
00810 fprintf(stderr, FMTMSG, Sinf_name);
00811 exit(FMTERR);
00812
00813 };
00814 }