beta-0.89.2
[luatex.git] / source / texk / web2c / web2c / main.c
blob78f7041166915c91df6d9905565f81b242b72800
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.
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
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. */
17 #include "web2c.h"
18 #include "web2c-parser.h"
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
26 #define max_strings 50000
27 #define hash_prime 7883
28 #define sym_table_size 50000
29 #define unused 271828
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;
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;
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;
56 const char *std_header = "null.h"; /* Default include filename */
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;
65 void
66 find_next_temp (void)
68 next_temp[4]++;
69 if (next_temp[4] > 'z')
71 next_temp[4] = 'a';
72 next_temp[3]++;
76 void
77 normal (void)
79 out = stdout;
82 void
83 new_line (void)
85 if (!out)
86 return;
87 if (line_pos > 0)
89 putc ('\n', out);
90 line_pos = 0;
95 /* Output the string S to the file `out'. */
97 void
98 my_output (const_string s)
100 int len = strlen (s);
101 int less_indent = 0;
103 if (!out)
104 return;
106 if (line_pos + len > max_line_length)
107 new_line ();
109 if (indent > 1 && (strcmp (s, "case") == 0 || strcmp (s, "default") == 0))
110 less_indent = 2;
112 while (line_pos < indent * 2 - less_indent) {
113 fputs (" ", out);
114 line_pos += 2;
117 /* Output the token. */
118 fputs (s, out);
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;
126 last_brace = (s[0] == '}');
129 void
130 semicolon (void)
132 if (!last_brace) {
133 my_output (";");
134 new_line ();
135 last_brace = 1;
139 static int
140 hash (const_string id)
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;
149 search_table (const_string id)
151 int ptr;
152 ptr = hash_list[hash (id)];
153 while (ptr != -1)
155 if (strcmp (id, sym_table[ptr].id) == 0)
156 return (ptr);
157 else
158 ptr = sym_table[ptr].next;
160 return -1;
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. */
167 add_to_table (string id)
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;
183 void
184 remove_locals (void)
186 int h, ptr;
187 for (h = 0; h < hash_prime; h++)
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;
196 global = 1;
199 void
200 mark (void)
202 mark_sym_free = next_sym_free;
203 mark_string_free = next_string_free;
204 global = 0;
208 void
209 initialize (void)
211 register int i;
213 for (i = 0; i < hash_prime; hash_list[i++] = -1)
216 normal ();
218 coerce = xfopen (coerce_name, FOPEN_W_MODE);
221 #ifdef WIN32
222 #include <io.h>
223 #include <fcntl.h>
224 #endif
227 main (int argc, string *argv)
229 int i;
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])
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;
261 else
263 fprintf (stderr, "web2c: Unknown argument %s, ignored\n", argv[i]);
266 initialize ();
267 yyparse ();
268 new_line ();
270 xfclose (coerce, coerce_name);
272 if (debug)
274 fprintf (stderr, "%d symbols.\n", next_sym_free);
275 fprintf (stderr, "%d strings.\n", next_string_free);
278 return EXIT_SUCCESS;