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