#include #include #include #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE (!0) #endif typedef struct scrap_node { struct scrap_node *next; int scrap; } Scrap_Node; typedef struct name { char *spelling; struct name *llink; struct name *rlink; Scrap_Node *defs; Scrap_Node *uses; int mark; char tab_flag; char indent_flag; char debug_flag; } Name; int tex_flag; /* if FALSE, don't emit the .tex file */ int output_flag; /* if FALSE, don't emit the output files */ int compare_flag; /* if FALSE, overwrite without comparison */ char *command_name; char *source_name; /* name of the current file */ int source_line; /* current line in the source file */ Name *file_names; Name *macro_names; Name *user_names; void pass1(); void write_tex(); void write_files(); void source_open(); /* pass in the name of the source file */ int source_get(); /* no args; returns the next char or EOF */ void init_scraps(); int collect_scrap(); int write_scraps(); Name *collect_file_name(); Name *collect_macro_name(); Name *collect_scrap_name(); Name *name_add(); Name *prefix_add(); char *save_string(); void reverse_lists(); void *arena_getmem(); void arena_free(); static FILE *source_file; /* the current input file */ static int source_peek; static int double_at; static int include_depth; struct { FILE *file; char *name; int line; } stack[10]; int source_get() { int c = source_peek; switch (c) { case EOF: { fclose(source_file); if (include_depth) { include_depth--; source_file = stack[include_depth].file; source_line = stack[include_depth].line; source_name = stack[include_depth].name; source_peek = getc(source_file); c = source_get(); } } return c; case '@': { c = getc(source_file); if (double_at) { source_peek = c; double_at = FALSE; c = '@'; } else switch (c) { case 'i': { if (include_depth < 10) { char name[100]; { char *p = name; do c = getc(source_file); while (c == ' ' || c == '\t'); while (isgraph(c)) { *p++ = c; c = getc(source_file); } *p = '\0'; if (c != '\n') { fprintf(stderr, "%s: unexpected characters after file name (%s, %d)\n", command_name, source_name, source_line); exit(-1); } } stack[include_depth].name = source_name; stack[include_depth].file = source_file; stack[include_depth].line = source_line + 1; include_depth++; source_line = 1; source_name = save_string(name); source_file = fopen(source_name, "r"); if (!source_file) { fprintf(stderr, "%s: can't open include file %s\n", command_name, source_name); exit(-1); } source_peek = getc(source_file); c = source_get(); } else { fprintf(stderr, "%s: include nesting too deep (%s, %d)\n", command_name, source_name, source_line); exit(-1); } } break; case 'f': case 'm': case 'u': case 'd': case 'o': case 'D': case 'O': case '{': case '}': case '<': case '>': case '|': source_peek = c; c = '@'; break; case '@': source_peek = c; double_at = TRUE; break; default: fprintf(stderr, "%s: bad @ sequence (%s, line %d)\n", command_name, source_name, source_line); exit(-1); } } return c; case '\n': source_line++; default: source_peek = getc(source_file); return c; } } void source_open(name) char *name; { source_file = fopen(name, "r"); if (!source_file) { fprintf(stderr, "%s: couldn't open %s\n", command_name, name); exit(-1); } source_name = name; source_line = 1; source_peek = getc(source_file); double_at = FALSE; include_depth = 0; }