|
|
1.1 ! root 1: /**************************************************************** ! 2: Copyright 1990, 1991, 1992, 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: /* Format.c -- this file takes an intermediate file (generated by pass 1 ! 25: of the translator) and some state information about the contents of that ! 26: file, and generates C program text. */ ! 27: ! 28: #include "defs.h" ! 29: #include "p1defs.h" ! 30: #include "format.h" ! 31: #include "output.h" ! 32: #include "names.h" ! 33: #include "iob.h" ! 34: ! 35: int c_output_line_length = DEF_C_LINE_LENGTH; ! 36: ! 37: int last_was_label; /* Boolean used to generate semicolons ! 38: when a label terminates a block */ ! 39: static char this_proc_name[52]; /* Name of the current procedure. This is ! 40: probably too simplistic to handle ! 41: multiple entry points */ ! 42: ! 43: static int p1getd(), p1gets(), p1getf(), get_p1_token(); ! 44: static int p1get_const(), p1getn(); ! 45: static expptr do_format(), do_p1_name_pointer(), do_p1_const(); ! 46: static expptr do_p1_expr(), do_p1_ident(), do_p1_charp(), do_p1_extern(); ! 47: static expptr do_p1_head(), do_p1_list(), do_p1_literal(); ! 48: static void do_p1_label(), do_p1_asgoto(), do_p1_goto(); ! 49: static void do_p1_if(), do_p1_else(), do_p1_elif(), do_p1_endif(); ! 50: static void do_p1_endelse(), do_p1_subr_ret(), do_p1_comp_goto(); ! 51: static void do_p1_for(), do_p1_end_for(), do_p1_fortran(); ! 52: static void do_p1_1while(), do_p1_2while(), do_p1_elseifstart(); ! 53: static void do_p1_comment(), do_p1_set_line(); ! 54: static expptr do_p1_addr(); ! 55: static void proto(); ! 56: void list_arg_types(); ! 57: chainp length_comp(); ! 58: void listargs(); ! 59: extern chainp assigned_fmts; ! 60: static char filename[P1_FILENAME_MAX]; ! 61: extern int gflag; ! 62: int gflag1; ! 63: extern char *parens; ! 64: ! 65: start_formatting () ! 66: { ! 67: FILE *infile; ! 68: static int wrote_one = 0; ! 69: extern int usedefsforcommon; ! 70: extern char *p1_file, *p1_bakfile; ! 71: ! 72: this_proc_name[0] = '\0'; ! 73: last_was_label = 0; ! 74: ei_next = ei_first; ! 75: wh_next = wh_first; ! 76: ! 77: (void) fclose (pass1_file); ! 78: if ((infile = fopen (p1_file, binread)) == NULL) ! 79: Fatal("start_formatting: couldn't open the intermediate file\n"); ! 80: ! 81: if (wrote_one) ! 82: nice_printf (c_file, "\n"); ! 83: ! 84: while (!feof (infile)) { ! 85: expptr this_expr; ! 86: ! 87: this_expr = do_format (infile, c_file); ! 88: if (this_expr) { ! 89: out_and_free_statement (c_file, this_expr); ! 90: } /* if this_expr */ ! 91: } /* while !feof infile */ ! 92: ! 93: (void) fclose (infile); ! 94: ! 95: if (last_was_label) ! 96: nice_printf (c_file, ";\n"); ! 97: ! 98: prev_tab (c_file); ! 99: gflag1 = 0; ! 100: if (this_proc_name[0]) ! 101: nice_printf (c_file, "} /* %s */\n", this_proc_name); ! 102: ! 103: ! 104: /* Write the #undefs for common variable reference */ ! 105: ! 106: if (usedefsforcommon) { ! 107: Extsym *ext; ! 108: int did_one = 0; ! 109: ! 110: for (ext = extsymtab; ext < nextext; ext++) ! 111: if (ext -> extstg == STGCOMMON && ext -> used_here) { ! 112: ext -> used_here = 0; ! 113: if (!did_one) ! 114: nice_printf (c_file, "\n"); ! 115: wr_abbrevs(c_file, 0, ext->extp); ! 116: did_one = 1; ! 117: ext -> extp = CHNULL; ! 118: } /* if */ ! 119: ! 120: if (did_one) ! 121: nice_printf (c_file, "\n"); ! 122: } /* if usedefsforcommon */ ! 123: ! 124: other_undefs(c_file); ! 125: ! 126: wrote_one = 1; ! 127: ! 128: /* For debugging only */ ! 129: ! 130: if (debugflag && (pass1_file = fopen (p1_bakfile, binwrite))) ! 131: if (infile = fopen (p1_file, binread)) { ! 132: ffilecopy (infile, pass1_file); ! 133: fclose (infile); ! 134: fclose (pass1_file); ! 135: } /* if infile */ ! 136: ! 137: /* End of "debugging only" */ ! 138: ! 139: scrub(p1_file); /* optionally unlink */ ! 140: ! 141: if ((pass1_file = fopen (p1_file, binwrite)) == NULL) ! 142: err ("start_formatting: couldn't reopen the pass1 file"); ! 143: ! 144: } /* start_formatting */ ! 145: ! 146: ! 147: static void ! 148: put_semi(outfile) ! 149: FILE *outfile; ! 150: { ! 151: nice_printf (outfile, ";\n"); ! 152: last_was_label = 0; ! 153: } ! 154: ! 155: #define SEM_CHECK(x) if (last_was_label) put_semi(x) ! 156: ! 157: /* do_format -- takes an input stream (a file in pass1 format) and writes ! 158: the appropriate C code to outfile when possible. When reading an ! 159: expression, the expression tree is returned instead. */ ! 160: ! 161: static expptr do_format (infile, outfile) ! 162: FILE *infile, *outfile; ! 163: { ! 164: int token_type, was_c_token; ! 165: expptr retval = ENULL; ! 166: ! 167: token_type = get_p1_token (infile); ! 168: was_c_token = 1; ! 169: switch (token_type) { ! 170: case P1_COMMENT: ! 171: do_p1_comment (infile, outfile); ! 172: was_c_token = 0; ! 173: break; ! 174: case P1_SET_LINE: ! 175: do_p1_set_line (infile); ! 176: was_c_token = 0; ! 177: break; ! 178: case P1_FILENAME: ! 179: p1gets(infile, filename, P1_FILENAME_MAX); ! 180: was_c_token = 0; ! 181: break; ! 182: case P1_NAME_POINTER: ! 183: retval = do_p1_name_pointer (infile); ! 184: break; ! 185: case P1_CONST: ! 186: retval = do_p1_const (infile); ! 187: break; ! 188: case P1_EXPR: ! 189: retval = do_p1_expr (infile, outfile); ! 190: break; ! 191: case P1_IDENT: ! 192: retval = do_p1_ident(infile); ! 193: break; ! 194: case P1_CHARP: ! 195: retval = do_p1_charp(infile); ! 196: break; ! 197: case P1_EXTERN: ! 198: retval = do_p1_extern (infile); ! 199: break; ! 200: case P1_HEAD: ! 201: gflag1 = 0; ! 202: retval = do_p1_head (infile, outfile); ! 203: gflag1 = gflag; ! 204: break; ! 205: case P1_LIST: ! 206: retval = do_p1_list (infile, outfile); ! 207: break; ! 208: case P1_LITERAL: ! 209: retval = do_p1_literal (infile); ! 210: break; ! 211: case P1_LABEL: ! 212: do_p1_label (infile, outfile); ! 213: /* last_was_label = 1; -- now set in do_p1_label */ ! 214: was_c_token = 0; ! 215: break; ! 216: case P1_ASGOTO: ! 217: do_p1_asgoto (infile, outfile); ! 218: break; ! 219: case P1_GOTO: ! 220: do_p1_goto (infile, outfile); ! 221: break; ! 222: case P1_IF: ! 223: do_p1_if (infile, outfile); ! 224: break; ! 225: case P1_ELSE: ! 226: SEM_CHECK(outfile); ! 227: do_p1_else (outfile); ! 228: break; ! 229: case P1_ELIF: ! 230: SEM_CHECK(outfile); ! 231: do_p1_elif (infile, outfile); ! 232: break; ! 233: case P1_ENDIF: ! 234: SEM_CHECK(outfile); ! 235: do_p1_endif (outfile); ! 236: break; ! 237: case P1_ENDELSE: ! 238: SEM_CHECK(outfile); ! 239: do_p1_endelse (outfile); ! 240: break; ! 241: case P1_ADDR: ! 242: retval = do_p1_addr (infile, outfile); ! 243: break; ! 244: case P1_SUBR_RET: ! 245: do_p1_subr_ret (infile, outfile); ! 246: break; ! 247: case P1_COMP_GOTO: ! 248: do_p1_comp_goto (infile, outfile); ! 249: break; ! 250: case P1_FOR: ! 251: do_p1_for (infile, outfile); ! 252: break; ! 253: case P1_ENDFOR: ! 254: SEM_CHECK(outfile); ! 255: do_p1_end_for (outfile); ! 256: break; ! 257: case P1_WHILE1START: ! 258: do_p1_1while(outfile); ! 259: break; ! 260: case P1_WHILE2START: ! 261: do_p1_2while(infile, outfile); ! 262: break; ! 263: case P1_PROCODE: ! 264: procode(outfile); ! 265: break; ! 266: case P1_ELSEIFSTART: ! 267: SEM_CHECK(outfile); ! 268: do_p1_elseifstart(outfile); ! 269: break; ! 270: case P1_FORTRAN: ! 271: do_p1_fortran(infile, outfile); ! 272: /* no break; */ ! 273: case P1_EOF: ! 274: was_c_token = 0; ! 275: break; ! 276: case P1_UNKNOWN: ! 277: Fatal("do_format: Unknown token type in intermediate file"); ! 278: break; ! 279: default: ! 280: Fatal("do_format: Bad token type in intermediate file"); ! 281: break; ! 282: } /* switch */ ! 283: ! 284: if (was_c_token) ! 285: last_was_label = 0; ! 286: return retval; ! 287: } /* do_format */ ! 288: ! 289: ! 290: static void ! 291: do_p1_comment (infile, outfile) ! 292: FILE *infile, *outfile; ! 293: { ! 294: extern int c_output_line_length, in_comment; ! 295: ! 296: char storage[COMMENT_BUFFER_SIZE + 1]; ! 297: int length; ! 298: ! 299: if (!p1gets(infile, storage, COMMENT_BUFFER_SIZE + 1)) ! 300: return; ! 301: ! 302: length = strlen (storage); ! 303: ! 304: gflag1 = 0; ! 305: in_comment = 1; ! 306: if (length > c_output_line_length - 6) ! 307: margin_printf (outfile, "/*%s*/\n", storage); ! 308: else ! 309: margin_printf (outfile, length ? "/* %s */\n" : "\n", storage); ! 310: in_comment = 0; ! 311: gflag1 = gflag; ! 312: } /* do_p1_comment */ ! 313: ! 314: static void ! 315: do_p1_set_line (infile) ! 316: FILE *infile; ! 317: { ! 318: int status; ! 319: long new_line_number = -1; ! 320: ! 321: status = p1getd (infile, &new_line_number); ! 322: ! 323: if (status == EOF) ! 324: err ("do_p1_set_line: Missing line number at end of file\n"); ! 325: else if (status == 0 || new_line_number == -1) ! 326: errl("do_p1_set_line: Illegal line number in intermediate file: %ld\n", ! 327: new_line_number); ! 328: else { ! 329: lineno = new_line_number; ! 330: } ! 331: } /* do_p1_set_line */ ! 332: ! 333: ! 334: static expptr do_p1_name_pointer (infile) ! 335: FILE *infile; ! 336: { ! 337: Namep namep = (Namep) NULL; ! 338: int status; ! 339: ! 340: status = p1getd (infile, (long *) &namep); ! 341: ! 342: if (status == EOF) ! 343: err ("do_p1_name_pointer: Missing pointer at end of file\n"); ! 344: else if (status == 0 || namep == (Namep) NULL) ! 345: erri ("do_p1_name_pointer: Illegal name pointer in p1 file: '%x'\n", ! 346: (int) namep); ! 347: ! 348: return (expptr) namep; ! 349: } /* do_p1_name_pointer */ ! 350: ! 351: ! 352: ! 353: static expptr do_p1_const (infile) ! 354: FILE *infile; ! 355: { ! 356: struct Constblock *c = (struct Constblock *) NULL; ! 357: long type = -1; ! 358: int status; ! 359: ! 360: status = p1getd (infile, &type); ! 361: ! 362: if (status == EOF) ! 363: err ("do_p1_const: Missing constant type at end of file\n"); ! 364: else if (status == 0) ! 365: errl("do_p1_const: Illegal constant type in p1 file: %ld\n", type); ! 366: else { ! 367: status = p1get_const (infile, (int)type, &c); ! 368: ! 369: if (status == EOF) { ! 370: err ("do_p1_const: Missing constant value at end of file\n"); ! 371: c = (struct Constblock *) NULL; ! 372: } else if (status == 0) { ! 373: err ("do_p1_const: Illegal constant value in p1 file\n"); ! 374: c = (struct Constblock *) NULL; ! 375: } /* else */ ! 376: } /* else */ ! 377: return (expptr) c; ! 378: } /* do_p1_const */ ! 379: ! 380: ! 381: static expptr do_p1_literal (infile) ! 382: FILE *infile; ! 383: { ! 384: int status; ! 385: long memno; ! 386: Addrp addrp; ! 387: ! 388: status = p1getd (infile, &memno); ! 389: ! 390: if (status == EOF) ! 391: err ("do_p1_literal: Missing memno at end of file"); ! 392: else if (status == 0) ! 393: err ("do_p1_literal: Missing memno in p1 file"); ! 394: else { ! 395: struct Literal *litp, *lastlit; ! 396: ! 397: addrp = ALLOC (Addrblock); ! 398: addrp -> tag = TADDR; ! 399: addrp -> vtype = TYUNKNOWN; ! 400: addrp -> Field = NULL; ! 401: ! 402: lastlit = litpool + nliterals; ! 403: for (litp = litpool; litp < lastlit; litp++) ! 404: if (litp -> litnum == memno) { ! 405: addrp -> vtype = litp -> littype; ! 406: *((union Constant *) &(addrp -> user)) = ! 407: *((union Constant *) &(litp -> litval)); ! 408: break; ! 409: } /* if litp -> litnum == memno */ ! 410: ! 411: addrp -> memno = memno; ! 412: addrp -> vstg = STGMEMNO; ! 413: addrp -> uname_tag = UNAM_CONST; ! 414: } /* else */ ! 415: ! 416: return (expptr) addrp; ! 417: } /* do_p1_literal */ ! 418: ! 419: ! 420: static void do_p1_label (infile, outfile) ! 421: FILE *infile, *outfile; ! 422: { ! 423: int status; ! 424: ftnint stateno; ! 425: char *user_label (); ! 426: struct Labelblock *L; ! 427: char *fmt; ! 428: ! 429: status = p1getd (infile, &stateno); ! 430: ! 431: if (status == EOF) ! 432: err ("do_p1_label: Missing label at end of file"); ! 433: else if (status == 0) ! 434: err ("do_p1_label: Missing label in p1 file "); ! 435: else if (stateno < 0) { /* entry */ ! 436: margin_printf(outfile, "\n%s:\n", user_label(stateno)); ! 437: last_was_label = 1; ! 438: } ! 439: else { ! 440: L = labeltab + stateno; ! 441: if (L->labused) { ! 442: fmt = "%s:\n"; ! 443: last_was_label = 1; ! 444: } ! 445: else ! 446: fmt = "/* %s: */\n"; ! 447: margin_printf(outfile, fmt, user_label(L->stateno)); ! 448: } /* else */ ! 449: } /* do_p1_label */ ! 450: ! 451: ! 452: ! 453: static void do_p1_asgoto (infile, outfile) ! 454: FILE *infile, *outfile; ! 455: { ! 456: expptr expr; ! 457: ! 458: expr = do_format (infile, outfile); ! 459: out_asgoto (outfile, expr); ! 460: ! 461: } /* do_p1_asgoto */ ! 462: ! 463: ! 464: static void do_p1_goto (infile, outfile) ! 465: FILE *infile, *outfile; ! 466: { ! 467: int status; ! 468: long stateno; ! 469: char *user_label (); ! 470: ! 471: status = p1getd (infile, &stateno); ! 472: ! 473: if (status == EOF) ! 474: err ("do_p1_goto: Missing goto label at end of file"); ! 475: else if (status == 0) ! 476: err ("do_p1_goto: Missing goto label in p1 file"); ! 477: else { ! 478: nice_printf (outfile, "goto %s;\n", user_label (stateno)); ! 479: } /* else */ ! 480: } /* do_p1_goto */ ! 481: ! 482: ! 483: static void do_p1_if (infile, outfile) ! 484: FILE *infile, *outfile; ! 485: { ! 486: expptr cond; ! 487: ! 488: do { ! 489: cond = do_format (infile, outfile); ! 490: } while (cond == ENULL); ! 491: ! 492: out_if (outfile, cond); ! 493: } /* do_p1_if */ ! 494: ! 495: ! 496: static void do_p1_else (outfile) ! 497: FILE *outfile; ! 498: { ! 499: out_else (outfile); ! 500: } /* do_p1_else */ ! 501: ! 502: ! 503: static void do_p1_elif (infile, outfile) ! 504: FILE *infile, *outfile; ! 505: { ! 506: expptr cond; ! 507: ! 508: do { ! 509: cond = do_format (infile, outfile); ! 510: } while (cond == ENULL); ! 511: ! 512: elif_out (outfile, cond); ! 513: } /* do_p1_elif */ ! 514: ! 515: static void do_p1_endif (outfile) ! 516: FILE *outfile; ! 517: { ! 518: endif_out (outfile); ! 519: } /* do_p1_endif */ ! 520: ! 521: ! 522: static void do_p1_endelse (outfile) ! 523: FILE *outfile; ! 524: { ! 525: end_else_out (outfile); ! 526: } /* do_p1_endelse */ ! 527: ! 528: ! 529: static expptr do_p1_addr (infile, outfile) ! 530: FILE *infile, *outfile; ! 531: { ! 532: Addrp addrp = (Addrp) NULL; ! 533: int status; ! 534: ! 535: status = p1getn (infile, (int)sizeof(struct Addrblock), (char **) &addrp); ! 536: ! 537: if (status == EOF) ! 538: err ("do_p1_addr: Missing Addrp at end of file"); ! 539: else if (status == 0) ! 540: err ("do_p1_addr: Missing Addrp in p1 file"); ! 541: else if (addrp == (Addrp) NULL) ! 542: err ("do_p1_addr: Null addrp in p1 file"); ! 543: else if (addrp -> tag != TADDR) ! 544: erri ("do_p1_addr: bad tag in p1 file '%d'", addrp -> tag); ! 545: else { ! 546: addrp -> vleng = do_format (infile, outfile); ! 547: addrp -> memoffset = do_format (infile, outfile); ! 548: } ! 549: ! 550: return (expptr) addrp; ! 551: } /* do_p1_addr */ ! 552: ! 553: ! 554: ! 555: static void do_p1_subr_ret (infile, outfile) ! 556: FILE *infile, *outfile; ! 557: { ! 558: expptr retval; ! 559: ! 560: nice_printf (outfile, "return "); ! 561: retval = do_format (infile, outfile); ! 562: if (!multitype) ! 563: if (retval) ! 564: expr_out (outfile, retval); ! 565: ! 566: nice_printf (outfile, ";\n"); ! 567: } /* do_p1_subr_ret */ ! 568: ! 569: ! 570: ! 571: static void do_p1_comp_goto (infile, outfile) ! 572: FILE *infile, *outfile; ! 573: { ! 574: expptr index; ! 575: expptr labels; ! 576: ! 577: index = do_format (infile, outfile); ! 578: ! 579: if (index == ENULL) { ! 580: err ("do_p1_comp_goto: no expression for computed goto"); ! 581: return; ! 582: } /* if index == ENULL */ ! 583: ! 584: labels = do_format (infile, outfile); ! 585: ! 586: if (labels && labels -> tag != TLIST) ! 587: erri ("do_p1_comp_goto: expected list, got tag '%d'", labels -> tag); ! 588: else ! 589: compgoto_out (outfile, index, labels); ! 590: } /* do_p1_comp_goto */ ! 591: ! 592: ! 593: static void do_p1_for (infile, outfile) ! 594: FILE *infile, *outfile; ! 595: { ! 596: expptr init, test, inc; ! 597: ! 598: init = do_format (infile, outfile); ! 599: test = do_format (infile, outfile); ! 600: inc = do_format (infile, outfile); ! 601: ! 602: out_for (outfile, init, test, inc); ! 603: } /* do_p1_for */ ! 604: ! 605: static void do_p1_end_for (outfile) ! 606: FILE *outfile; ! 607: { ! 608: out_end_for (outfile); ! 609: } /* do_p1_end_for */ ! 610: ! 611: ! 612: static void ! 613: do_p1_fortran(infile, outfile) ! 614: FILE *infile, *outfile; ! 615: { ! 616: char buf[P1_STMTBUFSIZE]; ! 617: if (!p1gets(infile, buf, P1_STMTBUFSIZE)) ! 618: return; ! 619: /* bypass nice_printf nonsense */ ! 620: fprintf(outfile, "/*< %s >*/\n", buf+1); /* + 1 to skip by '$' */ ! 621: } ! 622: ! 623: ! 624: static expptr do_p1_expr (infile, outfile) ! 625: FILE *infile, *outfile; ! 626: { ! 627: int status; ! 628: long opcode, type; ! 629: struct Exprblock *result = (struct Exprblock *) NULL; ! 630: ! 631: status = p1getd (infile, &opcode); ! 632: ! 633: if (status == EOF) ! 634: err ("do_p1_expr: Missing expr opcode at end of file"); ! 635: else if (status == 0) ! 636: err ("do_p1_expr: Missing expr opcode in p1 file"); ! 637: else { ! 638: ! 639: status = p1getd (infile, &type); ! 640: ! 641: if (status == EOF) ! 642: err ("do_p1_expr: Missing expr type at end of file"); ! 643: else if (status == 0) ! 644: err ("do_p1_expr: Missing expr type in p1 file"); ! 645: else if (opcode == 0) ! 646: return ENULL; ! 647: else { ! 648: result = ALLOC (Exprblock); ! 649: ! 650: result -> tag = TEXPR; ! 651: result -> vtype = type; ! 652: result -> opcode = opcode; ! 653: result -> vleng = do_format (infile, outfile); ! 654: ! 655: if (is_unary_op (opcode)) ! 656: result -> leftp = do_format (infile, outfile); ! 657: else if (is_binary_op (opcode)) { ! 658: result -> leftp = do_format (infile, outfile); ! 659: result -> rightp = do_format (infile, outfile); ! 660: } else ! 661: errl("do_p1_expr: Illegal opcode %ld", opcode); ! 662: } /* else */ ! 663: } /* else */ ! 664: ! 665: return (expptr) result; ! 666: } /* do_p1_expr */ ! 667: ! 668: ! 669: static expptr do_p1_ident(infile) ! 670: FILE *infile; ! 671: { ! 672: Addrp addrp; ! 673: int status; ! 674: long vtype, vstg; ! 675: ! 676: addrp = ALLOC (Addrblock); ! 677: addrp -> tag = TADDR; ! 678: ! 679: status = p1getd (infile, &vtype); ! 680: if (status == EOF) ! 681: err ("do_p1_ident: Missing identifier type at end of file\n"); ! 682: else if (status == 0 || vtype < 0 || vtype >= NTYPES) ! 683: errl("do_p1_ident: Bad type in intermediate file: %ld\n", vtype); ! 684: else ! 685: addrp -> vtype = vtype; ! 686: ! 687: status = p1getd (infile, &vstg); ! 688: if (status == EOF) ! 689: err ("do_p1_ident: Missing identifier storage at end of file\n"); ! 690: else if (status == 0 || vstg < 0 || vstg > STGNULL) ! 691: errl("do_p1_ident: Bad storage in intermediate file: %ld\n", vtype); ! 692: else ! 693: addrp -> vstg = vstg; ! 694: ! 695: status = p1gets(infile, addrp->user.ident, IDENT_LEN); ! 696: ! 697: if (status == EOF) ! 698: err ("do_p1_ident: Missing ident string at end of file"); ! 699: else if (status == 0) ! 700: err ("do_p1_ident: Missing ident string in intermediate file"); ! 701: addrp->uname_tag = UNAM_IDENT; ! 702: return (expptr) addrp; ! 703: } /* do_p1_ident */ ! 704: ! 705: static expptr do_p1_charp(infile) ! 706: FILE *infile; ! 707: { ! 708: Addrp addrp; ! 709: int status; ! 710: long vtype, vstg; ! 711: char buf[64]; ! 712: ! 713: addrp = ALLOC (Addrblock); ! 714: addrp -> tag = TADDR; ! 715: ! 716: status = p1getd (infile, &vtype); ! 717: if (status == EOF) ! 718: err ("do_p1_ident: Missing identifier type at end of file\n"); ! 719: else if (status == 0 || vtype < 0 || vtype >= NTYPES) ! 720: errl("do_p1_ident: Bad type in intermediate file: %ld\n", vtype); ! 721: else ! 722: addrp -> vtype = vtype; ! 723: ! 724: status = p1getd (infile, &vstg); ! 725: if (status == EOF) ! 726: err ("do_p1_ident: Missing identifier storage at end of file\n"); ! 727: else if (status == 0 || vstg < 0 || vstg > STGNULL) ! 728: errl("do_p1_ident: Bad storage in intermediate file: %ld\n", vtype); ! 729: else ! 730: addrp -> vstg = vstg; ! 731: ! 732: status = p1gets(infile, buf, (int)sizeof(buf)); ! 733: ! 734: if (status == EOF) ! 735: err ("do_p1_ident: Missing charp ident string at end of file"); ! 736: else if (status == 0) ! 737: err ("do_p1_ident: Missing charp ident string in intermediate file"); ! 738: addrp->uname_tag = UNAM_CHARP; ! 739: addrp->user.Charp = strcpy(mem(strlen(buf)+1,0), buf); ! 740: return (expptr) addrp; ! 741: } ! 742: ! 743: ! 744: static expptr do_p1_extern (infile) ! 745: FILE *infile; ! 746: { ! 747: Addrp addrp; ! 748: ! 749: addrp = ALLOC (Addrblock); ! 750: if (addrp) { ! 751: int status; ! 752: ! 753: addrp->tag = TADDR; ! 754: addrp->vstg = STGEXT; ! 755: addrp->uname_tag = UNAM_EXTERN; ! 756: status = p1getd (infile, &(addrp -> memno)); ! 757: if (status == EOF) ! 758: err ("do_p1_extern: Missing memno at end of file"); ! 759: else if (status == 0) ! 760: err ("do_p1_extern: Missing memno in intermediate file"); ! 761: if (addrp->vtype = extsymtab[addrp->memno].extype) ! 762: addrp->vclass = CLPROC; ! 763: } /* if addrp */ ! 764: ! 765: return (expptr) addrp; ! 766: } /* do_p1_extern */ ! 767: ! 768: ! 769: ! 770: static expptr do_p1_head (infile, outfile) ! 771: FILE *infile, *outfile; ! 772: { ! 773: int status; ! 774: int add_n_; ! 775: long class; ! 776: char storage[256]; ! 777: ! 778: status = p1getd (infile, &class); ! 779: if (status == EOF) ! 780: err ("do_p1_head: missing header class at end of file"); ! 781: else if (status == 0) ! 782: err ("do_p1_head: missing header class in p1 file"); ! 783: else { ! 784: status = p1gets (infile, storage, (int)sizeof(storage)); ! 785: if (status == EOF || status == 0) ! 786: storage[0] = '\0'; ! 787: } /* else */ ! 788: ! 789: if (class == CLPROC || class == CLMAIN) { ! 790: chainp lengths; ! 791: ! 792: add_n_ = nentry > 1; ! 793: lengths = length_comp(entries, add_n_); ! 794: ! 795: if (!add_n_ && protofile && class != CLMAIN) ! 796: protowrite(protofile, proctype, storage, entries, lengths); ! 797: ! 798: if (class == CLMAIN) ! 799: nice_printf (outfile, "/* Main program */ "); ! 800: else ! 801: nice_printf(outfile, "%s ", multitype ? "VOID" ! 802: : c_type_decl(proctype, 1)); ! 803: ! 804: nice_printf(outfile, add_n_ ? "%s0_" : "%s", storage); ! 805: if (!Ansi) { ! 806: listargs(outfile, entries, add_n_, lengths); ! 807: nice_printf (outfile, "\n"); ! 808: } ! 809: list_arg_types (outfile, entries, lengths, add_n_, "\n"); ! 810: nice_printf (outfile, "{\n"); ! 811: frchain(&lengths); ! 812: next_tab (outfile); ! 813: strcpy(this_proc_name, storage); ! 814: list_decls (outfile); ! 815: ! 816: } else if (class == CLBLOCK) ! 817: next_tab (outfile); ! 818: else ! 819: errl("do_p1_head: got class %ld", class); ! 820: ! 821: return NULL; ! 822: } /* do_p1_head */ ! 823: ! 824: ! 825: static expptr do_p1_list (infile, outfile) ! 826: FILE *infile, *outfile; ! 827: { ! 828: long tag, type, count; ! 829: int status; ! 830: expptr result; ! 831: ! 832: status = p1getd (infile, &tag); ! 833: if (status == EOF) ! 834: err ("do_p1_list: missing list tag at end of file"); ! 835: else if (status == 0) ! 836: err ("do_p1_list: missing list tag in p1 file"); ! 837: else { ! 838: status = p1getd (infile, &type); ! 839: if (status == EOF) ! 840: err ("do_p1_list: missing list type at end of file"); ! 841: else if (status == 0) ! 842: err ("do_p1_list: missing list type in p1 file"); ! 843: else { ! 844: status = p1getd (infile, &count); ! 845: if (status == EOF) ! 846: err ("do_p1_list: missing count at end of file"); ! 847: else if (status == 0) ! 848: err ("do_p1_list: missing count in p1 file"); ! 849: } /* else */ ! 850: } /* else */ ! 851: ! 852: result = (expptr) ALLOC (Listblock); ! 853: if (result) { ! 854: chainp pointer; ! 855: ! 856: result -> tag = tag; ! 857: result -> listblock.vtype = type; ! 858: ! 859: /* Assume there will be enough data */ ! 860: ! 861: if (count--) { ! 862: pointer = result->listblock.listp = ! 863: mkchain((char *)do_format(infile, outfile), CHNULL); ! 864: while (count--) { ! 865: pointer -> nextp = ! 866: mkchain((char *)do_format(infile, outfile), CHNULL); ! 867: pointer = pointer -> nextp; ! 868: } /* while (count--) */ ! 869: } /* if (count) */ ! 870: } /* if (result) */ ! 871: ! 872: return result; ! 873: } /* do_p1_list */ ! 874: ! 875: ! 876: chainp length_comp(e, add_n) /* get lengths of characters args */ ! 877: struct Entrypoint *e; ! 878: int add_n; ! 879: { ! 880: chainp lengths; ! 881: chainp args, args1; ! 882: Namep arg, np; ! 883: int nchargs; ! 884: Argtypes *at; ! 885: Atype *a; ! 886: extern int init_ac[TYSUBR+1]; ! 887: ! 888: if (!e) ! 889: return 0; /* possible only with errors */ ! 890: args = args1 = add_n ? allargs : e->arglist; ! 891: nchargs = 0; ! 892: for (lengths = NULL; args; args = args -> nextp) ! 893: if (arg = (Namep)args->datap) { ! 894: if (arg->vclass == CLUNKNOWN) ! 895: arg->vclass = CLVAR; ! 896: if (arg->vtype == TYCHAR && arg->vclass != CLPROC) { ! 897: lengths = mkchain((char *)arg, lengths); ! 898: nchargs++; ! 899: } ! 900: } ! 901: if (!add_n && (np = e->enamep)) { ! 902: /* one last check -- by now we know all we ever will ! 903: * about external args... ! 904: */ ! 905: save_argtypes(e->arglist, &e->entryname->arginfo, ! 906: &np->arginfo, 0, np->fvarname, STGEXT, nchargs, ! 907: np->vtype, 1); ! 908: at = e->entryname->arginfo; ! 909: a = at->atypes + init_ac[np->vtype]; ! 910: for(; args1; a++, args1 = args1->nextp) { ! 911: frchain(&a->cp); ! 912: if (arg = (Namep)args1->datap) ! 913: switch(arg->vclass) { ! 914: case CLPROC: ! 915: if (arg->vimpltype ! 916: && a->type >= 300) ! 917: a->type = TYUNKNOWN + 200; ! 918: break; ! 919: case CLUNKNOWN: ! 920: a->type %= 100; ! 921: } ! 922: } ! 923: } ! 924: return revchain(lengths); ! 925: } ! 926: ! 927: void listargs(outfile, entryp, add_n_, lengths) ! 928: FILE *outfile; ! 929: struct Entrypoint *entryp; ! 930: int add_n_; ! 931: chainp lengths; ! 932: { ! 933: chainp args; ! 934: char *s; ! 935: Namep arg; ! 936: int did_one = 0; ! 937: ! 938: nice_printf (outfile, "("); ! 939: ! 940: if (add_n_) { ! 941: nice_printf(outfile, "n__"); ! 942: did_one = 1; ! 943: args = allargs; ! 944: } ! 945: else { ! 946: if (!entryp) ! 947: return; /* possible only with errors */ ! 948: args = entryp->arglist; ! 949: } ! 950: ! 951: if (multitype) ! 952: { ! 953: nice_printf(outfile, ", ret_val"); ! 954: did_one = 1; ! 955: args = allargs; ! 956: } ! 957: else if (ONEOF(proctype, MSKCOMPLEX|MSKCHAR)) ! 958: { ! 959: s = xretslot[proctype]->user.ident; ! 960: nice_printf(outfile, did_one ? ", %s" : "%s", ! 961: *s == '(' /*)*/ ? "r_v" : s); ! 962: did_one = 1; ! 963: if (proctype == TYCHAR) ! 964: nice_printf (outfile, ", ret_val_len"); ! 965: } ! 966: for (; args; args = args -> nextp) ! 967: if (arg = (Namep)args->datap) { ! 968: nice_printf (outfile, "%s", did_one ? ", " : ""); ! 969: out_name (outfile, arg); ! 970: did_one = 1; ! 971: } ! 972: ! 973: for (args = lengths; args; args = args -> nextp) ! 974: nice_printf(outfile, ", %s", ! 975: new_arg_length((Namep)args->datap)); ! 976: nice_printf (outfile, ")"); ! 977: } /* listargs */ ! 978: ! 979: ! 980: void list_arg_types(outfile, entryp, lengths, add_n_, finalnl) ! 981: FILE *outfile; ! 982: struct Entrypoint *entryp; ! 983: chainp lengths; ! 984: int add_n_; ! 985: char *finalnl; ! 986: { ! 987: chainp args; ! 988: int last_type = -1, last_class = -1; ! 989: int did_one = 0, done_one, is_ext; ! 990: char *s, *sep = "", *sep1; ! 991: ! 992: if (outfile == (FILE *) NULL) { ! 993: err ("list_arg_types: null output file"); ! 994: return; ! 995: } else if (entryp == (struct Entrypoint *) NULL) { ! 996: err ("list_arg_types: null procedure entry pointer"); ! 997: return; ! 998: } /* else */ ! 999: ! 1000: if (Ansi) { ! 1001: done_one = 0; ! 1002: sep1 = ", "; ! 1003: nice_printf(outfile, "(" /*)*/); ! 1004: } ! 1005: else { ! 1006: done_one = 1; ! 1007: sep1 = ";\n"; ! 1008: } ! 1009: args = entryp->arglist; ! 1010: if (add_n_) { ! 1011: nice_printf(outfile, "int n__"); ! 1012: did_one = done_one; ! 1013: sep = sep1; ! 1014: args = allargs; ! 1015: } ! 1016: if (multitype) { ! 1017: nice_printf(outfile, "%sMultitype *ret_val", sep); ! 1018: did_one = done_one; ! 1019: sep = sep1; ! 1020: } ! 1021: else if (ONEOF (proctype, MSKCOMPLEX|MSKCHAR)) { ! 1022: s = xretslot[proctype]->user.ident; ! 1023: nice_printf(outfile, "%s%s *%s", sep, c_type_decl(proctype, 0), ! 1024: *s == '(' /*)*/ ? "r_v" : s); ! 1025: did_one = done_one; ! 1026: sep = sep1; ! 1027: if (proctype == TYCHAR) ! 1028: nice_printf (outfile, "%sftnlen ret_val_len", sep); ! 1029: } /* if ONEOF proctype */ ! 1030: for (; args; args = args -> nextp) { ! 1031: Namep arg = (Namep) args->datap; ! 1032: ! 1033: /* Scalars are passed by reference, and arrays will have their lower bound ! 1034: adjusted, so nearly everything is printed with a star in front. The ! 1035: exception is character lengths, which are passed by value. */ ! 1036: ! 1037: if (arg) { ! 1038: int type = arg -> vtype, class = arg -> vclass; ! 1039: ! 1040: if (class == CLPROC) ! 1041: if (arg->vimpltype) ! 1042: type = Castargs ? TYUNKNOWN : TYSUBR; ! 1043: else if (type == TYREAL && forcedouble && !Castargs) ! 1044: type = TYDREAL; ! 1045: ! 1046: if (type == last_type && class == last_class && did_one) ! 1047: nice_printf (outfile, ", "); ! 1048: else ! 1049: if ((is_ext = class == CLPROC) && Castargs) ! 1050: nice_printf(outfile, "%s%s ", sep, ! 1051: usedcasts[type] = casttypes[type]); ! 1052: else ! 1053: nice_printf(outfile, "%s%s ", sep, ! 1054: c_type_decl(type, is_ext)); ! 1055: if (class == CLPROC) ! 1056: if (Castargs) ! 1057: out_name(outfile, arg); ! 1058: else { ! 1059: nice_printf(outfile, "(*"); ! 1060: out_name(outfile, arg); ! 1061: nice_printf(outfile, ") %s", parens); ! 1062: } ! 1063: else { ! 1064: nice_printf (outfile, "*"); ! 1065: out_name (outfile, arg); ! 1066: } ! 1067: ! 1068: last_type = type; ! 1069: last_class = class; ! 1070: did_one = done_one; ! 1071: sep = sep1; ! 1072: } /* if (arg) */ ! 1073: } /* for args = entryp -> arglist */ ! 1074: ! 1075: for (args = lengths; args; args = args -> nextp) ! 1076: nice_printf(outfile, "%sftnlen %s", sep, ! 1077: new_arg_length((Namep)args->datap)); ! 1078: if (did_one) ! 1079: nice_printf (outfile, ";\n"); ! 1080: else if (Ansi) ! 1081: nice_printf(outfile, ! 1082: /*((*/ sep != sep1 && Ansi == 1 ? "void)%s" : ")%s", ! 1083: finalnl); ! 1084: } /* list_arg_types */ ! 1085: ! 1086: static void ! 1087: write_formats(outfile) ! 1088: FILE *outfile; ! 1089: { ! 1090: register struct Labelblock *lp; ! 1091: int first = 1; ! 1092: char *fs; ! 1093: ! 1094: for(lp = labeltab ; lp < highlabtab ; ++lp) ! 1095: if (lp->fmtlabused) { ! 1096: if (first) { ! 1097: first = 0; ! 1098: nice_printf(outfile, "/* Format strings */\n"); ! 1099: } ! 1100: nice_printf(outfile, "static char fmt_%ld[] = \"", ! 1101: lp->stateno); ! 1102: if (!(fs = lp->fmtstring)) ! 1103: fs = ""; ! 1104: nice_printf(outfile, "%s\";\n", fs); ! 1105: } ! 1106: if (!first) ! 1107: nice_printf(outfile, "\n"); ! 1108: } ! 1109: ! 1110: static void ! 1111: write_ioblocks(outfile) ! 1112: FILE *outfile; ! 1113: { ! 1114: register iob_data *L; ! 1115: register char *f, **s, *sep; ! 1116: ! 1117: nice_printf(outfile, "/* Fortran I/O blocks */\n"); ! 1118: L = iob_list = (iob_data *)revchain((chainp)iob_list); ! 1119: do { ! 1120: nice_printf(outfile, "static %s %s = { ", ! 1121: L->type, L->name); ! 1122: sep = 0; ! 1123: for(s = L->fields; f = *s; s++) { ! 1124: if (sep) ! 1125: nice_printf(outfile, sep); ! 1126: sep = ", "; ! 1127: if (*f == '"') { /* kludge */ ! 1128: nice_printf(outfile, "\""); ! 1129: nice_printf(outfile, "%s\"", f+1); ! 1130: } ! 1131: else ! 1132: nice_printf(outfile, "%s", f); ! 1133: } ! 1134: nice_printf(outfile, " };\n"); ! 1135: } ! 1136: while(L = L->next); ! 1137: nice_printf(outfile, "\n\n"); ! 1138: } ! 1139: ! 1140: static void ! 1141: write_assigned_fmts(outfile) ! 1142: FILE *outfile; ! 1143: { ! 1144: register chainp cp; ! 1145: Namep np; ! 1146: int did_one = 0; ! 1147: ! 1148: cp = assigned_fmts = revchain(assigned_fmts); ! 1149: nice_printf(outfile, "/* Assigned format variables */\nchar "); ! 1150: do { ! 1151: np = (Namep)cp->datap; ! 1152: if (did_one) ! 1153: nice_printf(outfile, ", "); ! 1154: did_one = 1; ! 1155: nice_printf(outfile, "*%s_fmt", np->fvarname); ! 1156: } ! 1157: while(cp = cp->nextp); ! 1158: nice_printf(outfile, ";\n\n"); ! 1159: } ! 1160: ! 1161: static char * ! 1162: to_upper(s) ! 1163: register char *s; ! 1164: { ! 1165: static char buf[64]; ! 1166: register char *t = buf; ! 1167: register int c; ! 1168: while(*t++ = (c = *s++) >= 'a' && c <= 'z' ? c + 'A' - 'a' : c); ! 1169: return buf; ! 1170: } ! 1171: ! 1172: ! 1173: /* This routine creates static structures representing a namelist. ! 1174: Declarations of the namelist and related structures are: ! 1175: ! 1176: struct Vardesc { ! 1177: char *name; ! 1178: char *addr; ! 1179: ftnlen *dims; /* laid out as struct dimensions below *//* ! 1180: int type; ! 1181: }; ! 1182: typedef struct Vardesc Vardesc; ! 1183: ! 1184: struct Namelist { ! 1185: char *name; ! 1186: Vardesc **vars; ! 1187: int nvars; ! 1188: }; ! 1189: ! 1190: struct dimensions ! 1191: { ! 1192: ftnlen numberofdimensions; ! 1193: ftnlen numberofelements ! 1194: ftnlen baseoffset; ! 1195: ftnlen span[numberofdimensions-1]; ! 1196: }; ! 1197: ! 1198: If dims is not null, then the corner element of the array is at ! 1199: addr. However, the element with subscripts (i1,...,in) is at ! 1200: addr + sizeoftype * (i1+span[0]*(i2+span[1]*...) - dimp->baseoffset) ! 1201: */ ! 1202: ! 1203: static void ! 1204: write_namelists(nmch, outfile) ! 1205: chainp nmch; ! 1206: FILE *outfile; ! 1207: { ! 1208: Namep var; ! 1209: struct Hashentry *entry; ! 1210: struct Dimblock *dimp; ! 1211: int i, nd, type; ! 1212: char *comma, *name; ! 1213: register chainp q; ! 1214: register Namep v; ! 1215: extern int typeconv[]; ! 1216: ! 1217: nice_printf(outfile, "/* Namelist stuff */\n\n"); ! 1218: for (entry = hashtab; entry < lasthash; ++entry) { ! 1219: if (!(v = entry->varp) || !v->vnamelist) ! 1220: continue; ! 1221: type = v->vtype; ! 1222: name = v->cvarname; ! 1223: if (dimp = v->vdim) { ! 1224: nd = dimp->ndim; ! 1225: nice_printf(outfile, ! 1226: "static ftnlen %s_dims[] = { %d, %ld, %ld", ! 1227: name, nd, ! 1228: dimp->nelt->constblock.Const.ci, ! 1229: dimp->baseoffset->constblock.Const.ci); ! 1230: for(i = 0, --nd; i < nd; i++) ! 1231: nice_printf(outfile, ", %ld", ! 1232: dimp->dims[i].dimsize->constblock.Const.ci); ! 1233: nice_printf(outfile, " };\n"); ! 1234: } ! 1235: nice_printf(outfile, "static Vardesc %s_dv = { \"%s\", %s", ! 1236: name, to_upper(v->fvarname), ! 1237: type == TYCHAR ? "" ! 1238: : (dimp || oneof_stg(v,v->vstg, ! 1239: M(STGEQUIV)|M(STGCOMMON))) ! 1240: ? "(char *)" : "(char *)&"); ! 1241: out_name(outfile, v); ! 1242: nice_printf(outfile, dimp ? ", %s_dims" : ", (ftnlen *)0", name); ! 1243: nice_printf(outfile, ", %ld };\n", ! 1244: type != TYCHAR ? (long)typeconv[type] ! 1245: : -v->vleng->constblock.Const.ci); ! 1246: } ! 1247: ! 1248: do { ! 1249: var = (Namep)nmch->datap; ! 1250: name = var->cvarname; ! 1251: nice_printf(outfile, "\nstatic Vardesc *%s_vl[] = ", name); ! 1252: comma = "{"; ! 1253: i = 0; ! 1254: for(q = var->varxptr.namelist ; q ; q = q->nextp) { ! 1255: v = (Namep)q->datap; ! 1256: if (!v->vnamelist) ! 1257: continue; ! 1258: i++; ! 1259: nice_printf(outfile, "%s &%s_dv", comma, v->cvarname); ! 1260: comma = ","; ! 1261: } ! 1262: nice_printf(outfile, " };\n"); ! 1263: nice_printf(outfile, ! 1264: "static Namelist %s = { \"%s\", %s_vl, %d };\n", ! 1265: name, to_upper(var->fvarname), name, i); ! 1266: } ! 1267: while(nmch = nmch->nextp); ! 1268: nice_printf(outfile, "\n"); ! 1269: } ! 1270: ! 1271: /* fixextype tries to infer from usage in previous procedures ! 1272: the type of an external procedure declared ! 1273: external and passed as an argument but never typed or invoked. ! 1274: */ ! 1275: ! 1276: static int ! 1277: fixexttype(var) ! 1278: Namep var; ! 1279: { ! 1280: Extsym *e; ! 1281: int type, type1; ! 1282: extern void changedtype(); ! 1283: ! 1284: type = var->vtype; ! 1285: e = &extsymtab[var->vardesc.varno]; ! 1286: if ((type1 = e->extype) && type == TYUNKNOWN) ! 1287: return var->vtype = type1; ! 1288: if (var->visused) { ! 1289: if (e->exused && type != type1) ! 1290: changedtype(var); ! 1291: e->exused = 1; ! 1292: e->extype = type; ! 1293: } ! 1294: return type; ! 1295: } ! 1296: ! 1297: static void ! 1298: ref_defs(outfile, refdefs) FILE *outfile; chainp refdefs; ! 1299: { ! 1300: chainp cp; ! 1301: int eb, i, j, n; ! 1302: struct Dimblock *dimp; ! 1303: long L; ! 1304: expptr b, vl; ! 1305: Namep var; ! 1306: char *amp, *comma; ! 1307: ! 1308: ind_printf(0, outfile, "\n"); ! 1309: for(cp = refdefs = revchain(refdefs); cp; cp = cp->nextp) { ! 1310: var = (Namep)cp->datap; ! 1311: cp->datap = 0; ! 1312: amp = "_subscr"; ! 1313: if (!(eb = var->vsubscrused)) { ! 1314: var->vrefused = 0; ! 1315: if (!ISCOMPLEX(var->vtype)) ! 1316: amp = "_ref"; ! 1317: } ! 1318: def_start(outfile, var->cvarname, amp, CNULL); ! 1319: dimp = var->vdim; ! 1320: vl = 0; ! 1321: comma = "("; ! 1322: amp = ""; ! 1323: if (var->vtype == TYCHAR) { ! 1324: amp = "&"; ! 1325: vl = var->vleng; ! 1326: if (ISCONST(vl) && vl->constblock.Const.ci == 1) ! 1327: vl = 0; ! 1328: nice_printf(outfile, "%sa_0", comma); ! 1329: comma = ","; ! 1330: } ! 1331: n = dimp->ndim; ! 1332: for(i = 1; i <= n; i++, comma = ",") ! 1333: nice_printf(outfile, "%sa_%d", comma, i); ! 1334: nice_printf(outfile, ") %s", amp); ! 1335: if (var->vsubscrused) ! 1336: var->vsubscrused = 0; ! 1337: else if (!ISCOMPLEX(var->vtype)) { ! 1338: out_name(outfile, var); ! 1339: nice_printf(outfile, "[%s", vl ? "(" : ""); ! 1340: } ! 1341: for(j = 2; j < n; j++) ! 1342: nice_printf(outfile, "("); ! 1343: while(--i > 1) { ! 1344: nice_printf(outfile, "(a_%d)%s*", i, i == n ? "" : ")"); ! 1345: expr_out(outfile, cpexpr(dimp->dims[i-2].dimsize)); ! 1346: nice_printf(outfile, " + "); ! 1347: } ! 1348: nice_printf(outfile, "a_1"); ! 1349: if (var->vtype == TYCHAR) { ! 1350: if (vl) { ! 1351: nice_printf(outfile, ")*"); ! 1352: expr_out(outfile, cpexpr(vl)); ! 1353: } ! 1354: nice_printf(outfile, " + a_0"); ! 1355: } ! 1356: if (var->vstg != STGARG && (b = dimp->baseoffset)) { ! 1357: b = cpexpr(b); ! 1358: if (var->vtype == TYCHAR) ! 1359: b = mkexpr(OPSTAR, cpexpr(var->vleng), b); ! 1360: nice_printf(outfile, " - "); ! 1361: expr_out(outfile, b); ! 1362: } ! 1363: if (ISCOMPLEX(var->vtype)) { ! 1364: ind_printf(0, outfile, "\n"); ! 1365: def_start(outfile, var->cvarname, "_ref", CNULL); ! 1366: comma = "("; ! 1367: for(i = 1; i <= n; i++, comma = ",") ! 1368: nice_printf(outfile, "%sa_%d", comma, i); ! 1369: nice_printf(outfile, ") %s[%s_subscr", ! 1370: var->cvarname, var->cvarname); ! 1371: comma = "("; ! 1372: for(i = 1; i <= n; i++, comma = ",") ! 1373: nice_printf(outfile, "%sa_%d", comma, i); ! 1374: nice_printf(outfile, ")"); ! 1375: } ! 1376: ind_printf(0, outfile, "]\n" + eb); ! 1377: } ! 1378: nice_printf(outfile, "\n"); ! 1379: frchain(refdefs); ! 1380: } ! 1381: ! 1382: list_decls (outfile) ! 1383: FILE *outfile; ! 1384: { ! 1385: extern chainp used_builtins; ! 1386: extern struct Hashentry *hashtab; ! 1387: extern ftnint wr_char_len(); ! 1388: struct Hashentry *entry; ! 1389: int write_header = 1; ! 1390: int last_class = -1, last_stg = -1; ! 1391: Namep var; ! 1392: int Alias, Define, did_one, last_type, type; ! 1393: extern int def_equivs, useauto; ! 1394: extern chainp new_vars; /* Compiler-generated locals */ ! 1395: chainp namelists = 0, refdefs = 0; ! 1396: char *ctype; ! 1397: int useauto1 = useauto && !saveall; ! 1398: long x; ! 1399: extern int hsize; ! 1400: ! 1401: /* First write out the statically initialized data */ ! 1402: ! 1403: if (initfile) ! 1404: list_init_data(&initfile, initfname, outfile); ! 1405: ! 1406: /* Next come formats */ ! 1407: write_formats(outfile); ! 1408: ! 1409: /* Now write out the system-generated identifiers */ ! 1410: ! 1411: if (new_vars || nequiv) { ! 1412: chainp args, next_var, this_var; ! 1413: chainp nv[TYVOID], nv1[TYVOID]; ! 1414: int i, j; ! 1415: Addrp Var; ! 1416: Namep arg; ! 1417: ! 1418: /* zap unused dimension variables */ ! 1419: ! 1420: for(args = allargs; args; args = args->nextp) { ! 1421: arg = (Namep)args->datap; ! 1422: if (this_var = arg->vlastdim) { ! 1423: frexpr((tagptr)this_var->datap); ! 1424: this_var->datap = 0; ! 1425: } ! 1426: } ! 1427: ! 1428: /* sort new_vars by type, skipping entries just zapped */ ! 1429: ! 1430: for(i = TYADDR; i < TYVOID; i++) ! 1431: nv[i] = 0; ! 1432: for(this_var = new_vars; this_var; this_var = next_var) { ! 1433: next_var = this_var->nextp; ! 1434: if (Var = (Addrp)this_var->datap) { ! 1435: if (!(this_var->nextp = nv[j = Var->vtype])) ! 1436: nv1[j] = this_var; ! 1437: nv[j] = this_var; ! 1438: } ! 1439: else { ! 1440: this_var->nextp = 0; ! 1441: frchain(&this_var); ! 1442: } ! 1443: } ! 1444: new_vars = 0; ! 1445: for(i = TYVOID; --i >= TYADDR;) ! 1446: if (this_var = nv[i]) { ! 1447: nv1[i]->nextp = new_vars; ! 1448: new_vars = this_var; ! 1449: } ! 1450: ! 1451: /* write the declarations */ ! 1452: ! 1453: did_one = 0; ! 1454: last_type = -1; ! 1455: ! 1456: for (this_var = new_vars; this_var; this_var = this_var -> nextp) { ! 1457: Var = (Addrp) this_var->datap; ! 1458: ! 1459: if (Var == (Addrp) NULL) ! 1460: err ("list_decls: null variable"); ! 1461: else if (Var -> tag != TADDR) ! 1462: erri ("list_decls: bad tag on new variable '%d'", ! 1463: Var -> tag); ! 1464: ! 1465: type = nv_type (Var); ! 1466: if (Var->vstg == STGINIT ! 1467: || Var->uname_tag == UNAM_IDENT ! 1468: && *Var->user.ident == ' ' ! 1469: && multitype) ! 1470: continue; ! 1471: if (!did_one) ! 1472: nice_printf (outfile, "/* System generated locals */\n"); ! 1473: ! 1474: if (last_type == type && did_one) ! 1475: nice_printf (outfile, ", "); ! 1476: else { ! 1477: if (did_one) ! 1478: nice_printf (outfile, ";\n"); ! 1479: nice_printf (outfile, "%s ", ! 1480: c_type_decl (type, Var -> vclass == CLPROC)); ! 1481: } /* else */ ! 1482: ! 1483: /* Character type is really a string type. Put out a '*' for parameters ! 1484: with unknown length and functions returning character */ ! 1485: ! 1486: if (Var -> vtype == TYCHAR && (!ISICON ((Var -> vleng)) ! 1487: || Var -> vclass == CLPROC)) ! 1488: nice_printf (outfile, "*"); ! 1489: ! 1490: write_nv_ident(outfile, (Addrp)this_var->datap); ! 1491: if (Var -> vtype == TYCHAR && Var->vclass != CLPROC && ! 1492: ISICON((Var -> vleng)) ! 1493: && (i = Var->vleng->constblock.Const.ci) > 0) ! 1494: nice_printf (outfile, "[%d]", i); ! 1495: ! 1496: did_one = 1; ! 1497: last_type = nv_type (Var); ! 1498: } /* for this_var */ ! 1499: ! 1500: /* Handle the uninitialized equivalences */ ! 1501: ! 1502: do_uninit_equivs (outfile, &did_one); ! 1503: ! 1504: if (did_one) ! 1505: nice_printf (outfile, ";\n\n"); ! 1506: } /* if new_vars */ ! 1507: ! 1508: /* Write out builtin declarations */ ! 1509: ! 1510: if (used_builtins) { ! 1511: chainp cp; ! 1512: Extsym *es; ! 1513: ! 1514: last_type = -1; ! 1515: did_one = 0; ! 1516: ! 1517: nice_printf (outfile, "/* Builtin functions */"); ! 1518: ! 1519: for (cp = used_builtins; cp; cp = cp -> nextp) { ! 1520: Addrp e = (Addrp)cp->datap; ! 1521: ! 1522: switch(type = e->vtype) { ! 1523: case TYDREAL: ! 1524: case TYREAL: ! 1525: /* if (forcedouble || e->dbl_builtin) */ ! 1526: /* libF77 currently assumes everything double */ ! 1527: type = TYDREAL; ! 1528: ctype = "double"; ! 1529: break; ! 1530: case TYCOMPLEX: ! 1531: case TYDCOMPLEX: ! 1532: type = TYVOID; ! 1533: /* no break */ ! 1534: default: ! 1535: ctype = c_type_decl(type, 0); ! 1536: } ! 1537: ! 1538: if (did_one && last_type == type) ! 1539: nice_printf(outfile, ", "); ! 1540: else ! 1541: nice_printf(outfile, "%s\n%s ", did_one ? ";" : "", ctype); ! 1542: ! 1543: extern_out(outfile, es = &extsymtab[e -> memno]); ! 1544: proto(outfile, es->arginfo, es->fextname); ! 1545: last_type = type; ! 1546: did_one = 1; ! 1547: } /* for cp = used_builtins */ ! 1548: ! 1549: nice_printf (outfile, ";\n\n"); ! 1550: } /* if used_builtins */ ! 1551: ! 1552: last_type = -1; ! 1553: for (entry = hashtab; entry < lasthash; ++entry) { ! 1554: var = entry -> varp; ! 1555: ! 1556: if (var) { ! 1557: int procclass = var -> vprocclass; ! 1558: char *comment = NULL; ! 1559: int stg = var -> vstg; ! 1560: int class = var -> vclass; ! 1561: type = var -> vtype; ! 1562: ! 1563: if (var->vrefused) ! 1564: refdefs = mkchain((char *)var, refdefs); ! 1565: if (var->vsubscrused) ! 1566: if (ISCOMPLEX(var->vtype)) ! 1567: var->vsubscrused = 0; ! 1568: else ! 1569: refdefs = mkchain((char *)var, refdefs); ! 1570: if (ONEOF(stg, M(STGARG)|M(STGLENG)|M(STGINIT))) ! 1571: continue; ! 1572: ! 1573: if (useauto1 && stg == STGBSS && !var->vsave) ! 1574: stg = STGAUTO; ! 1575: ! 1576: switch (class) { ! 1577: case CLVAR: ! 1578: break; ! 1579: case CLPROC: ! 1580: switch(procclass) { ! 1581: case PTHISPROC: ! 1582: extsymtab[var->vardesc.varno].extype = type; ! 1583: continue; ! 1584: case PSTFUNCT: ! 1585: case PINTRINSIC: ! 1586: continue; ! 1587: case PUNKNOWN: ! 1588: err ("list_decls: unknown procedure class"); ! 1589: continue; ! 1590: case PEXTERNAL: ! 1591: if (stg == STGUNKNOWN) { ! 1592: warn1( ! 1593: "%.64s declared EXTERNAL but never used.", ! 1594: var->fvarname); ! 1595: /* to retain names declared EXTERNAL */ ! 1596: /* but not referenced, change ! 1597: /* "continue" to "stg = STGEXT" */ ! 1598: continue; ! 1599: } ! 1600: else ! 1601: type = fixexttype(var); ! 1602: } ! 1603: break; ! 1604: case CLUNKNOWN: ! 1605: /* declared but never used */ ! 1606: continue; ! 1607: case CLPARAM: ! 1608: continue; ! 1609: case CLNAMELIST: ! 1610: if (var->visused) ! 1611: namelists = mkchain((char *)var, namelists); ! 1612: continue; ! 1613: default: ! 1614: erri("list_decls: can't handle class '%d' yet", ! 1615: class); ! 1616: Fatal(var->fvarname); ! 1617: continue; ! 1618: } /* switch */ ! 1619: ! 1620: /* Might be equivalenced to a common. If not, don't process */ ! 1621: if (stg == STGCOMMON && !var->vcommequiv) ! 1622: continue; ! 1623: ! 1624: /* Only write the header if system-generated locals, builtins, or ! 1625: uninitialized equivs were already output */ ! 1626: ! 1627: if (write_header == 1 && (new_vars || nequiv || used_builtins) ! 1628: && oneof_stg ( var, stg, ! 1629: M(STGBSS)|M(STGEXT)|M(STGAUTO)|M(STGCOMMON)|M(STGEQUIV))) { ! 1630: nice_printf (outfile, "/* Local variables */\n"); ! 1631: write_header = 2; ! 1632: } ! 1633: ! 1634: ! 1635: Alias = oneof_stg(var, stg, M(STGEQUIV)|M(STGCOMMON)); ! 1636: if (Define = (Alias && def_equivs)) { ! 1637: if (!write_header) ! 1638: nice_printf(outfile, ";\n"); ! 1639: def_start(outfile, var->cvarname, CNULL, "("); ! 1640: goto Alias1; ! 1641: } ! 1642: else if (type == last_type && class == last_class && ! 1643: stg == last_stg && !write_header) ! 1644: nice_printf (outfile, ", "); ! 1645: else { ! 1646: if (!write_header && ONEOF(stg, M(STGBSS)| ! 1647: M(STGEXT)|M(STGAUTO)|M(STGEQUIV)|M(STGCOMMON))) ! 1648: nice_printf (outfile, ";\n"); ! 1649: ! 1650: switch (stg) { ! 1651: case STGARG: ! 1652: case STGLENG: ! 1653: /* Part of the argument list, don't write them out ! 1654: again */ ! 1655: continue; /* Go back to top of the loop */ ! 1656: case STGBSS: ! 1657: case STGEQUIV: ! 1658: case STGCOMMON: ! 1659: nice_printf (outfile, "static "); ! 1660: break; ! 1661: case STGEXT: ! 1662: nice_printf (outfile, "extern "); ! 1663: break; ! 1664: case STGAUTO: ! 1665: break; ! 1666: case STGINIT: ! 1667: case STGUNKNOWN: ! 1668: /* Don't want to touch the initialized data, that will ! 1669: be handled elsewhere. Unknown data have ! 1670: already been complained about, so skip them */ ! 1671: continue; ! 1672: default: ! 1673: erri("list_decls: can't handle storage class %d", ! 1674: stg); ! 1675: continue; ! 1676: } /* switch */ ! 1677: ! 1678: if (type == TYCHAR && halign && class != CLPROC ! 1679: && ISICON(var->vleng)) { ! 1680: nice_printf(outfile, "struct { %s fill; char val", ! 1681: halign); ! 1682: x = wr_char_len(outfile, var->vdim, ! 1683: var->vleng->constblock.Const.ci, 1); ! 1684: if (x %= hsize) ! 1685: nice_printf(outfile, "; char fill2[%ld]", ! 1686: hsize - x); ! 1687: nice_printf(outfile, "; } %s_st;\n", var->cvarname); ! 1688: def_start(outfile, var->cvarname, CNULL, var->cvarname); ! 1689: ind_printf(0, outfile, "_st.val\n"); ! 1690: last_type = -1; ! 1691: write_header = 2; ! 1692: continue; ! 1693: } ! 1694: nice_printf(outfile, "%s ", ! 1695: c_type_decl(type, class == CLPROC)); ! 1696: } /* else */ ! 1697: ! 1698: /* Character type is really a string type. Put out a '*' for variable ! 1699: length strings, and also for equivalences */ ! 1700: ! 1701: if (type == TYCHAR && class != CLPROC ! 1702: && (!var->vleng || !ISICON (var -> vleng)) ! 1703: || oneof_stg(var, stg, M(STGEQUIV)|M(STGCOMMON))) ! 1704: nice_printf (outfile, "*%s", var->cvarname); ! 1705: else { ! 1706: nice_printf (outfile, "%s", var->cvarname); ! 1707: if (class == CLPROC) { ! 1708: Argtypes *at; ! 1709: if (!(at = var->arginfo) ! 1710: && var->vprocclass == PEXTERNAL) ! 1711: at = extsymtab[var->vardesc.varno].arginfo; ! 1712: proto(outfile, at, var->fvarname); ! 1713: } ! 1714: else if (type == TYCHAR && ISICON ((var -> vleng))) ! 1715: wr_char_len(outfile, var->vdim, ! 1716: (int)var->vleng->constblock.Const.ci, 0); ! 1717: else if (var -> vdim && ! 1718: !oneof_stg (var, stg, M(STGEQUIV)|M(STGCOMMON))) ! 1719: comment = wr_ardecls(outfile, var->vdim, 1L); ! 1720: } ! 1721: ! 1722: if (comment) ! 1723: nice_printf (outfile, "%s", comment); ! 1724: Alias1: ! 1725: if (Alias) { ! 1726: char *amp, *lp, *name, *rp; ! 1727: char *equiv_name (); ! 1728: ftnint voff = var -> voffset; ! 1729: int et0, expr_type, k; ! 1730: Extsym *E; ! 1731: struct Equivblock *eb; ! 1732: char buf[16]; ! 1733: ! 1734: /* We DON'T want to use oneof_stg here, because we need to distinguish ! 1735: between them */ ! 1736: ! 1737: if (stg == STGEQUIV) { ! 1738: name = equiv_name(k = var->vardesc.varno, CNULL); ! 1739: eb = eqvclass + k; ! 1740: if (eb->eqvinit) { ! 1741: amp = "&"; ! 1742: et0 = TYERROR; ! 1743: } ! 1744: else { ! 1745: amp = ""; ! 1746: et0 = eb->eqvtype; ! 1747: } ! 1748: expr_type = et0; ! 1749: } ! 1750: else { ! 1751: E = &extsymtab[var->vardesc.varno]; ! 1752: sprintf(name = buf, "%s%d", E->cextname, E->curno); ! 1753: expr_type = type; ! 1754: et0 = -1; ! 1755: amp = "&"; ! 1756: } /* else */ ! 1757: ! 1758: if (!Define) ! 1759: nice_printf (outfile, " = "); ! 1760: if (voff) { ! 1761: k = typesize[type]; ! 1762: switch((int)(voff % k)) { ! 1763: case 0: ! 1764: voff /= k; ! 1765: expr_type = type; ! 1766: break; ! 1767: case SZSHORT: ! 1768: case SZSHORT+SZLONG: ! 1769: expr_type = TYSHORT; ! 1770: voff /= SZSHORT; ! 1771: break; ! 1772: case SZLONG: ! 1773: expr_type = TYLONG; ! 1774: voff /= SZLONG; ! 1775: break; ! 1776: default: ! 1777: expr_type = TYCHAR; ! 1778: } ! 1779: } ! 1780: ! 1781: if (expr_type == type) { ! 1782: lp = rp = ""; ! 1783: if (et0 == -1 && !voff) ! 1784: goto cast; ! 1785: } ! 1786: else { ! 1787: lp = "("; ! 1788: rp = ")"; ! 1789: cast: ! 1790: nice_printf(outfile, "(%s *)", c_type_decl(type, 0)); ! 1791: } ! 1792: ! 1793: /* Now worry about computing the offset */ ! 1794: ! 1795: if (voff) { ! 1796: if (expr_type == et0) ! 1797: nice_printf (outfile, "%s%s + %ld%s", ! 1798: lp, name, voff, rp); ! 1799: else ! 1800: nice_printf(outfile, "%s(%s *)%s%s + %ld%s", lp, ! 1801: c_type_decl (expr_type, 0), amp, ! 1802: name, voff, rp); ! 1803: } else ! 1804: nice_printf(outfile, "%s%s", amp, name); ! 1805: /* Always put these at the end of the line */ ! 1806: last_type = last_class = last_stg = -1; ! 1807: write_header = 0; ! 1808: if (Define) { ! 1809: ind_printf(0, outfile, ")\n"); ! 1810: write_header = 2; ! 1811: } ! 1812: continue; ! 1813: } ! 1814: write_header = 0; ! 1815: last_type = type; ! 1816: last_class = class; ! 1817: last_stg = stg; ! 1818: } /* if (var) */ ! 1819: } /* for (entry = hashtab */ ! 1820: ! 1821: if (!write_header) ! 1822: nice_printf (outfile, ";\n\n"); ! 1823: else if (write_header == 2) ! 1824: nice_printf(outfile, "\n"); ! 1825: ! 1826: /* Next, namelists, which may reference equivs */ ! 1827: ! 1828: if (namelists) { ! 1829: write_namelists(namelists = revchain(namelists), outfile); ! 1830: frchain(&namelists); ! 1831: } ! 1832: ! 1833: /* Finally, ioblocks (which may reference equivs and namelists) */ ! 1834: if (iob_list) ! 1835: write_ioblocks(outfile); ! 1836: if (assigned_fmts) ! 1837: write_assigned_fmts(outfile); ! 1838: ! 1839: if (refdefs) ! 1840: ref_defs(outfile, refdefs); ! 1841: ! 1842: } /* list_decls */ ! 1843: ! 1844: do_uninit_equivs (outfile, did_one) ! 1845: FILE *outfile; ! 1846: int *did_one; ! 1847: { ! 1848: extern int nequiv; ! 1849: struct Equivblock *eqv, *lasteqv = eqvclass + nequiv; ! 1850: int k, last_type = -1, t; ! 1851: ! 1852: for (eqv = eqvclass; eqv < lasteqv; eqv++) ! 1853: if (!eqv -> eqvinit && eqv -> eqvtop != eqv -> eqvbottom) { ! 1854: if (!*did_one) ! 1855: nice_printf (outfile, "/* System generated locals */\n"); ! 1856: t = eqv->eqvtype; ! 1857: if (last_type == t) ! 1858: nice_printf (outfile, ", "); ! 1859: else { ! 1860: if (*did_one) ! 1861: nice_printf (outfile, ";\n"); ! 1862: nice_printf (outfile, "static %s ", c_type_decl(t, 0)); ! 1863: k = typesize[t]; ! 1864: } /* else */ ! 1865: nice_printf(outfile, "%s", equiv_name((int)(eqv - eqvclass), CNULL)); ! 1866: nice_printf(outfile, "[%ld]", ! 1867: (eqv->eqvtop - eqv->eqvbottom + k - 1) / k); ! 1868: last_type = t; ! 1869: *did_one = 1; ! 1870: } /* if !eqv -> eqvinit */ ! 1871: } /* do_uninit_equivs */ ! 1872: ! 1873: ! 1874: /* wr_ardecls -- Writes the brackets and size for an array ! 1875: declaration. Because of the inner workings of the compiler, ! 1876: multi-dimensional arrays get mapped directly into a one-dimensional ! 1877: array, so we have to compute the size of the array here. When the ! 1878: dimension is greater than 1, a string comment about the original size ! 1879: is returned */ ! 1880: ! 1881: char *wr_ardecls(outfile, dimp, size) ! 1882: FILE *outfile; ! 1883: struct Dimblock *dimp; ! 1884: long size; ! 1885: { ! 1886: int i, k; ! 1887: static char buf[1000]; ! 1888: ! 1889: if (dimp == (struct Dimblock *) NULL) ! 1890: return NULL; ! 1891: ! 1892: sprintf(buf, "\t/* was "); /* would like to say k = sprintf(...), but */ ! 1893: k = strlen(buf); /* BSD doesn't return char transmitted count */ ! 1894: ! 1895: for (i = 0; i < dimp -> ndim; i++) { ! 1896: expptr this_size = dimp -> dims[i].dimsize; ! 1897: ! 1898: if (!ISICON (this_size)) ! 1899: err ("wr_ardecls: nonconstant array size"); ! 1900: else { ! 1901: size *= this_size -> constblock.Const.ci; ! 1902: sprintf(buf+k, "[%ld]", this_size -> constblock.Const.ci); ! 1903: k += strlen(buf+k); /* BSD prevents combining this with prev stmt */ ! 1904: } /* else */ ! 1905: } /* for i = 0 */ ! 1906: ! 1907: nice_printf (outfile, "[%ld]", size); ! 1908: strcat(buf+k, " */"); ! 1909: ! 1910: return (i > 1) ? buf : NULL; ! 1911: } /* wr_ardecls */ ! 1912: ! 1913: ! 1914: ! 1915: /* ---------------------------------------------------------------------- ! 1916: ! 1917: The following routines read from the p1 intermediate file. If ! 1918: that format changes, only these routines need be changed ! 1919: ! 1920: ---------------------------------------------------------------------- */ ! 1921: ! 1922: static int get_p1_token (infile) ! 1923: FILE *infile; ! 1924: { ! 1925: int token = P1_UNKNOWN; ! 1926: ! 1927: /* NOT PORTABLE!! */ ! 1928: ! 1929: if (fscanf (infile, "%d", &token) == EOF) ! 1930: return P1_EOF; ! 1931: ! 1932: /* Skip over the ": " */ ! 1933: ! 1934: if (getc (infile) != '\n') ! 1935: getc (infile); ! 1936: ! 1937: return token; ! 1938: } /* get_p1_token */ ! 1939: ! 1940: ! 1941: ! 1942: /* Returns a (null terminated) string from the input file */ ! 1943: ! 1944: static int p1gets (fp, str, size) ! 1945: FILE *fp; ! 1946: char *str; ! 1947: int size; ! 1948: { ! 1949: char *fgets (); ! 1950: char c; ! 1951: ! 1952: if (str == NULL) ! 1953: return 0; ! 1954: ! 1955: if ((c = getc (fp)) != ' ') ! 1956: ungetc (c, fp); ! 1957: ! 1958: if (fgets (str, size, fp)) { ! 1959: int length; ! 1960: ! 1961: str[size - 1] = '\0'; ! 1962: length = strlen (str); ! 1963: ! 1964: /* Get rid of the newline */ ! 1965: ! 1966: if (str[length - 1] == '\n') ! 1967: str[length - 1] = '\0'; ! 1968: return 1; ! 1969: ! 1970: } else if (feof (fp)) ! 1971: return EOF; ! 1972: else ! 1973: return 0; ! 1974: } /* p1gets */ ! 1975: ! 1976: ! 1977: static int p1get_const (infile, type, resultp) ! 1978: FILE *infile; ! 1979: int type; ! 1980: struct Constblock **resultp; ! 1981: { ! 1982: int status; ! 1983: struct Constblock *result; ! 1984: ! 1985: if (type != TYCHAR) { ! 1986: *resultp = result = ALLOC(Constblock); ! 1987: result -> tag = TCONST; ! 1988: result -> vtype = type; ! 1989: } ! 1990: ! 1991: switch (type) { ! 1992: case TYINT1: ! 1993: case TYSHORT: ! 1994: case TYLONG: ! 1995: case TYLOGICAL: ! 1996: #ifdef TYQUAD ! 1997: case TYQUAD: ! 1998: #endif ! 1999: case TYLOGICAL1: ! 2000: case TYLOGICAL2: ! 2001: status = p1getd (infile, &(result -> Const.ci)); ! 2002: break; ! 2003: case TYREAL: ! 2004: case TYDREAL: ! 2005: status = p1getf(infile, &result->Const.cds[0]); ! 2006: result->vstg = 1; ! 2007: break; ! 2008: case TYCOMPLEX: ! 2009: case TYDCOMPLEX: ! 2010: status = p1getf(infile, &result->Const.cds[0]); ! 2011: if (status && status != EOF) ! 2012: status = p1getf(infile, &result->Const.cds[1]); ! 2013: result->vstg = 1; ! 2014: break; ! 2015: case TYCHAR: ! 2016: status = fscanf(infile, "%lx", resultp); ! 2017: break; ! 2018: default: ! 2019: erri ("p1get_const: bad constant type '%d'", type); ! 2020: status = 0; ! 2021: break; ! 2022: } /* switch */ ! 2023: ! 2024: return status; ! 2025: } /* p1get_const */ ! 2026: ! 2027: static int p1getd (infile, result) ! 2028: FILE *infile; ! 2029: long *result; ! 2030: { ! 2031: return fscanf (infile, "%ld", result); ! 2032: } /* p1getd */ ! 2033: ! 2034: static int ! 2035: p1getf(infile, result) ! 2036: FILE *infile; ! 2037: char **result; ! 2038: { ! 2039: ! 2040: char buf[1324]; ! 2041: register int k; ! 2042: ! 2043: k = fscanf (infile, "%s", buf); ! 2044: if (k < 1) ! 2045: k = EOF; ! 2046: else ! 2047: strcpy(*result = mem(strlen(buf)+1,0), buf); ! 2048: return k; ! 2049: } ! 2050: ! 2051: static int p1getn (infile, count, result) ! 2052: FILE *infile; ! 2053: int count; ! 2054: char **result; ! 2055: { ! 2056: ! 2057: char *bufptr; ! 2058: extern ptr ckalloc (); ! 2059: ! 2060: bufptr = (char *) ckalloc (count); ! 2061: ! 2062: if (result) ! 2063: *result = bufptr; ! 2064: ! 2065: for (; !feof (infile) && count > 0; count--) ! 2066: *bufptr++ = getc (infile); ! 2067: ! 2068: return feof (infile) ? EOF : 1; ! 2069: } /* p1getn */ ! 2070: ! 2071: static void ! 2072: proto(outfile, at, fname) ! 2073: FILE *outfile; ! 2074: Argtypes *at; ! 2075: char *fname; ! 2076: { ! 2077: int i, j, k, n; ! 2078: char *comma; ! 2079: Atype *atypes; ! 2080: Namep np; ! 2081: chainp cp; ! 2082: extern void bad_atypes(); ! 2083: ! 2084: if (at) { ! 2085: /* Correct types that we learn on the fly, e.g. ! 2086: subroutine gotcha(foo) ! 2087: external foo ! 2088: call zap(...,foo,...) ! 2089: call foo(...) ! 2090: */ ! 2091: atypes = at->atypes; ! 2092: n = at->defined ? at->dnargs : at->nargs; ! 2093: for(i = 0; i++ < n; atypes++) { ! 2094: if (!(cp = atypes->cp)) ! 2095: continue; ! 2096: j = atypes->type; ! 2097: do { ! 2098: np = (Namep)cp->datap; ! 2099: k = np->vtype; ! 2100: if (np->vclass == CLPROC) { ! 2101: if (!np->vimpltype && k) ! 2102: k += 200; ! 2103: else { ! 2104: if (j >= 300) ! 2105: j = TYUNKNOWN + 200; ! 2106: continue; ! 2107: } ! 2108: } ! 2109: if (j == k) ! 2110: continue; ! 2111: if (j >= 300 ! 2112: || j == 200 && k >= 200) ! 2113: j = k; ! 2114: else { ! 2115: if (at->nargs >= 0) ! 2116: bad_atypes(at,fname,i,j,k,""," and"); ! 2117: goto break2; ! 2118: } ! 2119: } ! 2120: while(cp = cp->nextp); ! 2121: atypes->type = j; ! 2122: frchain(&atypes->cp); ! 2123: } ! 2124: } ! 2125: break2: ! 2126: if (parens) { ! 2127: nice_printf(outfile, parens); ! 2128: return; ! 2129: } ! 2130: ! 2131: if (!at || (n = at-> defined ? at->dnargs : at->nargs) < 0) { ! 2132: nice_printf(outfile, Ansi == 1 ? "()" : "(...)"); ! 2133: return; ! 2134: } ! 2135: ! 2136: if (n == 0) { ! 2137: nice_printf(outfile, Ansi == 1 ? "(void)" : "()"); ! 2138: return; ! 2139: } ! 2140: ! 2141: atypes = at->atypes; ! 2142: nice_printf(outfile, "("); ! 2143: comma = ""; ! 2144: for(; --n >= 0; atypes++) { ! 2145: k = atypes->type; ! 2146: if (k == TYADDR) ! 2147: nice_printf(outfile, "%schar **", comma); ! 2148: else if (k >= 200) { ! 2149: k -= 200; ! 2150: nice_printf(outfile, "%s%s", comma, ! 2151: usedcasts[k] = casttypes[k]); ! 2152: } ! 2153: else if (k >= 100) ! 2154: nice_printf(outfile, ! 2155: k == TYCHAR + 100 ? "%s%s *" : "%s%s", ! 2156: comma, c_type_decl(k-100, 0)); ! 2157: else ! 2158: nice_printf(outfile, "%s%s *", comma, ! 2159: c_type_decl(k, 0)); ! 2160: comma = ", "; ! 2161: } ! 2162: nice_printf(outfile, ")"); ! 2163: } ! 2164: ! 2165: void ! 2166: protowrite(protofile, type, name, e, lengths) ! 2167: FILE *protofile; ! 2168: char *name; ! 2169: struct Entrypoint *e; ! 2170: chainp lengths; ! 2171: { ! 2172: extern char used_rets[]; ! 2173: int asave; ! 2174: ! 2175: if (!(asave = Ansi)) ! 2176: Castargs = Ansi = 1; ! 2177: nice_printf(protofile, "extern %s %s", protorettypes[type], name); ! 2178: list_arg_types(protofile, e, lengths, 0, ";\n"); ! 2179: used_rets[type] = 1; ! 2180: if (!(Ansi = asave)) ! 2181: Castargs = 0; ! 2182: } ! 2183: ! 2184: static void ! 2185: do_p1_1while(outfile) ! 2186: FILE *outfile; ! 2187: { ! 2188: if (*wh_next) { ! 2189: nice_printf(outfile, ! 2190: "for(;;) { /* while(complicated condition) */\n" /*}*/ ); ! 2191: next_tab(outfile); ! 2192: } ! 2193: else ! 2194: nice_printf(outfile, "while(" /*)*/ ); ! 2195: } ! 2196: ! 2197: static void ! 2198: do_p1_2while(infile, outfile) ! 2199: FILE *infile, *outfile; ! 2200: { ! 2201: expptr test; ! 2202: ! 2203: test = do_format(infile, outfile); ! 2204: if (*wh_next) ! 2205: nice_printf(outfile, "if (!("); ! 2206: expr_out(outfile, test); ! 2207: if (*wh_next++) ! 2208: nice_printf(outfile, "))\n\tbreak;\n"); ! 2209: else { ! 2210: nice_printf(outfile, /*(*/ ") {\n"); ! 2211: next_tab(outfile); ! 2212: } ! 2213: } ! 2214: ! 2215: static void ! 2216: do_p1_elseifstart(outfile) ! 2217: FILE *outfile; ! 2218: { ! 2219: if (*ei_next++) { ! 2220: prev_tab(outfile); ! 2221: nice_printf(outfile, /*{*/ ! 2222: "} else /* if(complicated condition) */ {\n" /*}*/ ); ! 2223: next_tab(outfile); ! 2224: } ! 2225: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.