home *** CD-ROM | disk | FTP | other *** search
-
- #line 648 "nuweb.w"
- #include "global.h"
-
- #line 2497 "nuweb.w"
- #define SLAB_SIZE 500
-
- typedef struct slab {
- struct slab *next;
- char chars[SLAB_SIZE];
- } Slab;
-
- #line 2508 "nuweb.w"
- typedef struct {
- char *file_name;
- int file_line;
- int page;
- char letter;
- Slab *slab;
- } ScrapEntry;
-
- #line 2519 "nuweb.w"
- static ScrapEntry *SCRAP[256];
-
- #define scrap_array(i) SCRAP[(i) >> 8][(i) & 255]
-
- static int scraps;
-
- #line 2540 "nuweb.w"
- void init_scraps(void)
- {
- scraps = 1;
- SCRAP[0] = (ScrapEntry *) arena_getmem(256 * sizeof(ScrapEntry));
- }
-
- #line 2550 "nuweb.w"
- void write_scrap_ref(FILE *file, int num, int first, int *page)
- {
- if (scrap_array(num).page >= 0) {
- if (first)
- fprintf(file, "%d", scrap_array(num).page);
- else if (scrap_array(num).page != *page)
- fprintf(file, ", %d", scrap_array(num).page);
- if (scrap_array(num).letter > 0)
- putc(scrap_array(num).letter, file);
- }
- else {
- if (first)
- putc('?', file);
- else
- fputs(", ?", file);
-
- #line 2583 "nuweb.w"
- {
- if (!already_warned) {
- fprintf(stderr, "%s: you'll need to rerun nuweb after running LaTeX\n",
- command_name);
- already_warned = TRUE;
- }
- }
-
- #line 2565 "nuweb.w"
-
- }
- *page = scrap_array(num).page;
- }
-
- #line 2573 "nuweb.w"
- void write_single_scrap_ref(FILE *file, int num)
- {
- int page;
- write_scrap_ref(file, num, TRUE, &page);
- }
-
- #line 2602 "nuweb.w"
- typedef struct {
- Slab *scrap;
- Slab *prev;
- int index;
- } Manager;
-
- #line 2613 "nuweb.w"
- static void push(char c, Manager *manager)
- {
- Slab *scrap = manager->scrap;
- int index = manager->index;
- scrap->chars[index++] = c;
- if (index == SLAB_SIZE) {
- Slab *new = (Slab *) arena_getmem(sizeof(Slab));
- scrap->next = new;
- manager->scrap = new;
- index = 0;
- }
- manager->index = index;
- }
-
- #line 2630 "nuweb.w"
- static void pushs(char *s, Manager *manager)
- {
- while (*s)
- push(*s++, manager);
- }
-
- #line 2640 "nuweb.w"
- int collect_scrap(void)
- {
- Manager writer;
-
- #line 2650 "nuweb.w"
- {
- Slab *scrap = (Slab *) arena_getmem(sizeof(Slab));
- if ((scraps & 255) == 0)
- SCRAP[scraps >> 8] = (ScrapEntry *) arena_getmem(256 * sizeof(ScrapEntry));
- scrap_array(scraps).slab = scrap;
- scrap_array(scraps).file_name = save_string(source_name);
- scrap_array(scraps).file_line = source_line;
- scrap_array(scraps).page = -1;
- scrap_array(scraps).letter = 0;
- writer.scrap = scrap;
- writer.index = 0;
- }
-
- #line 2643 "nuweb.w"
-
-
- #line 2667 "nuweb.w"
- {
- int c = source_get();
- while (1) {
- switch (c) {
- case EOF: fprintf(stderr, "%s: unexpect EOF in scrap (%s, %d)\n",
- command_name, scrap_array(scraps).file_name,
- scrap_array(scraps).file_line);
- exit(-1);
- case '@':
- #line 2688 "nuweb.w"
- {
- c = source_get();
- switch (c) {
- case '@': pushs("@@", &writer);
- c = source_get();
- break;
- case '|':
- #line 2709 "nuweb.w"
- {
- do {
- char new_name[256];
- char *p = new_name;
- do
- c = source_get();
- while (isspace(c));
- if (c != '@') {
- Name *name;
- do {
- *p++ = c;
- c = source_get();
- } while (c != '@' && !isspace(c));
- *p = '\0';
- name = name_add(&user_names, new_name);
- if (!name->defs || name->defs->scrap != scraps) {
- Scrap_Node *def = (Scrap_Node *) arena_getmem(sizeof(Scrap_Node));
- def->scrap = scraps;
- def->next = name->defs;
- name->defs = def;
- }
- }
- } while (c != '@');
- c = source_get();
- if (c != '}') {
- fprintf(stderr, "%s: unexpected @%c in scrap (%s, %d)\n",
- command_name, c, source_name, source_line);
- exit(-1);
- }
- }
-
- #line 2694 "nuweb.w"
-
- case '}': push('\0', &writer);
- return scraps++;
- case '<':
- #line 2744 "nuweb.w"
- {
- Name *name = collect_scrap_name();
-
- #line 2755 "nuweb.w"
- {
- char *s = name->spelling;
- int len = strlen(s) - 1;
- pushs("@<", &writer);
- while (len > 0) {
- push(*s++, &writer);
- len--;
- }
- if (*s == ' ')
- pushs("...", &writer);
- else
- push(*s, &writer);
- pushs("@>", &writer);
- }
-
- #line 2746 "nuweb.w"
-
-
- #line 2774 "nuweb.w"
- {
- if (!name->uses || name->uses->scrap != scraps) {
- Scrap_Node *use = (Scrap_Node *) arena_getmem(sizeof(Scrap_Node));
- use->scrap = scraps;
- use->next = name->uses;
- name->uses = use;
- }
- }
-
- #line 2747 "nuweb.w"
-
- c = source_get();
- }
-
- #line 2697 "nuweb.w"
-
- break;
- default : fprintf(stderr, "%s: unexpected @%c in scrap (%s, %d)\n",
- command_name, c, source_name, source_line);
- exit(-1);
- }
- }
-
- #line 2675 "nuweb.w"
-
- break;
- default: push(c, &writer);
- c = source_get();
- break;
- }
- }
- }
-
- #line 2644 "nuweb.w"
-
- }
-
- #line 2787 "nuweb.w"
- static char pop(Manager *manager)
- {
- Slab *scrap = manager->scrap;
- int index = manager->index;
- char c = scrap->chars[index++];
- if (index == SLAB_SIZE) {
- manager->prev = scrap;
- manager->scrap = scrap->next;
- index = 0;
- }
- manager->index = index;
- return c;
- }
-
- #line 2806 "nuweb.w"
- static Name *pop_scrap_name(Manager *manager)
- {
- char name[256];
- char *p = name;
- int c = pop(manager);
- while (TRUE) {
- if (c == '@')
-
- #line 2825 "nuweb.w"
- {
- c = pop(manager);
- if (c == '@') {
- *p++ = c;
- c = pop(manager);
- }
- else if (c == '>') {
- if (p - name > 3 && p[-1] == '.' && p[-2] == '.' && p[-3] == '.') {
- p[-3] = ' ';
- p -= 2;
- }
- *p = '\0';
- return prefix_add(¯o_names, name);
- }
- else {
- fprintf(stderr, "%s: found an internal problem\n", command_name);
- exit(-1);
- }
- }
-
- #line 2813 "nuweb.w"
-
- else {
- *p++ = c;
- c = pop(manager);
- }
- }
- }
-
- #line 2849 "nuweb.w"
- int write_scraps(FILE *file, Scrap_Node *defs, int global_indent,
- char *indent_chars, char debug_flag, char tab_flag, char indent_flag)
- {
- int indent = 0;
- while (defs) {
-
- #line 2864 "nuweb.w"
- {
- char c;
- Manager reader;
- int line_number = scrap_array(defs->scrap).file_line;
-
- #line 2895 "nuweb.w"
- if (debug_flag) {
- fprintf(file, "\n#line %d \"%s\"\n",
- line_number, scrap_array(defs->scrap).file_name);
-
- #line 2905 "nuweb.w"
- {
- if (indent_flag) {
- if (tab_flag)
- for (indent=0; indent<global_indent; indent++)
- putc(' ', file);
- else
- for (indent=0; indent<global_indent; indent++)
- putc(indent_chars[indent], file);
- }
- indent = 0;
- }
-
- #line 2898 "nuweb.w"
-
- }
-
- #line 2868 "nuweb.w"
-
- reader.scrap = scrap_array(defs->scrap).slab;
- reader.index = 0;
- c = pop(&reader);
- while (c) {
- switch (c) {
- case '@':
- #line 2936 "nuweb.w"
- {
- c = pop(&reader);
- switch (c) {
- case '@': putc(c, file);
- indent_chars[global_indent + indent] = ' ';
- indent++;
- break;
- case '<':
- #line 2955 "nuweb.w"
- {
- Name *name = pop_scrap_name(&reader);
- if (name->mark) {
- fprintf(stderr, "%s: recursive macro discovered involving <%s>\n",
- command_name, name->spelling);
- exit(-1);
- }
- if (name->defs) {
- name->mark = TRUE;
- indent = write_scraps(file, name->defs, global_indent + indent,
- indent_chars, debug_flag, tab_flag, indent_flag);
- indent -= global_indent;
- name->mark = FALSE;
- }
- else if (!tex_flag)
- fprintf(stderr, "%s: macro never defined <%s>\n",
- command_name, name->spelling);
- }
-
- #line 2943 "nuweb.w"
-
-
- #line 2895 "nuweb.w"
- if (debug_flag) {
- fprintf(file, "\n#line %d \"%s\"\n",
- line_number, scrap_array(defs->scrap).file_name);
-
- #line 2905 "nuweb.w"
- {
- if (indent_flag) {
- if (tab_flag)
- for (indent=0; indent<global_indent; indent++)
- putc(' ', file);
- else
- for (indent=0; indent<global_indent; indent++)
- putc(indent_chars[indent], file);
- }
- indent = 0;
- }
-
- #line 2898 "nuweb.w"
-
- }
-
- #line 2944 "nuweb.w"
-
- break;
- default: /* ignore, since we should already have a warning */
- break;
- }
- }
-
- #line 2874 "nuweb.w"
-
- break;
- case '\n': putc(c, file);
- line_number++;
-
- #line 2905 "nuweb.w"
- {
- if (indent_flag) {
- if (tab_flag)
- for (indent=0; indent<global_indent; indent++)
- putc(' ', file);
- else
- for (indent=0; indent<global_indent; indent++)
- putc(indent_chars[indent], file);
- }
- indent = 0;
- }
-
- #line 2878 "nuweb.w"
-
- break;
- case '\t':
- #line 2921 "nuweb.w"
- {
- if (tab_flag)
-
- #line 1382 "nuweb.w"
- {
- int delta = 8 - (indent % 8);
- indent += delta;
- while (delta > 0) {
- putc(' ', file);
- delta--;
- }
- }
-
- #line 2923 "nuweb.w"
-
- else {
- putc('\t', file);
- indent_chars[global_indent + indent] = '\t';
- indent++;
- }
- }
-
- #line 2880 "nuweb.w"
-
- break;
- default: putc(c, file);
- indent_chars[global_indent + indent] = ' ';
- indent++;
- break;
- }
- c = pop(&reader);
- }
- }
-
- #line 2854 "nuweb.w"
-
- defs = defs->next;
- }
- return indent + global_indent;
- }
-
- #line 2984 "nuweb.w"
- void collect_numbers(char *aux_name)
- {
- if (number_flag) {
- int i;
- for (i=1; i<scraps; i++)
- scrap_array(i).page = i;
- }
- else {
- FILE *aux_file = fopen(aux_name, "r");
- already_warned = FALSE;
- if (aux_file) {
- char aux_line[500];
- while (fgets(aux_line, 500, aux_file)) {
- int scrap_number;
- int page_number;
- char dummy[50];
- if (3 == sscanf(aux_line, "\\newlabel{scrap%d}{%[^}]}{%d}",
- &scrap_number, dummy, &page_number)) {
- if (scrap_number < scraps)
- scrap_array(scrap_number).page = page_number;
- else
-
- #line 2583 "nuweb.w"
- {
- if (!already_warned) {
- fprintf(stderr, "%s: you'll need to rerun nuweb after running LaTeX\n",
- command_name);
- already_warned = TRUE;
- }
- }
-
- #line 3005 "nuweb.w"
-
- }
- }
- fclose(aux_file);
-
- #line 3017 "nuweb.w"
- {
- int scrap;
- for (scrap=2; scrap<scraps; scrap++) {
- if (scrap_array(scrap-1).page == scrap_array(scrap).page) {
- if (!scrap_array(scrap-1).letter)
- scrap_array(scrap-1).letter = 'a';
- scrap_array(scrap).letter = scrap_array(scrap-1).letter + 1;
- }
- }
- }
-
- #line 3009 "nuweb.w"
-
- }
- }
- }
-
- #line 3523 "nuweb.w"
- typedef struct name_node {
- struct name_node *next;
- Name *name;
- } Name_Node;
-
- #line 3531 "nuweb.w"
- typedef struct goto_node {
- Name_Node *output; /* list of words ending in this state */
- struct move_node *moves; /* list of possible moves */
- struct goto_node *fail; /* and where to go when no move fits */
- struct goto_node *next; /* next goto node with same depth */
- } Goto_Node;
-
- #line 3541 "nuweb.w"
- typedef struct move_node {
- struct move_node *next;
- Goto_Node *state;
- char c;
- } Move_Node;
-
- #line 3550 "nuweb.w"
- static Goto_Node *root[CHAR_MAX];
- static int max_depth;
- static Goto_Node **depths;
-
- #line 3558 "nuweb.w"
- static Goto_Node *goto_lookup(char c, Goto_Node *g)
- {
- Move_Node *m = g->moves;
- while (m && m->c != c)
- m = m->next;
- if (m)
- return m->state;
- else
- return NULL;
- }
-
- #line 3579 "nuweb.w"
- static void build_gotos(Name *tree);
- static int reject_match(Name *name, char post, Manager *reader);
-
- void search(void)
- {
- int i;
- for (i=0; i<CHAR_MAX; i++)
- root[i] = NULL;
- max_depth = 16;
- depths = (Goto_Node **) arena_getmem(max_depth * sizeof(Goto_Node *));
- for (i=0; i<max_depth; i++)
- depths[i] = NULL;
- build_gotos(user_names);
-
- #line 3667 "nuweb.w"
- {
- int depth;
- for (depth=1; depth<max_depth; depth++) {
- Goto_Node *r = depths[depth];
- while (r) {
- Move_Node *m = r->moves;
- while (m) {
- char a = m->c;
- Goto_Node *s = m->state;
- Goto_Node *state = r->fail;
- while (state && !goto_lookup(a, state))
- state = state->fail;
- if (state)
- s->fail = goto_lookup(a, state);
- else
- s->fail = root[a];
- if (s->fail) {
- Name_Node *p = s->fail->output;
- while (p) {
- Name_Node *q = (Name_Node *) arena_getmem(sizeof(Name_Node));
- q->name = p->name;
- q->next = s->output;
- s->output = q;
- p = p->next;
- }
- }
- m = m->next;
- }
- r = r->next;
- }
- }
- }
-
- #line 3592 "nuweb.w"
-
-
- #line 3706 "nuweb.w"
- {
- for (i=1; i<scraps; i++) {
- char c;
- Manager reader;
- Goto_Node *state = NULL;
- reader.prev = NULL;
- reader.scrap = scrap_array(i).slab;
- reader.index = 0;
- c = pop(&reader);
- while (c) {
- while (state && !goto_lookup(c, state))
- state = state->fail;
- if (state)
- state = goto_lookup(c, state);
- else
- state = root[c];
- c = pop(&reader);
- if (state && state->output) {
- Name_Node *p = state->output;
- do {
- Name *name = p->name;
- if (!reject_match(name, c, &reader) &&
- (!name->uses || name->uses->scrap != i)) {
- Scrap_Node *new_use =
- (Scrap_Node *) arena_getmem(sizeof(Scrap_Node));
- new_use->scrap = i;
- new_use->next = name->uses;
- name->uses = new_use;
- }
- p = p->next;
- } while (p);
- }
- }
- }
- }
-
- #line 3593 "nuweb.w"
-
- }
-
- #line 3601 "nuweb.w"
- static void build_gotos(Name *tree)
- {
- while (tree) {
-
- #line 3613 "nuweb.w"
- {
- int depth = 2;
- char *p = tree->spelling;
- char c = *p++;
- Goto_Node *q = root[c];
- if (!q) {
- q = (Goto_Node *) arena_getmem(sizeof(Goto_Node));
- root[c] = q;
- q->moves = NULL;
- q->fail = NULL;
- q->moves = NULL;
- q->output = NULL;
- q->next = depths[1];
- depths[1] = q;
- }
- while (c = *p++) {
- Goto_Node *new = goto_lookup(c, q);
- if (!new) {
- Move_Node *new_move = (Move_Node *) arena_getmem(sizeof(Move_Node));
- new = (Goto_Node *) arena_getmem(sizeof(Goto_Node));
- new->moves = NULL;
- new->fail = NULL;
- new->moves = NULL;
- new->output = NULL;
- new_move->state = new;
- new_move->c = c;
- new_move->next = q->moves;
- q->moves = new_move;
- if (depth == max_depth) {
- int i;
- Goto_Node **new_depths =
- (Goto_Node **) arena_getmem(2*depth*sizeof(Goto_Node *));
- max_depth = 2 * depth;
- for (i=0; i<depth; i++)
- new_depths[i] = depths[i];
- depths = new_depths;
- for (i=depth; i<max_depth; i++)
- depths[i] = NULL;
- }
- new->next = depths[depth];
- depths[depth] = new;
- }
- q = new;
- depth++;
- }
- q->output = (Name_Node *) arena_getmem(sizeof(Name_Node));
- q->output->next = NULL;
- q->output->name = tree;
- }
-
- #line 3604 "nuweb.w"
-
- build_gotos(tree->rlink);
- tree = tree->llink;
- }
- }
-
- #line 3754 "nuweb.w"
- #define sym_char(c) (isalnum(c) || (c) == '_')
-
- static int op_char(char c)
- {
- switch (c) {
- case '!': case '@': case '#': case '%': case '$': case '^':
- case '&': case '*': case '-': case '+': case '=': case '/':
- case '|': case '~': case '<': case '>':
- return TRUE;
- default:
- return FALSE;
- }
- }
-
- #line 3771 "nuweb.w"
- static int reject_match(Name *name, char post, Manager *reader)
- {
- int len = strlen(name->spelling);
- char first = name->spelling[0];
- char last = name->spelling[len - 1];
- char prev = '\0';
- len = reader->index - len - 2;
- if (len >= 0)
- prev = reader->scrap->chars[len];
- else if (reader->prev)
- prev = reader->scrap->chars[SLAB_SIZE - len];
- if (sym_char(last) && sym_char(post)) return TRUE;
- if (sym_char(first) && sym_char(prev)) return TRUE;
- if (op_char(last) && op_char(post)) return TRUE;
- if (op_char(first) && op_char(prev)) return TRUE;
- return FALSE;
- }
-