home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD2.bin / bbs / gnu / f2c-1993.04.28-src.lha / f2c-1993.04.28 / src / format.c < prev    next >
C/C++ Source or Header  |  1993-04-28  |  53KB  |  2,226 lines

  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 =