Back to index

tetex-bin  3.0
main.c
Go to the documentation of this file.
00001 /* web2c -- convert the pseudo-Pascal generated by Tangle to C.
00002    The output depends on many C macros and some postprocessing by other
00003    programs.
00004 
00005    Arguments:
00006    -f:  force strict interpretation of semantics of for stmt
00007    (never used with TeX and friends)
00008    -t:  special optimizations for tex.p->tex*.c
00009    -m:  special optimizations for mf.p->mf*.c
00010    -c:  supply the base part of the name of the coerce.h file
00011    -h:  supply the name of the standard header file
00012    -d:  generate some additional debugging output
00013 
00014    The majority of this program (which includes ptoc.yacc and ptoc.lex)
00015    was written by Tomas Rokicki, with modifications by Tim Morgan, et al. */
00016 
00017 #include "web2c.h"
00018 #include "y_tab.h"
00019 
00020 
00021 /* Changing this value will probably stimulate bugs in some
00022    preprocessors -- those which want to put the expansion of a macro
00023    entirely on one line.  */
00024 #define max_line_length 78
00025 
00026 #define max_strings 20000
00027 #define hash_prime 101
00028 #define sym_table_size 3000
00029 #define unused 271828
00030 
00031 /* Says whether to give voluminous progress reports.  */
00032 boolean debug = false;
00033 int indent = 0;
00034 int line_pos = 0;
00035 int last_brace = 0;
00036 int block_level = 0;
00037 int last_tok;
00038 int tex = 0, strict_for = 0, mf = 0;
00039 
00040 char safe_string[80];
00041 char var_list[200];
00042 char field_list[200];
00043 char last_id[80];
00044 char z_id[80];
00045 char next_temp[] = "zzzaa";
00046 char coerce_name[100] = "coerce.h";
00047 string program_name;
00048 
00049 long last_i_num;
00050 int ii, l_s;
00051 long lower_bound, upper_bound;
00052 FILE *out;
00053 FILE *coerce;
00054 int pf_count = 1;
00055 
00056 char *std_header = "null.h";       /* Default include filename */
00057 
00058 char strings[max_strings];
00059 int hash_list[hash_prime];
00060 short global = 1;
00061 struct sym_entry sym_table[sym_table_size];
00062 int next_sym_free = -1, next_string_free = 0;
00063 int mark_sym_free, mark_string_free;
00064 
00065 int argc;
00066 char **gargv;
00067 
00068 extern int yyleng;
00069 
00070 void
00071 find_next_temp P1H(void)
00072 {
00073   next_temp[4]++;
00074   if (next_temp[4] > 'z')
00075     {
00076       next_temp[4] = 'a';
00077       next_temp[3]++;
00078     }
00079 }
00080 
00081 void
00082 normal P1H(void)
00083 {
00084   out = stdout;
00085 }
00086 
00087 void
00088 new_line P1H(void)
00089 {
00090   if (!out)
00091     return;
00092   if (line_pos > 0)
00093     {
00094       putc ('\n', out);
00095       line_pos = 0;
00096     }
00097 }
00098 
00099 
00100 /* Output the string S to the file `out'.  */
00101 
00102 void
00103 my_output P1C(string, s)
00104 {
00105   int len = strlen (s);
00106   int less_indent = 0;
00107 
00108   if (!out)
00109     return;
00110 
00111   if (line_pos + len > max_line_length)
00112     new_line ();
00113 
00114   if (indent > 1 && (strcmp (s, "case") == 0 || strcmp (s, "default") == 0))
00115     less_indent = 2;
00116 
00117   while (line_pos < indent * 2 - less_indent) {
00118     fputs ("  ", out);
00119     line_pos += 2;
00120   }
00121 
00122   /* Output the token.  */
00123   fputs (s, out);
00124 
00125   /* Omitting the space for parentheses makes fixwrites lose.  Sigh.
00126      What a kludge.  */
00127   if (!(len == 1 && (*s == ';' || *s == '[' || *s == ']')))
00128     putc (' ', out);
00129   line_pos += len + 1;
00130 
00131   last_brace = (s[0] == '}');
00132 }
00133 
00134 void
00135 semicolon P1H(void)
00136 {
00137   if (!last_brace) {
00138     my_output (";");
00139     new_line ();
00140     last_brace = 1;
00141   }
00142 }
00143 
00144 int
00145 hash P1C(const_string, id)
00146 {
00147   register int i = 0, j;
00148   for (j = 0; id[j] != 0; j++)
00149     i = (i + i + id[j]) % hash_prime;
00150   return i;
00151 }
00152 
00153 int
00154 search_table P1C(const_string, id)
00155 {
00156   int ptr;
00157   ptr = hash_list[hash (id)];
00158   while (ptr != -1)
00159     {
00160       if (strcmp (id, sym_table[ptr].id) == 0)
00161        return (ptr);
00162       else
00163        ptr = sym_table[ptr].next;
00164     }
00165   return -1;
00166 }
00167 
00168 
00169 /* Add ID to the symbol table.  Leave it up to the caller to assign to
00170    the `typ' field.  Return the index into the `sym_table' array.  */
00171 int
00172 add_to_table P1C(string, id)
00173 {
00174   int h, ptr;
00175   h = hash (id);
00176   ptr = hash_list[h];
00177   hash_list[h] = ++next_sym_free;
00178   sym_table[next_sym_free].next = ptr;
00179   sym_table[next_sym_free].val = unused;
00180   sym_table[next_sym_free].id = strings + next_string_free;
00181   sym_table[next_sym_free].var_formal = false;
00182   sym_table[next_sym_free].var_not_needed = false;
00183   strcpy (strings + next_string_free, id);
00184   next_string_free += strlen (id) + 1;
00185   return next_sym_free;
00186 }
00187 
00188 void
00189 remove_locals P1H(void)
00190 {
00191   int h, ptr;
00192   for (h = 0; h < hash_prime; h++)
00193     {
00194       next_sym_free = mark_sym_free;
00195       next_string_free = mark_string_free;
00196       ptr = hash_list[h];
00197       while (ptr > next_sym_free)
00198        ptr = sym_table[ptr].next;
00199       hash_list[h] = ptr;
00200     }
00201   global = 1;
00202 }
00203 
00204 void
00205 mark P1H(void)
00206 {
00207   mark_sym_free = next_sym_free;
00208   mark_string_free = next_string_free;
00209   global = 0;
00210 }
00211 
00212 
00213 void
00214 initialize P1H(void)
00215 {
00216   register int i;
00217 
00218   for (i = 0; i < hash_prime; hash_list[i++] = -1)
00219     ;
00220 
00221   normal ();
00222 
00223   coerce = xfopen (coerce_name, FOPEN_W_MODE);
00224 }
00225 
00226 int
00227 main P2C(int, argc, string *, argv)
00228 {
00229   int error, i;
00230 
00231   for (i = 1; i < argc; i++)
00232     if (argv[i][0] == '-')
00233       switch (argv[i][1])
00234        {
00235        case 't':
00236          tex = true;
00237          break;
00238        case 'm':
00239          mf = true;
00240          break;
00241        case 'f':
00242          strict_for = true;
00243          break;
00244        case 'h':
00245          std_header = &argv[i][2];
00246          break;
00247        case 'd':
00248          debug = true;
00249          break;
00250        case 'c':
00251           program_name = &argv[i][2];
00252          sprintf (coerce_name, "%s.h", program_name);
00253          break;
00254        default:
00255          fprintf (stderr, "web2c: Unknown option %s, ignored\n", argv[i]);
00256          break;
00257        }
00258     else
00259       {
00260        fprintf (stderr, "web2c: Unknown argument %s, ignored\n", argv[i]);
00261       }
00262 
00263   initialize ();
00264   error = yyparse ();
00265   new_line ();
00266 
00267   xfclose (coerce, coerce_name);
00268 
00269   if (debug)
00270     fprintf (stderr, "%d symbols.\n", next_sym_free);
00271 
00272   return EXIT_SUCCESS;
00273 }