1 /* web2c -- convert the pseudo-Pascal generated by Tangle to C.
2    The output depends on many C macros and some postprocessing by other
3    programs.
4 
5    Arguments:
6    -f:  force strict interpretation of semantics of for stmt
7    (never used with TeX and friends)
8    -t:  special optimizations for tex.p->tex*.c
9    -m:  special optimizations for mf.p->mf*.c
10    -c:  supply the base part of the name of the coerce.h file
11    -h:  supply the name of the standard header file
12    -d:  generate some additional debugging output
13 
14    The majority of this program (which includes ptoc.yacc and ptoc.lex)
15    was written by Tomas Rokicki, with modifications by Tim Morgan, et al. */
16 
17 #include "web2c.h"
18 #include "web2c-parser.h"
19 
20 
21 /* Changing this value will probably stimulate bugs in some
22    preprocessors -- those which want to put the expansion of a macro
23    entirely on one line.  */
24 #define max_line_length 78
25 
26 #define max_strings 50000
27 #define hash_prime 7883
28 #define sym_table_size 50000
29 #define unused 271828
30 
31 /* Says whether to give voluminous progress reports.  */
32 boolean debug = false;
33 int indent = 0;
34 int line_pos = 0;
35 int last_brace = 0;
36 int block_level = 0;
37 int last_tok;
38 int tex = 0, strict_for = 0, mf = 0;
39 
40 char safe_string[80];
41 char var_list[200];
42 char field_list[200];
43 char last_id[80];
44 char z_id[80];
45 char next_temp[] = "zzzaa";
46 char coerce_name[100] = "coerce.h";
47 string program_name;
48 
49 long last_i_num;
50 int ii, l_s;
51 long lower_bound, upper_bound;
52 FILE *out;
53 FILE *coerce;
54 int pf_count = 1;
55 
56 const char *std_header = "null.h";	/* Default include filename */
57 
58 char strings[max_strings];
59 int hash_list[hash_prime];
60 short global = 1;
61 struct sym_entry sym_table[sym_table_size];
62 int next_sym_free = -1, next_string_free = 0;
63 int mark_sym_free, mark_string_free;
64 
65 void
find_next_temp(void)66 find_next_temp (void)
67 {
68   next_temp[4]++;
69   if (next_temp[4] > 'z')
70     {
71       next_temp[4] = 'a';
72       next_temp[3]++;
73     }
74 }
75 
76 void
normal(void)77 normal (void)
78 {
79   out = stdout;
80 }
81 
82 void
new_line(void)83 new_line (void)
84 {
85   if (!out)
86     return;
87   if (line_pos > 0)
88     {
89       putc ('\n', out);
90       line_pos = 0;
91     }
92 }
93 
94 
95 /* Output the string S to the file `out'.  */
96 
97 void
my_output(const_string s)98 my_output (const_string s)
99 {
100   int len = strlen (s);
101   int less_indent = 0;
102 
103   if (!out)
104     return;
105 
106   if (line_pos + len > max_line_length)
107     new_line ();
108 
109   if (indent > 1 && (strcmp (s, "case") == 0 || strcmp (s, "default") == 0))
110     less_indent = 2;
111 
112   while (line_pos < indent * 2 - less_indent) {
113     fputs ("  ", out);
114     line_pos += 2;
115   }
116 
117   /* Output the token.  */
118   fputs (s, out);
119 
120   /* Omitting the space for parentheses makes fixwrites lose.  Sigh.
121      What a kludge.  */
122   if (!(len == 1 && (*s == ';' || *s == '[' || *s == ']')))
123     putc (' ', out);
124   line_pos += len + 1;
125 
126   last_brace = (s[0] == '}');
127 }
128 
129 void
semicolon(void)130 semicolon (void)
131 {
132   if (!last_brace) {
133     my_output (";");
134     new_line ();
135     last_brace = 1;
136   }
137 }
138 
139 static int
hash(const_string id)140 hash (const_string id)
141 {
142   register int i = 0, j;
143   for (j = 0; id[j] != 0; j++)
144     i = (i + i + id[j]) % hash_prime;
145   return i;
146 }
147 
148 int
search_table(const_string id)149 search_table (const_string id)
150 {
151   int ptr;
152   ptr = hash_list[hash (id)];
153   while (ptr != -1)
154     {
155       if (strcmp (id, sym_table[ptr].id) == 0)
156 	return (ptr);
157       else
158 	ptr = sym_table[ptr].next;
159     }
160   return -1;
161 }
162 
163 
164 /* Add ID to the symbol table.  Leave it up to the caller to assign to
165    the `typ' field.  Return the index into the `sym_table' array.  */
166 int
add_to_table(string id)167 add_to_table (string id)
168 {
169   int h, ptr;
170   h = hash (id);
171   ptr = hash_list[h];
172   hash_list[h] = ++next_sym_free;
173   sym_table[next_sym_free].next = ptr;
174   sym_table[next_sym_free].val = unused;
175   sym_table[next_sym_free].id = strings + next_string_free;
176   sym_table[next_sym_free].var_formal = false;
177   sym_table[next_sym_free].var_not_needed = false;
178   strcpy (strings + next_string_free, id);
179   next_string_free += strlen (id) + 1;
180   return next_sym_free;
181 }
182 
183 void
remove_locals(void)184 remove_locals (void)
185 {
186   int h, ptr;
187   for (h = 0; h < hash_prime; h++)
188     {
189       next_sym_free = mark_sym_free;
190       next_string_free = mark_string_free;
191       ptr = hash_list[h];
192       while (ptr > next_sym_free)
193 	ptr = sym_table[ptr].next;
194       hash_list[h] = ptr;
195     }
196   global = 1;
197 }
198 
199 void
mark(void)200 mark (void)
201 {
202   mark_sym_free = next_sym_free;
203   mark_string_free = next_string_free;
204   global = 0;
205 }
206 
207 
208 void
initialize(void)209 initialize (void)
210 {
211   register int i;
212 
213   for (i = 0; i < hash_prime; hash_list[i++] = -1)
214     ;
215 
216   normal ();
217 
218   coerce = xfopen (coerce_name, FOPEN_W_MODE);
219 }
220 
221 #ifdef WIN32
222 #include <io.h>
223 #include <fcntl.h>
224 #endif
225 
226 int
main(int argc,string * argv)227 main (int argc, string *argv)
228 {
229   int i;
230 
231 #ifdef WIN32
232   setmode(fileno(stdout), _O_BINARY);
233 #endif
234   for (i = 1; i < argc; i++)
235     if (argv[i][0] == '-')
236       switch (argv[i][1])
237 	{
238 	case 't':
239 	  tex = true;
240 	  break;
241 	case 'm':
242 	  mf = true;
243 	  break;
244 	case 'f':
245 	  strict_for = true;
246 	  break;
247 	case 'h':
248 	  std_header = &argv[i][2];
249 	  break;
250 	case 'd':
251 	  debug = true;
252 	  break;
253 	case 'c':
254           program_name = &argv[i][2];
255 	  sprintf (coerce_name, "%s.h", program_name);
256 	  break;
257 	default:
258 	  fprintf (stderr, "web2c: Unknown option %s, ignored\n", argv[i]);
259 	  break;
260 	}
261     else
262       {
263 	fprintf (stderr, "web2c: Unknown argument %s, ignored\n", argv[i]);
264       }
265 
266   initialize ();
267   yyparse ();
268   new_line ();
269 
270   xfclose (coerce, coerce_name);
271 
272   if (debug)
273     {
274       fprintf (stderr, "%d symbols.\n", next_sym_free);
275       fprintf (stderr, "%d strings.\n", next_string_free);
276     }
277 
278   return EXIT_SUCCESS;
279 }
280