diff options
Diffstat (limited to 'Build/source/texk/web2c/web2c/main.c')
-rw-r--r-- | Build/source/texk/web2c/web2c/main.c | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/web2c/main.c b/Build/source/texk/web2c/web2c/main.c new file mode 100644 index 00000000000..b57a36277a9 --- /dev/null +++ b/Build/source/texk/web2c/web2c/main.c @@ -0,0 +1,273 @@ +/* web2c -- convert the pseudo-Pascal generated by Tangle to C. + The output depends on many C macros and some postprocessing by other + programs. + + Arguments: + -f: force strict interpretation of semantics of for stmt + (never used with TeX and friends) + -t: special optimizations for tex.p->tex*.c + -m: special optimizations for mf.p->mf*.c + -c: supply the base part of the name of the coerce.h file + -h: supply the name of the standard header file + -d: generate some additional debugging output + + The majority of this program (which includes ptoc.yacc and ptoc.lex) + was written by Tomas Rokicki, with modifications by Tim Morgan, et al. */ + +#include "web2c.h" +#include "y_tab.h" + + +/* Changing this value will probably stimulate bugs in some + preprocessors -- those which want to put the expansion of a macro + entirely on one line. */ +#define max_line_length 78 + +#define max_strings 20000 +#define hash_prime 101 +#define sym_table_size 3000 +#define unused 271828 + +/* Says whether to give voluminous progress reports. */ +boolean debug = false; +int indent = 0; +int line_pos = 0; +int last_brace = 0; +int block_level = 0; +int last_tok; +int tex = 0, strict_for = 0, mf = 0; + +char safe_string[80]; +char var_list[200]; +char field_list[200]; +char last_id[80]; +char z_id[80]; +char next_temp[] = "zzzaa"; +char coerce_name[100] = "coerce.h"; +string program_name; + +long last_i_num; +int ii, l_s; +long lower_bound, upper_bound; +FILE *out; +FILE *coerce; +int pf_count = 1; + +char *std_header = "null.h"; /* Default include filename */ + +char strings[max_strings]; +int hash_list[hash_prime]; +short global = 1; +struct sym_entry sym_table[sym_table_size]; +int next_sym_free = -1, next_string_free = 0; +int mark_sym_free, mark_string_free; + +int argc; +char **gargv; + +extern int yyleng; + +void +find_next_temp P1H(void) +{ + next_temp[4]++; + if (next_temp[4] > 'z') + { + next_temp[4] = 'a'; + next_temp[3]++; + } +} + +void +normal P1H(void) +{ + out = stdout; +} + +void +new_line P1H(void) +{ + if (!out) + return; + if (line_pos > 0) + { + putc ('\n', out); + line_pos = 0; + } +} + + +/* Output the string S to the file `out'. */ + +void +my_output P1C(string, s) +{ + int len = strlen (s); + int less_indent = 0; + + if (!out) + return; + + if (line_pos + len > max_line_length) + new_line (); + + if (indent > 1 && (strcmp (s, "case") == 0 || strcmp (s, "default") == 0)) + less_indent = 2; + + while (line_pos < indent * 2 - less_indent) { + fputs (" ", out); + line_pos += 2; + } + + /* Output the token. */ + fputs (s, out); + + /* Omitting the space for parentheses makes fixwrites lose. Sigh. + What a kludge. */ + if (!(len == 1 && (*s == ';' || *s == '[' || *s == ']'))) + putc (' ', out); + line_pos += len + 1; + + last_brace = (s[0] == '}'); +} + +void +semicolon P1H(void) +{ + if (!last_brace) { + my_output (";"); + new_line (); + last_brace = 1; + } +} + +int +hash P1C(const_string, id) +{ + register int i = 0, j; + for (j = 0; id[j] != 0; j++) + i = (i + i + id[j]) % hash_prime; + return i; +} + +int +search_table P1C(const_string, id) +{ + int ptr; + ptr = hash_list[hash (id)]; + while (ptr != -1) + { + if (strcmp (id, sym_table[ptr].id) == 0) + return (ptr); + else + ptr = sym_table[ptr].next; + } + return -1; +} + + +/* Add ID to the symbol table. Leave it up to the caller to assign to + the `typ' field. Return the index into the `sym_table' array. */ +int +add_to_table P1C(string, id) +{ + int h, ptr; + h = hash (id); + ptr = hash_list[h]; + hash_list[h] = ++next_sym_free; + sym_table[next_sym_free].next = ptr; + sym_table[next_sym_free].val = unused; + sym_table[next_sym_free].id = strings + next_string_free; + sym_table[next_sym_free].var_formal = false; + sym_table[next_sym_free].var_not_needed = false; + strcpy (strings + next_string_free, id); + next_string_free += strlen (id) + 1; + return next_sym_free; +} + +void +remove_locals P1H(void) +{ + int h, ptr; + for (h = 0; h < hash_prime; h++) + { + next_sym_free = mark_sym_free; + next_string_free = mark_string_free; + ptr = hash_list[h]; + while (ptr > next_sym_free) + ptr = sym_table[ptr].next; + hash_list[h] = ptr; + } + global = 1; +} + +void +mark P1H(void) +{ + mark_sym_free = next_sym_free; + mark_string_free = next_string_free; + global = 0; +} + + +void +initialize P1H(void) +{ + register int i; + + for (i = 0; i < hash_prime; hash_list[i++] = -1) + ; + + normal (); + + coerce = xfopen (coerce_name, FOPEN_W_MODE); +} + +int +main P2C(int, argc, string *, argv) +{ + int error, i; + + for (i = 1; i < argc; i++) + if (argv[i][0] == '-') + switch (argv[i][1]) + { + case 't': + tex = true; + break; + case 'm': + mf = true; + break; + case 'f': + strict_for = true; + break; + case 'h': + std_header = &argv[i][2]; + break; + case 'd': + debug = true; + break; + case 'c': + program_name = &argv[i][2]; + sprintf (coerce_name, "%s.h", program_name); + break; + default: + fprintf (stderr, "web2c: Unknown option %s, ignored\n", argv[i]); + break; + } + else + { + fprintf (stderr, "web2c: Unknown argument %s, ignored\n", argv[i]); + } + + initialize (); + error = yyparse (); + new_line (); + + xfclose (coerce, coerce_name); + + if (debug) + fprintf (stderr, "%d symbols.\n", next_sym_free); + + return EXIT_SUCCESS; +} |