home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / f2csrc.zip / f2csrc / src / format.c < prev    next >
C/C++ Source or Header  |  1994-02-25  |  60KB  |  2,497 lines

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