|
|
1.1 ! root 1: /**************************************************************** ! 2: Copyright 1990, 1991, 1993 by AT&T Bell Laboratories and Bellcore. ! 3: ! 4: Permission to use, copy, modify, and distribute this software ! 5: and its documentation for any purpose and without fee is hereby ! 6: granted, provided that the above copyright notice appear in all ! 7: copies and that both that the copyright notice and this ! 8: permission notice and warranty disclaimer appear in supporting ! 9: documentation, and that the names of AT&T Bell Laboratories or ! 10: Bellcore or any of their entities not be used in advertising or ! 11: publicity pertaining to distribution of the software without ! 12: specific, written prior permission. ! 13: ! 14: AT&T and Bellcore disclaim all warranties with regard to this ! 15: software, including all implied warranties of merchantability ! 16: and fitness. In no event shall AT&T or Bellcore be liable for ! 17: any special, indirect or consequential damages or any damages ! 18: whatsoever resulting from loss of use, data or profits, whether ! 19: in an action of contract, negligence or other tortious action, ! 20: arising out of or in connection with the use or performance of ! 21: this software. ! 22: ****************************************************************/ ! 23: ! 24: #include "defs.h" ! 25: #include "output.h" ! 26: #include "names.h" ! 27: #include "format.h" ! 28: ! 29: #define MAX_INIT_LINE 100 ! 30: #define NAME_MAX 64 ! 31: ! 32: static int memno2info(); ! 33: ! 34: extern char *initbname; ! 35: extern void def_start(); ! 36: ! 37: void list_init_data(Infile, Inname, outfile) ! 38: FILE **Infile, *outfile; ! 39: char *Inname; ! 40: { ! 41: FILE *sortfp; ! 42: int status; ! 43: ! 44: fclose(*Infile); ! 45: *Infile = 0; ! 46: ! 47: if (status = dsort(Inname, sortfname)) ! 48: fatali ("sort failed, status %d", status); ! 49: ! 50: scrub(Inname); /* optionally unlink Inname */ ! 51: ! 52: if ((sortfp = fopen(sortfname, textread)) == NULL) ! 53: Fatal("Couldn't open sorted initialization data"); ! 54: ! 55: do_init_data(outfile, sortfp); ! 56: fclose(sortfp); ! 57: scrub(sortfname); ! 58: ! 59: /* Insert a blank line after any initialized data */ ! 60: ! 61: nice_printf (outfile, "\n"); ! 62: ! 63: if (debugflag && infname) ! 64: /* don't back block data file up -- it won't be overwritten */ ! 65: backup(initfname, initbname); ! 66: } /* list_init_data */ ! 67: ! 68: ! 69: ! 70: /* do_init_data -- returns YES when at least one declaration has been ! 71: written */ ! 72: ! 73: int do_init_data(outfile, infile) ! 74: FILE *outfile, *infile; ! 75: { ! 76: char varname[NAME_MAX], ovarname[NAME_MAX]; ! 77: ftnint offset; ! 78: ftnint type; ! 79: int vargroup; /* 0 --> init, 1 --> equiv, 2 --> common */ ! 80: int did_one = 0; /* True when one has been output */ ! 81: chainp values = CHNULL; /* Actual data values */ ! 82: int keepit = 0; ! 83: Namep np; ! 84: ! 85: ovarname[0] = '\0'; ! 86: ! 87: while (rdname (infile, &vargroup, varname) && rdlong (infile, &offset) ! 88: && rdlong (infile, &type)) { ! 89: if (strcmp (varname, ovarname)) { ! 90: ! 91: /* If this is a new variable name, the old initialization has been ! 92: completed */ ! 93: ! 94: wr_one_init(outfile, ovarname, &values, keepit); ! 95: ! 96: strcpy (ovarname, varname); ! 97: values = CHNULL; ! 98: if (vargroup == 0) { ! 99: if (memno2info(atoi(varname+2), &np)) { ! 100: if (((Addrp)np)->uname_tag != UNAM_NAME) { ! 101: err("do_init_data: expected NAME"); ! 102: goto Keep; ! 103: } ! 104: np = ((Addrp)np)->user.name; ! 105: } ! 106: if (!(keepit = np->visused) && !np->vimpldovar) ! 107: warn1("local variable %s never used", ! 108: np->fvarname); ! 109: } ! 110: else { ! 111: Keep: ! 112: keepit = 1; ! 113: } ! 114: if (keepit && !did_one) { ! 115: nice_printf (outfile, "/* Initialized data */\n\n"); ! 116: did_one = YES; ! 117: } ! 118: } /* if strcmp */ ! 119: ! 120: values = mkchain((char *)data_value(infile, offset, (int)type), values); ! 121: } /* while */ ! 122: ! 123: /* Write out the last declaration */ ! 124: ! 125: wr_one_init (outfile, ovarname, &values, keepit); ! 126: ! 127: return did_one; ! 128: } /* do_init_data */ ! 129: ! 130: ! 131: ftnint ! 132: wr_char_len(outfile, dimp, n, extra1) ! 133: FILE *outfile; ! 134: int n; ! 135: struct Dimblock *dimp; ! 136: int extra1; ! 137: { ! 138: int i, nd; ! 139: expptr e; ! 140: ftnint rv; ! 141: ! 142: if (!dimp) { ! 143: nice_printf (outfile, extra1 ? "[%d+1]" : "[%d]", n); ! 144: return n + extra1; ! 145: } ! 146: nice_printf(outfile, "[%d", n); ! 147: nd = dimp->ndim; ! 148: rv = n; ! 149: for(i = 0; i < nd; i++) { ! 150: e = dimp->dims[i].dimsize; ! 151: if (!ISICON (e)) ! 152: err ("wr_char_len: nonconstant array size"); ! 153: else { ! 154: nice_printf(outfile, "*%ld", e->constblock.Const.ci); ! 155: rv *= e->constblock.Const.ci; ! 156: } ! 157: } ! 158: /* extra1 allows for stupid C compilers that complain about ! 159: * too many initializers in ! 160: * char x[2] = "ab"; ! 161: */ ! 162: nice_printf(outfile, extra1 ? "+1]" : "]"); ! 163: return extra1 ? rv+1 : rv; ! 164: } ! 165: ! 166: static int ch_ar_dim = -1; /* length of each element of char string array */ ! 167: static int eqvmemno; /* kludge */ ! 168: ! 169: static void ! 170: write_char_init(outfile, Values, namep) ! 171: FILE *outfile; ! 172: chainp *Values; ! 173: Namep namep; ! 174: { ! 175: struct Equivblock *eqv; ! 176: long size; ! 177: struct Dimblock *dimp; ! 178: int i, nd, type; ! 179: expptr ds; ! 180: ! 181: if (!namep) ! 182: return; ! 183: if(nequiv >= maxequiv) ! 184: many("equivalences", 'q', maxequiv); ! 185: eqv = &eqvclass[nequiv]; ! 186: eqv->eqvbottom = 0; ! 187: type = namep->vtype; ! 188: size = type == TYCHAR ! 189: ? namep->vleng->constblock.Const.ci ! 190: : typesize[type]; ! 191: if (dimp = namep->vdim) ! 192: for(i = 0, nd = dimp->ndim; i < nd; i++) { ! 193: ds = dimp->dims[i].dimsize; ! 194: if (!ISICON(ds)) ! 195: err("write_char_values: nonconstant array size"); ! 196: else ! 197: size *= ds->constblock.Const.ci; ! 198: } ! 199: *Values = revchain(*Values); ! 200: eqv->eqvtop = size; ! 201: eqvmemno = ++lastvarno; ! 202: eqv->eqvtype = type; ! 203: wr_equiv_init(outfile, nequiv, Values, 0); ! 204: def_start(outfile, namep->cvarname, CNULL, ""); ! 205: if (type == TYCHAR) ! 206: ind_printf(0, outfile, "((char *)&equiv_%d)\n\n", eqvmemno); ! 207: else ! 208: ind_printf(0, outfile, dimp ! 209: ? "((%s *)&equiv_%d)\n\n" : "(*(%s *)&equiv_%d)\n\n", ! 210: c_type_decl(type,0), eqvmemno); ! 211: } ! 212: ! 213: /* wr_one_init -- outputs the initialization of the variable pointed to ! 214: by info. When is_addr is true, info is an Addrp; otherwise, ! 215: treat it as a Namep */ ! 216: ! 217: void wr_one_init (outfile, varname, Values, keepit) ! 218: FILE *outfile; ! 219: char *varname; ! 220: chainp *Values; ! 221: int keepit; ! 222: { ! 223: static int memno; ! 224: static union { ! 225: Namep name; ! 226: Addrp addr; ! 227: } info; ! 228: Namep namep; ! 229: int is_addr, size, type; ! 230: ftnint last, loc; ! 231: int is_scalar = 0; ! 232: char *array_comment = NULL, *name; ! 233: chainp cp, values; ! 234: extern char datachar[]; ! 235: static int e1[3] = {1, 0, 1}; ! 236: ftnint x; ! 237: extern int hsize; ! 238: ! 239: if (!keepit) ! 240: goto done; ! 241: if (varname == NULL || varname[1] != '.') ! 242: goto badvar; ! 243: ! 244: /* Get back to a meaningful representation; find the given memno in one ! 245: of the appropriate tables (user-generated variables in the hash table, ! 246: system-generated variables in a separate list */ ! 247: ! 248: memno = atoi(varname + 2); ! 249: switch(varname[0]) { ! 250: case 'q': ! 251: /* Must subtract eqvstart when the source file ! 252: * contains more than one procedure. ! 253: */ ! 254: wr_equiv_init(outfile, eqvmemno = memno - eqvstart, Values, 0); ! 255: goto done; ! 256: case 'Q': ! 257: /* COMMON initialization (BLOCK DATA) */ ! 258: wr_equiv_init(outfile, memno, Values, 1); ! 259: goto done; ! 260: case 'v': ! 261: break; ! 262: default: ! 263: badvar: ! 264: errstr("wr_one_init: unknown variable name '%s'", varname); ! 265: goto done; ! 266: } ! 267: ! 268: is_addr = memno2info (memno, &info.name); ! 269: if (info.name == (Namep) NULL) { ! 270: err ("wr_one_init -- unknown variable"); ! 271: return; ! 272: } ! 273: if (is_addr) { ! 274: if (info.addr -> uname_tag != UNAM_NAME) { ! 275: erri ("wr_one_init -- couldn't get name pointer; tag is %d", ! 276: info.addr -> uname_tag); ! 277: namep = (Namep) NULL; ! 278: nice_printf (outfile, " /* bad init data */"); ! 279: } else ! 280: namep = info.addr -> user.name; ! 281: } else ! 282: namep = info.name; ! 283: ! 284: /* check for character initialization */ ! 285: ! 286: *Values = values = revchain(*Values); ! 287: type = info.name->vtype; ! 288: if (type == TYCHAR) { ! 289: for(last = 0; values; values = values->nextp) { ! 290: cp = (chainp)values->datap; ! 291: loc = (ftnint)cp->datap; ! 292: if (loc > last) { ! 293: write_char_init(outfile, Values, namep); ! 294: goto done; ! 295: } ! 296: last = (int)cp->nextp->datap == TYBLANK ! 297: ? loc + (int)cp->nextp->nextp->datap ! 298: : loc + 1; ! 299: } ! 300: if (halign && info.name->tag == TNAME) { ! 301: nice_printf(outfile, "static struct { %s fill; char val", ! 302: halign); ! 303: x = wr_char_len(outfile, namep->vdim, ch_ar_dim = ! 304: info.name -> vleng -> constblock.Const.ci, 1); ! 305: if (x %= hsize) ! 306: nice_printf(outfile, "; char fill2[%ld]", hsize - x); ! 307: name = info.name->cvarname; ! 308: nice_printf(outfile, "; } %s_st = { 0,", name); ! 309: wr_output_values(outfile, namep, *Values); ! 310: nice_printf(outfile, " };\n"); ! 311: ch_ar_dim = -1; ! 312: def_start(outfile, name, CNULL, name); ! 313: ind_printf(0, outfile, "_st.val\n"); ! 314: goto done; ! 315: } ! 316: } ! 317: else { ! 318: size = typesize[type]; ! 319: loc = 0; ! 320: for(; values; values = values->nextp) { ! 321: if ((int)((chainp)values->datap)->nextp->datap == TYCHAR) { ! 322: write_char_init(outfile, Values, namep); ! 323: goto done; ! 324: } ! 325: last = ((long) ((chainp) values->datap)->datap) / size; ! 326: if (last - loc > 4) { ! 327: write_char_init(outfile, Values, namep); ! 328: goto done; ! 329: } ! 330: loc = last; ! 331: } ! 332: } ! 333: values = *Values; ! 334: ! 335: nice_printf (outfile, "static %s ", c_type_decl (type, 0)); ! 336: ! 337: if (is_addr) ! 338: write_nv_ident (outfile, info.addr); ! 339: else ! 340: out_name (outfile, info.name); ! 341: ! 342: if (namep) ! 343: is_scalar = namep -> vdim == (struct Dimblock *) NULL; ! 344: ! 345: if (namep && !is_scalar) ! 346: array_comment = type == TYCHAR ! 347: ? 0 : wr_ardecls(outfile, namep->vdim, 1L); ! 348: ! 349: if (type == TYCHAR) ! 350: if (ISICON (info.name -> vleng)) ! 351: ! 352: /* We'll make single strings one character longer, so that we can use the ! 353: standard C initialization. All this does is pad an extra zero onto the ! 354: end of the string */ ! 355: wr_char_len(outfile, namep->vdim, ch_ar_dim = ! 356: info.name -> vleng -> constblock.Const.ci, e1[Ansi]); ! 357: else ! 358: err ("variable length character initialization"); ! 359: ! 360: if (array_comment) ! 361: nice_printf (outfile, "%s", array_comment); ! 362: ! 363: nice_printf (outfile, " = "); ! 364: wr_output_values (outfile, namep, values); ! 365: ch_ar_dim = -1; ! 366: nice_printf (outfile, ";\n"); ! 367: done: ! 368: frchain(Values); ! 369: } /* wr_one_init */ ! 370: ! 371: ! 372: ! 373: ! 374: chainp data_value (infile, offset, type) ! 375: FILE *infile; ! 376: ftnint offset; ! 377: int type; ! 378: { ! 379: char line[MAX_INIT_LINE + 1], *pointer; ! 380: chainp vals, prev_val; ! 381: long atol(); ! 382: char *newval; ! 383: ! 384: if (fgets (line, MAX_INIT_LINE, infile) == NULL) { ! 385: err ("data_value: error reading from intermediate file"); ! 386: return CHNULL; ! 387: } /* if fgets */ ! 388: ! 389: /* Get rid of the trailing newline */ ! 390: ! 391: if (line[0]) ! 392: line[strlen (line) - 1] = '\0'; ! 393: ! 394: #define iswhite(x) (isspace (x) || (x) == ',') ! 395: ! 396: pointer = line; ! 397: prev_val = vals = CHNULL; ! 398: ! 399: while (*pointer) { ! 400: register char *end_ptr, old_val; ! 401: ! 402: /* Move pointer to the start of the next word */ ! 403: ! 404: while (*pointer && iswhite (*pointer)) ! 405: pointer++; ! 406: if (*pointer == '\0') ! 407: break; ! 408: ! 409: /* Move end_ptr to the end of the current word */ ! 410: ! 411: for (end_ptr = pointer + 1; *end_ptr && !iswhite (*end_ptr); ! 412: end_ptr++) ! 413: ; ! 414: ! 415: old_val = *end_ptr; ! 416: *end_ptr = '\0'; ! 417: ! 418: /* Add this value to the end of the list */ ! 419: ! 420: if (ONEOF(type, MSKREAL|MSKCOMPLEX)) ! 421: newval = cpstring(pointer); ! 422: else ! 423: newval = (char *)atol(pointer); ! 424: if (vals) { ! 425: prev_val->nextp = mkchain(newval, CHNULL); ! 426: prev_val = prev_val -> nextp; ! 427: } else ! 428: prev_val = vals = mkchain(newval, CHNULL); ! 429: *end_ptr = old_val; ! 430: pointer = end_ptr; ! 431: } /* while *pointer */ ! 432: ! 433: return mkchain((char *)offset, mkchain((char *)LONG_CAST type, vals)); ! 434: } /* data_value */ ! 435: ! 436: static void ! 437: overlapping() ! 438: { ! 439: extern char *filename0; ! 440: static int warned = 0; ! 441: ! 442: if (warned) ! 443: return; ! 444: warned = 1; ! 445: ! 446: fprintf(stderr, "Error"); ! 447: if (filename0) ! 448: fprintf(stderr, " in file %s", filename0); ! 449: fprintf(stderr, ": overlapping initializations\n"); ! 450: nerr++; ! 451: } ! 452: ! 453: static void make_one_const(); ! 454: static long charlen; ! 455: ! 456: void wr_output_values (outfile, namep, values) ! 457: FILE *outfile; ! 458: Namep namep; ! 459: chainp values; ! 460: { ! 461: int type = TYUNKNOWN; ! 462: struct Constblock Const; ! 463: static expptr Vlen; ! 464: ! 465: if (namep) ! 466: type = namep -> vtype; ! 467: ! 468: /* Handle array initializations away from scalars */ ! 469: ! 470: if (namep && namep -> vdim) ! 471: wr_array_init (outfile, namep -> vtype, values); ! 472: ! 473: else if (values->nextp && type != TYCHAR) ! 474: overlapping(); ! 475: ! 476: else { ! 477: make_one_const(type, &Const.Const, values); ! 478: Const.vtype = type; ! 479: Const.vstg = ONEOF(type, MSKREAL|MSKCOMPLEX) != 0; ! 480: if (type== TYCHAR) { ! 481: if (!Vlen) ! 482: Vlen = ICON(0); ! 483: Const.vleng = Vlen; ! 484: Vlen->constblock.Const.ci = charlen; ! 485: out_const (outfile, &Const); ! 486: free (Const.Const.ccp); ! 487: } ! 488: else ! 489: out_const (outfile, &Const); ! 490: } ! 491: } ! 492: ! 493: ! 494: wr_array_init (outfile, type, values) ! 495: FILE *outfile; ! 496: int type; ! 497: chainp values; ! 498: { ! 499: int size = typesize[type]; ! 500: long index, main_index = 0; ! 501: int k; ! 502: ! 503: if (type == TYCHAR) { ! 504: nice_printf(outfile, "\""); ! 505: k = 0; ! 506: if (Ansi != 1) ! 507: ch_ar_dim = -1; ! 508: } ! 509: else ! 510: nice_printf (outfile, "{ "); ! 511: while (values) { ! 512: struct Constblock Const; ! 513: ! 514: index = ((long) ((chainp) values->datap)->datap) / size; ! 515: while (index > main_index) { ! 516: ! 517: /* Fill with zeros. The structure shorthand works because the compiler ! 518: will expand the "0" in braces to fill the size of the entire structure ! 519: */ ! 520: ! 521: switch (type) { ! 522: case TYREAL: ! 523: case TYDREAL: ! 524: nice_printf (outfile, "0.0,"); ! 525: break; ! 526: case TYCOMPLEX: ! 527: case TYDCOMPLEX: ! 528: nice_printf (outfile, "{0},"); ! 529: break; ! 530: case TYCHAR: ! 531: nice_printf(outfile, " "); ! 532: break; ! 533: default: ! 534: nice_printf (outfile, "0,"); ! 535: break; ! 536: } /* switch */ ! 537: main_index++; ! 538: } /* while index > main_index */ ! 539: ! 540: if (index < main_index) ! 541: overlapping(); ! 542: else switch (type) { ! 543: case TYCHAR: ! 544: { int this_char; ! 545: ! 546: if (k == ch_ar_dim) { ! 547: nice_printf(outfile, "\" \""); ! 548: k = 0; ! 549: } ! 550: this_char = (int) ((chainp) values->datap)-> ! 551: nextp->nextp->datap; ! 552: if ((int)((chainp)values->datap)->nextp->datap == TYBLANK) { ! 553: main_index += this_char; ! 554: k += this_char; ! 555: while(--this_char >= 0) ! 556: nice_printf(outfile, " "); ! 557: values = values -> nextp; ! 558: continue; ! 559: } ! 560: nice_printf(outfile, str_fmt[this_char], this_char); ! 561: k++; ! 562: } /* case TYCHAR */ ! 563: break; ! 564: ! 565: case TYINT1: ! 566: case TYSHORT: ! 567: case TYLONG: ! 568: #ifdef TYQUAD ! 569: case TYQUAD: ! 570: #endif ! 571: case TYREAL: ! 572: case TYDREAL: ! 573: case TYLOGICAL: ! 574: case TYLOGICAL1: ! 575: case TYLOGICAL2: ! 576: case TYCOMPLEX: ! 577: case TYDCOMPLEX: ! 578: make_one_const(type, &Const.Const, values); ! 579: Const.vtype = type; ! 580: Const.vstg = ONEOF(type, MSKREAL|MSKCOMPLEX) != 0; ! 581: out_const(outfile, &Const); ! 582: break; ! 583: default: ! 584: erri("wr_array_init: bad type '%d'", type); ! 585: break; ! 586: } /* switch */ ! 587: values = values->nextp; ! 588: ! 589: main_index++; ! 590: if (values && type != TYCHAR) ! 591: nice_printf (outfile, ","); ! 592: } /* while values */ ! 593: ! 594: if (type == TYCHAR) { ! 595: nice_printf(outfile, "\""); ! 596: } ! 597: else ! 598: nice_printf (outfile, " }"); ! 599: } /* wr_array_init */ ! 600: ! 601: ! 602: static void ! 603: make_one_const(type, storage, values) ! 604: int type; ! 605: union Constant *storage; ! 606: chainp values; ! 607: { ! 608: union Constant *Const; ! 609: register char **L; ! 610: ! 611: if (type == TYCHAR) { ! 612: char *str, *str_ptr; ! 613: chainp v, prev; ! 614: int b = 0, k, main_index = 0; ! 615: ! 616: /* Find the max length of init string, by finding the highest offset ! 617: value stored in the list of initial values */ ! 618: ! 619: for(k = 1, prev = CHNULL, v = values; v; prev = v, v = v->nextp) ! 620: ; ! 621: if (prev != CHNULL) ! 622: k = ((int) (((chainp) prev->datap)->datap)) + 2; ! 623: /* + 2 above for null char at end */ ! 624: str = Alloc (k); ! 625: for (str_ptr = str; values; str_ptr++) { ! 626: int index = (int) (((chainp) values->datap)->datap); ! 627: ! 628: if (index < main_index) ! 629: overlapping(); ! 630: while (index > main_index++) ! 631: *str_ptr++ = ' '; ! 632: ! 633: k = (int) (((chainp) values->datap)->nextp->nextp->datap); ! 634: if ((int)((chainp)values->datap)->nextp->datap == TYBLANK) { ! 635: b = k; ! 636: break; ! 637: } ! 638: *str_ptr = k; ! 639: values = values -> nextp; ! 640: } /* for str_ptr */ ! 641: *str_ptr = '\0'; ! 642: Const = storage; ! 643: Const -> ccp = str; ! 644: Const -> ccp1.blanks = b; ! 645: charlen = str_ptr - str; ! 646: } else { ! 647: int i = 0; ! 648: chainp vals; ! 649: ! 650: vals = ((chainp)values->datap)->nextp->nextp; ! 651: if (vals) { ! 652: L = (char **)storage; ! 653: do L[i++] = vals->datap; ! 654: while(vals = vals->nextp); ! 655: } ! 656: ! 657: } /* else */ ! 658: ! 659: } /* make_one_const */ ! 660: ! 661: ! 662: ! 663: rdname (infile, vargroupp, name) ! 664: FILE *infile; ! 665: int *vargroupp; ! 666: char *name; ! 667: { ! 668: register int i, c; ! 669: ! 670: c = getc (infile); ! 671: ! 672: if (feof (infile)) ! 673: return NO; ! 674: ! 675: *vargroupp = c - '0'; ! 676: for (i = 1;; i++) { ! 677: if (i >= NAME_MAX) ! 678: Fatal("rdname: oversize name"); ! 679: c = getc (infile); ! 680: if (feof (infile)) ! 681: return NO; ! 682: if (c == '\t') ! 683: break; ! 684: *name++ = c; ! 685: } ! 686: *name = 0; ! 687: return YES; ! 688: } /* rdname */ ! 689: ! 690: rdlong (infile, n) ! 691: FILE *infile; ! 692: ftnint *n; ! 693: { ! 694: register int c; ! 695: ! 696: for (c = getc (infile); !feof (infile) && isspace (c); c = getc (infile)) ! 697: ; ! 698: ! 699: if (feof (infile)) ! 700: return NO; ! 701: ! 702: for (*n = 0; isdigit (c); c = getc (infile)) ! 703: *n = 10 * (*n) + c - '0'; ! 704: return YES; ! 705: } /* rdlong */ ! 706: ! 707: ! 708: static int ! 709: memno2info (memno, info) ! 710: int memno; ! 711: Namep *info; ! 712: { ! 713: chainp this_var; ! 714: extern chainp new_vars; ! 715: extern struct Hashentry *hashtab, *lasthash; ! 716: struct Hashentry *entry; ! 717: ! 718: for (this_var = new_vars; this_var; this_var = this_var -> nextp) { ! 719: Addrp var = (Addrp) this_var->datap; ! 720: ! 721: if (var == (Addrp) NULL) ! 722: Fatal("memno2info: null variable"); ! 723: else if (var -> tag != TADDR) ! 724: Fatal("memno2info: bad tag"); ! 725: if (memno == var -> memno) { ! 726: *info = (Namep) var; ! 727: return 1; ! 728: } /* if memno == var -> memno */ ! 729: } /* for this_var = new_vars */ ! 730: ! 731: for (entry = hashtab; entry < lasthash; ++entry) { ! 732: Namep var = entry -> varp; ! 733: ! 734: if (var && var -> vardesc.varno == memno && var -> vstg == STGINIT) { ! 735: *info = (Namep) var; ! 736: return 0; ! 737: } /* if entry -> vardesc.varno == memno */ ! 738: } /* for entry = hashtab */ ! 739: ! 740: Fatal("memno2info: couldn't find memno"); ! 741: return 0; ! 742: } /* memno2info */ ! 743: ! 744: static chainp ! 745: do_string(outfile, v, nloc) ! 746: FILEP outfile; ! 747: register chainp v; ! 748: ftnint *nloc; ! 749: { ! 750: register chainp cp, v0; ! 751: ftnint dloc, k, loc; ! 752: unsigned long uk; ! 753: char buf[8], *comma; ! 754: ! 755: nice_printf(outfile, "{"); ! 756: cp = (chainp)v->datap; ! 757: loc = (ftnint)cp->datap; ! 758: comma = ""; ! 759: for(v0 = v;;) { ! 760: switch((int)cp->nextp->datap) { ! 761: case TYBLANK: ! 762: k = (ftnint)cp->nextp->nextp->datap; ! 763: loc += k; ! 764: while(--k >= 0) { ! 765: nice_printf(outfile, "%s' '", comma); ! 766: comma = ", "; ! 767: } ! 768: break; ! 769: case TYCHAR: ! 770: uk = (ftnint)cp->nextp->nextp->datap; ! 771: sprintf(buf, chr_fmt[uk], uk); ! 772: nice_printf(outfile, "%s'%s'", comma, buf); ! 773: comma = ", "; ! 774: loc++; ! 775: break; ! 776: default: ! 777: goto done; ! 778: } ! 779: v0 = v; ! 780: if (!(v = v->nextp)) ! 781: break; ! 782: cp = (chainp)v->datap; ! 783: dloc = (ftnint)cp->datap; ! 784: if (loc != dloc) ! 785: break; ! 786: } ! 787: done: ! 788: nice_printf(outfile, "}"); ! 789: *nloc = loc; ! 790: return v0; ! 791: } ! 792: ! 793: static chainp ! 794: Ado_string(outfile, v, nloc) ! 795: FILEP outfile; ! 796: register chainp v; ! 797: ftnint *nloc; ! 798: { ! 799: register chainp cp, v0; ! 800: ftnint dloc, k, loc; ! 801: ! 802: nice_printf(outfile, "\""); ! 803: cp = (chainp)v->datap; ! 804: loc = (ftnint)cp->datap; ! 805: for(v0 = v;;) { ! 806: switch((int)cp->nextp->datap) { ! 807: case TYBLANK: ! 808: k = (ftnint)cp->nextp->nextp->datap; ! 809: loc += k; ! 810: while(--k >= 0) ! 811: nice_printf(outfile, " "); ! 812: break; ! 813: case TYCHAR: ! 814: k = (ftnint)cp->nextp->nextp->datap; ! 815: nice_printf(outfile, str_fmt[k], k); ! 816: loc++; ! 817: break; ! 818: default: ! 819: goto done; ! 820: } ! 821: v0 = v; ! 822: if (!(v = v->nextp)) ! 823: break; ! 824: cp = (chainp)v->datap; ! 825: dloc = (ftnint)cp->datap; ! 826: if (loc != dloc) ! 827: break; ! 828: } ! 829: done: ! 830: nice_printf(outfile, "\""); ! 831: *nloc = loc; ! 832: return v0; ! 833: } ! 834: ! 835: static char * ! 836: Len(L,type) ! 837: long L; ! 838: int type; ! 839: { ! 840: static char buf[24]; ! 841: if (L == 1 && type != TYCHAR) ! 842: return ""; ! 843: sprintf(buf, "[%ld]", L); ! 844: return buf; ! 845: } ! 846: ! 847: wr_equiv_init(outfile, memno, Values, iscomm) ! 848: FILE *outfile; ! 849: int memno; ! 850: chainp *Values; ! 851: int iscomm; ! 852: { ! 853: struct Equivblock *eqv; ! 854: char *equiv_name (); ! 855: int curtype, dtype, filltype, filltype1, j, k, wasblank, xtype; ! 856: static char Blank[] = ""; ! 857: register char *comma = Blank; ! 858: register chainp cp, v; ! 859: chainp sentinel, values, v1; ! 860: ftnint L, L1, dL, dloc, loc, loc0; ! 861: union Constant Const; ! 862: char imag_buf[50], real_buf[50]; ! 863: int szshort = typesize[TYSHORT]; ! 864: static char typepref[] = {0, 0, TYINT1, TYSHORT, TYLONG, ! 865: #ifdef TYQUAD ! 866: TYQUAD, ! 867: #endif ! 868: TYREAL, TYDREAL, TYREAL, TYDREAL, ! 869: TYLOGICAL1, TYLOGICAL2, ! 870: TYLOGICAL, TYCHAR}; ! 871: extern int htype; ! 872: char *z; ! 873: ! 874: /* add sentinel */ ! 875: if (iscomm) { ! 876: L = extsymtab[memno].maxleng; ! 877: xtype = extsymtab[memno].extype; ! 878: } ! 879: else { ! 880: eqv = &eqvclass[memno]; ! 881: L = eqv->eqvtop - eqv->eqvbottom; ! 882: xtype = eqv->eqvtype; ! 883: } ! 884: ! 885: if (halign && typealign[typepref[xtype]] < typealign[htype]) ! 886: xtype = htype; ! 887: ! 888: if (xtype != TYCHAR) { ! 889: ! 890: /* unless the data include a value of the appropriate ! 891: * type, we add an extra element in an attempt ! 892: * to force correct alignment */ ! 893: ! 894: for(v = *Values;;v = v->nextp) { ! 895: if (!v) { ! 896: dtype = typepref[xtype]; ! 897: z = ISREAL(dtype) ? cpstring("0.") : (char *)0; ! 898: k = typesize[dtype]; ! 899: if (j = L % k) ! 900: L += k - j; ! 901: v = mkchain((char *)L, ! 902: mkchain((char *)LONG_CAST dtype, ! 903: mkchain(z, CHNULL))); ! 904: *Values = mkchain((char *)v, *Values); ! 905: L += k; ! 906: break; ! 907: } ! 908: if ((int)((chainp)v->datap)->nextp->datap == xtype) ! 909: break; ! 910: } ! 911: } ! 912: ! 913: sentinel = mkchain((char *)L, mkchain((char *)TYERROR,CHNULL)); ! 914: *Values = values = revchain(mkchain((char *)sentinel, *Values)); ! 915: ! 916: /* use doublereal fillers only if there are doublereal values */ ! 917: ! 918: k = TYLONG; ! 919: for(v = values; v; v = v->nextp) ! 920: if (ONEOF((int)((chainp)v->datap)->nextp->datap, ! 921: M(TYDREAL)|M(TYDCOMPLEX))) { ! 922: k = TYDREAL; ! 923: break; ! 924: } ! 925: type_choice[0] = k; ! 926: ! 927: nice_printf(outfile, "%sstruct {\n", iscomm ? "" : "static "); ! 928: next_tab(outfile); ! 929: loc = loc0 = k = 0; ! 930: curtype = -1; ! 931: for(v = values; v; v = v->nextp) { ! 932: cp = (chainp)v->datap; ! 933: dloc = (ftnint)cp->datap; ! 934: L = dloc - loc; ! 935: if (L < 0) { ! 936: overlapping(); ! 937: if ((int)cp->nextp->datap != TYERROR) { ! 938: v1 = cp; ! 939: frchain(&v1); ! 940: v->datap = 0; ! 941: } ! 942: continue; ! 943: } ! 944: dtype = (int)cp->nextp->datap; ! 945: if (dtype == TYBLANK) { ! 946: dtype = TYCHAR; ! 947: wasblank = 1; ! 948: } ! 949: else ! 950: wasblank = 0; ! 951: if (curtype != dtype || L > 0) { ! 952: if (curtype != -1) { ! 953: L1 = (loc - loc0)/dL; ! 954: nice_printf(outfile, "%s e_%d%s;\n", ! 955: typename[curtype], ++k, ! 956: Len(L1,curtype)); ! 957: } ! 958: curtype = dtype; ! 959: loc0 = dloc; ! 960: } ! 961: if (L > 0) { ! 962: if (xtype == TYCHAR) ! 963: filltype = TYCHAR; ! 964: else { ! 965: filltype = L % szshort ? TYCHAR ! 966: : type_choice[L/szshort % 4]; ! 967: filltype1 = loc % szshort ? TYCHAR ! 968: : type_choice[loc/szshort % 4]; ! 969: if (typesize[filltype] > typesize[filltype1]) ! 970: filltype = filltype1; ! 971: } ! 972: L1 = L / typesize[filltype]; ! 973: nice_printf(outfile, "%s fill_%d[%ld];\n", ! 974: typename[filltype], ++k, L1); ! 975: loc = dloc; ! 976: } ! 977: if (wasblank) { ! 978: loc += (ftnint)cp->nextp->nextp->datap; ! 979: dL = 1; ! 980: } ! 981: else { ! 982: dL = typesize[dtype]; ! 983: loc += dL; ! 984: } ! 985: } ! 986: nice_printf(outfile, "} %s = { ", iscomm ! 987: ? extsymtab[memno].cextname ! 988: : equiv_name(eqvmemno, CNULL)); ! 989: loc = 0; ! 990: for(v = values; ; v = v->nextp) { ! 991: cp = (chainp)v->datap; ! 992: if (!cp) ! 993: continue; ! 994: dtype = (int)cp->nextp->datap; ! 995: if (dtype == TYERROR) ! 996: break; ! 997: dloc = (ftnint)cp->datap; ! 998: if (dloc > loc) { ! 999: nice_printf(outfile, "%s{0}", comma); ! 1000: comma = ", "; ! 1001: loc = dloc; ! 1002: } ! 1003: if (comma != Blank) ! 1004: nice_printf(outfile, ", "); ! 1005: comma = ", "; ! 1006: if (dtype == TYCHAR || dtype == TYBLANK) { ! 1007: v = Ansi == 1 ? Ado_string(outfile, v, &loc) ! 1008: : do_string(outfile, v, &loc); ! 1009: continue; ! 1010: } ! 1011: make_one_const(dtype, &Const, v); ! 1012: switch(dtype) { ! 1013: case TYLOGICAL: ! 1014: case TYLOGICAL2: ! 1015: case TYLOGICAL1: ! 1016: if (Const.ci < 0 || Const.ci > 1) ! 1017: errl( ! 1018: "wr_equiv_init: unexpected logical value %ld", ! 1019: Const.ci); ! 1020: nice_printf(outfile, ! 1021: Const.ci ? "TRUE_" : "FALSE_"); ! 1022: break; ! 1023: case TYINT1: ! 1024: case TYSHORT: ! 1025: case TYLONG: ! 1026: #ifdef TYQUAD ! 1027: case TYQUAD: ! 1028: #endif ! 1029: nice_printf(outfile, "%ld", Const.ci); ! 1030: break; ! 1031: case TYREAL: ! 1032: nice_printf(outfile, "%s", ! 1033: flconst(real_buf, Const.cds[0])); ! 1034: break; ! 1035: case TYDREAL: ! 1036: nice_printf(outfile, "%s", Const.cds[0]); ! 1037: break; ! 1038: case TYCOMPLEX: ! 1039: nice_printf(outfile, "%s, %s", ! 1040: flconst(real_buf, Const.cds[0]), ! 1041: flconst(imag_buf, Const.cds[1])); ! 1042: break; ! 1043: case TYDCOMPLEX: ! 1044: nice_printf(outfile, "%s, %s", ! 1045: Const.cds[0], Const.cds[1]); ! 1046: break; ! 1047: default: ! 1048: erri("unexpected type %d in wr_equiv_init", ! 1049: dtype); ! 1050: } ! 1051: loc += typesize[dtype]; ! 1052: } ! 1053: nice_printf(outfile, " };\n\n"); ! 1054: prev_tab(outfile); ! 1055: frchain(&sentinel); ! 1056: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.