-/* Copyright 2014 Clerk Ma
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 USA. */
-
-#define EXTERN extern
-
-#include "texd.h"
-
-/* following bit used to be end of tex1.c */
-#ifdef STAT
-/* sec 0284 */
-void restore_trace_(halfword p, char * s)
-{
- begin_diagnostic();
- print_char('{');
- print_string(s);
- print_char(' ');
- show_eqtb(p);
- print_char('}');
- end_diagnostic(false);
-}
-#endif
-/* sec 0281 */
-void unsave (void)
-{
- halfword p;
- quarterword l;
- halfword t;
-
- if (cur_level > level_one)
- {
- decr(cur_level);
-
- while (true)
- {
- decr(save_ptr);
-
- if (save_type(save_ptr) == level_boundary)
- goto done;
-
- p = save_index(save_ptr);
-
- if (save_type(save_ptr) == insert_token)
- {
- t = cur_tok;
- cur_tok = p;
- back_input();
- cur_tok = t;
- }
- else
- {
- if (save_type(save_ptr) == restore_old_value)
- {
- l = save_level(save_ptr);
- decr(save_ptr);
- }
- else
- save_stack[save_ptr] = eqtb[undefined_control_sequence];
-
- if (p < int_base)
- if (eq_level(p) == level_one)
- {
- eq_destroy(save_stack[save_ptr]);
-#ifdef STAT
- if (tracing_restores > 0)
- restore_trace(p, "retaining");
-#endif
- }
- else
- {
- eq_destroy(eqtb[p]);
- eqtb[p] = save_stack[save_ptr];
-#ifdef STAT
- if (tracing_restores > 0)
- restore_trace(p, "restoring");
-#endif
- }
- else if (xeq_level[p] != level_one)
- {
- eqtb[p] = save_stack[save_ptr];
- xeq_level[p] = l;
-#ifdef STAT
- if (tracing_restores > 0)
- restore_trace(p, "restoring");
-#endif
- }
- else
- {
-#ifdef STAT
- if (tracing_restores > 0)
- restore_trace(p, "retaining");
-#endif
- }
- }
- }
-done:
- cur_group = save_level(save_ptr);
- cur_boundary = save_index(save_ptr);
- }
- else
- {
- confusion("curlevel");
- return;
- }
-}
-/* This is where the old tex2.c used to start */
-/* sec 0288 */
-void prepare_mag (void)
-{
- if ((mag_set > 0) && (mag != mag_set))
- {
- print_err("Incompatible magnification (");
- print_int(mag);
- print_string(");");
- print_nl(" the previous value will be retained");
- help2("I can handle only one magnification ratio per job. So I've",
- "reverted to the magnification you used earlier on this run.");
- int_error(mag_set);
- geq_word_define(int_base + mag_code, mag_set);
- }
-
- if ((mag <= 0) || (mag > 32768L))
- {
- print_err("Illegal magnification has been changed to 1000");
- help1("The magnification ratio must be between 1 and 32768.");
- int_error(mag);
- geq_word_define(int_base + mag_code, 1000);
- }
-
- mag_set = mag;
-}
-/* sec 0295 */
-void token_show_ (halfword p)
-{
- if (p != 0)
- show_token_list(link(p), 0, 10000000L);
-}
-/* sec 0296 */
-void print_meaning (void)
-{
- print_cmd_chr(cur_cmd, cur_chr);
-
- if (cur_cmd >= call)
- {
- print_char(':');
- print_ln();
- token_show(cur_chr);
- }
- else if (cur_cmd == top_bot_mark)
- {
- print_char(':');
- print_ln();
- token_show(cur_mark[cur_chr]);
- }
-}
-/* sec 0299 */
-void show_cur_cmd_chr (void)
-{
- begin_diagnostic();
- print_nl("{");
-
- if (mode != shown_mode)
- {
- print_mode(mode);
- print_string(": ");
- shown_mode = mode;
- }
-
- print_cmd_chr(cur_cmd, cur_chr);
- print_char('}');
- end_diagnostic(false);
-}
-/* sec 0311 */
-void show_context (void)
-{
- char old_setting;
- integer nn;
- boolean bottom_line;
- integer i;
- integer j;
- integer l;
- integer m;
- integer n;
- integer p;
- integer q;
-
- base_ptr = input_ptr;
- input_stack[base_ptr] = cur_input;
- nn = -1;
- bottom_line = false;
-
- while (true)
- {
- cur_input = input_stack[base_ptr];
-
- if ((state != token_list))
- if ((cur_input.name_field > 17) || (base_ptr == 0))
- bottom_line = true;
-
- if ((base_ptr == input_ptr) || bottom_line || (nn < error_context_lines))
- {
- if ((base_ptr == input_ptr) || (state != token_list) ||
- (index != backed_up) || (loc != 0))
- {
- tally = 0;
- old_setting = selector;
-
- if (state != token_list)
- {
- if (cur_input.name_field <= 17)
- if ((cur_input.name_field == 0))
- if (base_ptr == 0)
- print_nl("<*>");
- else
- print_nl("<insert> ");
- else
- {
- print_nl("<read ");
-
- if (cur_input.name_field == 17)
- print_char('*');
- else
- print_int(cur_input.name_field - 1);
-
- print_char('>');
- }
- else
- {
- if (c_style_flag)
- {
- print_ln();
-
- if (cur_input.name_field > 17)
- print(cur_input.name_field);
-
- print_char('(');
- print_int(line);
- print_string(") :");
- }
- else
- {
- print_nl("l.");
- print_int(line);
- }
- }
-
- print_char(' ');
- begin_pseudoprint();
-
- if (buffer[limit] == end_line_char)
- j = limit;
- else
- j = limit + 1;
-
- if (j > 0)
- for (i = start; i <= j - 1; i++)
- {
- if (i == loc)
- set_trick_count();
-
- print(buffer[i]);
- }
- }
- else
- {
- switch (index)
- {
- case parameter:
- print_nl("<argument> ");
- break;
-
- case u_template:
- case v_template:
- print_nl("<template> ");
- break;
-
- case backed_up:
- if (loc == 0)
- print_nl("<recently read> ");
- else
- print_nl("<to be read again> ");
- break;
-
- case inserted:
- print_nl("<inserted text> ");
- break;
-
- case macro:
- print_ln();
- print_cs(cur_input.name_field);
- break;
-
- case output_text:
- print_nl("<output> ");
- break;
-
- case every_par_text:
- print_nl("<everypar> ");
- break;
-
- case every_math_text:
- print_nl("<everymath> ");
- break;
-
- case every_display_text:
- print_nl("<everydisplay> ");
- break;
-
- case every_hbox_text:
- print_nl("<everyhbox> ");
- break;
-
- case every_vbox_text:
- print_nl("<everyvbox> ");
- break;
-
- case every_job_text:
- print_nl("<everyjob> ");
- break;
-
- case every_cr_text:
- print_nl("<everycr> ");
- break;
-
- case mark_text:
- print_nl("<mark> ");
- break;
-
- case write_text:
- print_nl("<write> ");
- break;
-
- default:
- print_nl("?");
- break;
- }
-
- begin_pseudoprint();
-
- if (index < macro)
- show_token_list(start, loc, 100000L);
- else
- show_token_list(link(start), loc, 100000L);
- }
-
- selector = old_setting;
-
- if (trick_count == 1000000L)
- set_trick_count();
-
- if (tally < trick_count)
- m = tally - first_count;
- else
- m = trick_count - first_count;
-
- if (l + first_count <= half_error_line)
- {
- p = 0;
- n = l + first_count;
- }
- else
- {
- print_string("...");
- p = l + first_count - half_error_line + 3;
- n = half_error_line;
- }
-
- for (q = p; q <= first_count - 1; q++)
- print_char(trick_buf[q % error_line]);
-
- print_ln();
-
- for (q = 1; q <= n; q++)
- print_char(' ');
-
- if (m + n <= error_line)
- p = first_count + m;
- else
- p = first_count +(error_line - n - 3);
-
- for (q = first_count; q <= p - 1; q++)
- print_char(trick_buf[q % error_line]);
-
- if (m + n > error_line)
- print_string("...");
-
- incr(nn);
- }
- }
- else if (nn == error_context_lines)
- {
- print_nl("...");
- incr(nn);
- }
-
- if (bottom_line)
- goto done;
-
- decr(base_ptr);
- }
-
-done:
- cur_input = input_stack[input_ptr];
-}
-/* sec 0323 */
-void begin_token_list_ (halfword p, quarterword t)
-{
- push_input();
- state = token_list;
- start = p;
- index = t;
-
- if (t >= macro)
- {
- add_token_ref(p);
-
- if (t == macro)
- limit = param_ptr;
- else
- {
- loc = link(p);
-
- if (tracing_macros > 1)
- {
- begin_diagnostic();
- print_nl("");
-
- switch (t)
- {
- case mark_text:
- print_esc("mark");
- break;
-
- case write_text:
- print_esc("write");
- break;
-
- default:
- print_cmd_chr(assign_toks, t - output_text + output_routine_loc);
- break;
- }
-
- print_string("->");
- token_show(p);
- end_diagnostic(false);
- }
- }
- }
- else
- loc = p;
-}
-/* sec 0324 */
-void end_token_list (void)
-{
- if (index >= backed_up)
- {
- if (index <= inserted)
- flush_list(start);
- else
- {
- delete_token_ref(start);
-
- if (index == macro)
- while (param_ptr > limit)
- {
- decr(param_ptr);
- flush_list(param_stack[param_ptr]);
- }
- }
- }
- else if (index == u_template)
- if (align_state > 500000L)
- align_state = 0;
- else
- {
- fatal_error("(interwoven alignment preambles are not allowed)");
- return;
- }
-
- pop_input();
- check_interrupt();
-}
-/* sec 0325 */
-void back_input (void)
-{
- halfword p;
-
- while ((state == 0) && (loc == 0) &&
- (index != v_template))
- {
- end_token_list();
- }
-
- p = get_avail();
- info(p) = cur_tok;
-
- if (cur_tok < right_brace_limit)
- if (cur_tok < left_brace_limit)
- decr(align_state);
- else
- incr(align_state);
-
- push_input();
- state = token_list;
- start = p;
- index = backed_up;
- loc = p;
-}
-/* sec 0327 */
-void back_error (void)
-{
- OK_to_interrupt = false;
- back_input();
- OK_to_interrupt = true;
- error();
-}
-/* sec 0327 */
-void ins_error (void)
-{
- OK_to_interrupt = false;
- back_input();
- index = inserted;
- OK_to_interrupt = true;
- error();
-}
-/* sec 0328 */
-void begin_file_reading (void)
-{
- if (in_open == max_in_open)
- {
- overflow("text input levels", max_in_open);
- return;
- }
-#ifdef ALLOCATEBUFFER
- if (first == current_buf_size)
- buffer = realloc_buffer(increment_buf_size);
-
- if (first == current_buf_size) /* check again after allocation */
- {
- overflow("buffer size", current_buf_size);
- return;
- }
-#else
- if (first == buf_size)
- {
- overflow("buffer size", buf_size);
- return;
- }
-#endif
-
- incr(in_open);
-
- if (in_open > high_in_open) /* 1999 Jan 17 */
- high_in_open = in_open;
-
- push_input();
- index = in_open;
- line_stack[index] = line;
- start = first;
- state = 1;
- cur_input.name_field = 0;
-}
-/* sec 0329 */
-void end_file_reading (void)
-{
- first = start;
- line = line_stack[index];
-
- if (cur_input.name_field > 17)
- a_close(cur_file);
-
- pop_input();
- decr(in_open);
-}
-/* called only form tex0.c */
-/* sec 0330 */
-void clear_for_error_prompt (void)
-{
- while ((state != 0) && (cur_input.name_field == 0) &&
- (input_ptr > 0) && (loc > limit))
- end_file_reading();
-
- print_ln();
-}
-/* sec 0336 */
-void check_outer_validity (void)
-{
- halfword p;
- halfword q;
-
- if (scanner_status != 0)
- {
- deletions_allowed = false;
-
- if (cur_cs != 0)
- {
- if ((state == 0) || (cur_input.name_field < 1) || (cur_input.name_field > 17))
- {
- p = get_avail();
- info(p) = cs_token_flag + cur_cs;
- back_list(p);
- }
-
- cur_cmd = spacer;
- cur_chr = ' ';
- }
-
- if (scanner_status > skipping)
- {
- runaway();
-
- if (cur_cs == 0)
- print_err("File ended");
- else
- {
- cur_cs = 0;
- print_err("Forbidden control sequence found");
- }
-
- print_string(" while scanning ");
- p = get_avail();
-
- switch (scanner_status)
- {
- case defining:
- print_string("definition");
- info(p) = right_brace_token + '}';
- break;
-
- case matching:
- print_string("use");
- info(p) = par_token;
- long_state = outer_call;
- break;
-
- case aligning:
- print_string("preamble");
- info(p) = right_brace_token + '}';
- q = p;
- p = get_avail();
- link(p) = q;
- info(p) = cs_token_flag + frozen_cr;
- align_state = -1000000L;
- break;
-
- case absorbing:
- print_string("text");
- info(p) = right_brace_token + '}';
- break;
- }
-
- ins_list(p);
- print_string(" of ");
- sprint_cs(warning_index);
- help4("I suspect you have forgotten a `}', causing me",
- "to read past where you wanted me to stop.",
- "I'll try to recover; but if the error is serious,",
- "you'd better type `E' or `X' now and fix your file.");
- error();
- }
- else
- {
- print_err("Incomplete ");
- print_cmd_chr(if_test, cur_if);
- print_string("; all text was ignored after line ");
- print_int(skip_line);
- help3("A forbidden control sequence occurred in skipped text.",
- "This kind of error happens when you say `\\if...' and forget",
- "the matching `\\fi'. I've inserted a `\\fi'; this might work.");
-
- if (cur_cs != 0)
- cur_cs = 0;
- else
- help_line[2] = "The file ended while I was skipping conditional text.";
-
- cur_tok = cs_token_flag + frozen_fi;
- ins_error();
- }
-
- deletions_allowed = true;
- }
-}
-/* sec 0363 */
-void firm_up_the_line (void)
-{
- integer k;
-
- limit = last;
-
- if (pausing > 0)
- if (interaction > nonstop_mode)
- {
- ;
- print_ln();
-
- if (start < limit)
- for (k = start; k <= limit - 1; k++)
- print(buffer[k]);
-
- first = limit;
- prompt_input("=>");
-
- if (last > first)
- {
- for (k = first; k <= last - 1; k++)
- buffer[k + start - first] = buffer[k];
-
- limit = start + last - first;
- }
- }
-}
-/* sec 0365 */
-void get_token (void)
-{
- no_new_control_sequence = false;
- get_next();
- no_new_control_sequence = true;
-
- if (cur_cs == 0)
- cur_tok = (cur_cmd * 256) + cur_chr;
- else
- cur_tok = cs_token_flag + cur_cs;
-}
-/* sec 0389 */
-void macro_call (void)
-{
- halfword r;
- halfword p;
- halfword q;
- halfword s;
- halfword t;
- halfword u, v;
- halfword rbrace_ptr;
- small_number n;
- halfword unbalance;
- halfword m;
- halfword ref_count;
- small_number save_scanner_status;
- halfword save_warning_index;
- ASCII_code match_chr;
-
- save_scanner_status = scanner_status;
- save_warning_index = warning_index;
- warning_index = cur_cs;
- ref_count = cur_chr;
- r = link(ref_count);
- n = 0;
-
- if (tracing_macros > 0)
- {
- begin_diagnostic();
- print_ln();
- print_cs(warning_index);
- token_show(ref_count);
- end_diagnostic(false);
- }
-
- if (info(r) != end_match_token)
- {
- scanner_status = matching;
- unbalance = 0;
- long_state = eq_type(cur_cs);
-
- if (long_state >= outer_call)
- long_state = long_state - 2;
-
- do
- {
- link(temp_head) = 0;
-
- if ((info(r) > match_token + 255) || (info(r) < match_token))
- s = 0;
- else
- {
- match_chr = info(r) - match_token;
- s = link(r);
- r = s;
- p = temp_head;
- m = 0;
- }
-continu:
- get_token();
-
- if (cur_tok == info(r))
- {
- r = link(r);
-
- if ((info(r) >= match_token) && (info(r) <= end_match_token))
- {
- if (cur_tok < left_brace_limit)
- decr(align_state);
-
- goto found;
- }
- else
- goto continu;
- }
-
- if (s != r)
- if (s == 0)
- {
- print_err("Use of ");
- sprint_cs(warning_index);
- print_string(" doesn't match its definition");
- help4("If you say, e.g., `\\def\\a1{...}', then you must always",
- "put `1' after `\\a', since control sequence names are",
- "made up of letters only. The macro here has not been",
- "followed by the required stuff, so I'm ignoring it.");
- error();
- goto exit;
- }
- else
- {
- t = s;
- do
- {
- store_new_token(info(t));
- incr(m);
- u = link(t);
- v = s;
-
- while (true)
- {
- if (u == r)
- if (cur_tok != info(v))
- goto done;
- else
- {
- r = link(v);
- goto continu;
- }
-
- if (info(u) != info(v))
- goto done;
-
- u = link(u);
- v = link(v);
- }
-done:
- t = link(t);
- }
- while (!(t == r));
-
- r = s;
- }
-
- if (cur_tok == par_token)
- if (long_state != long_call)
- {
- if (long_state == call)
- {
- runaway();
- print_err("Paragraph ended before ");
- sprint_cs(warning_index);
- print_string("was complete");
- help3("I suspect you've forgotten a `}', causing me to apply this",
- "control sequence to too much text. How can we recover?",
- "My plan is to forget the whole thing and hope for the best.");
- back_error();
- }
-
- pstack[n] = link(temp_head);
- align_state = align_state - unbalance;
-
- for (m = 0; m <= n; m++)
- flush_list(pstack[m]);
-
- goto exit;
- }
-
- if (cur_tok < right_brace_limit)
- if (cur_tok < left_brace_limit)
- {
- unbalance = 1;
-
- while (true)
- {
- fast_store_new_token(cur_tok);
- get_token();
-
- if (cur_tok == par_token)
- if (long_state != long_call)
- {
- if (long_state == call)
- {
- runaway();
- print_err("Paragraph ended before ");
- sprint_cs(warning_index);
- print_string(" was complete");
- help3("I suspect you've forgotten a `}', causing me to apply this",
- "control sequence to too much text. How can we recover?",
- "My plan is to forget the whole thing and hope for the best.");
- back_error();
- }
-
- pstack[n] = link(temp_head);
- align_state = align_state - unbalance;
-
- for (m = 0; m <= n; m++)
- flush_list(pstack[m]);
- goto exit;
- }
-
- if (cur_tok < right_brace_limit)
- if (cur_tok < left_brace_limit)
- incr(unbalance);
- else
- {
- decr(unbalance);
-
- if (unbalance == 0)
- goto done1;
- }
- }
-done1:
- rbrace_ptr = p;
- store_new_token(cur_tok);
- }
- else
- {
- back_input();
- print_err("Argument of ");
- sprint_cs(warning_index);
- print_string(" has an extra }");
- help6("I've run across a `}' that doesn't seem to match anything.",
- "For example, `\\def\\a#1{...}' and `\\a}' would produce",
- "this error. If you simply proceed now, the `\\par' that",
- "I've just inserted will cause me to report a runaway",
- "argument that might be the root of the problem. But if",
- "your `}' was spurious, just type `2' and it will go away.");
- incr(align_state);
- long_state = call;
- cur_tok = par_token;
- ins_error();
- goto continu;
- }
- else
- {
- if (cur_tok == space_token)
- if (info(r) <= end_match_token)
- if (info(r) >= match_token)
- goto continu;
-
- store_new_token(cur_tok);
- }
-
- incr(m);
-
- if (info(r) > end_match_token)
- goto continu;
-
- if (info(r) < match_token)
- goto continu;
-found:
- if (s != 0)
- {
- if ((m == 1) && (info(p) < right_brace_limit) && (p != temp_head))
- {
- link(rbrace_ptr) = 0;
- free_avail(p);
- p = link(temp_head);
- pstack[n] = link(p);
- free_avail(p);
- }
- else
- pstack[n] = link(temp_head);
-
- incr(n);
-
- if (tracing_macros > 0)
- {
- begin_diagnostic();
- //print_nl(match_chr);
- print_nl(""); print(match_chr);
- print_int(n);
- print_string("<-");
- show_token_list(pstack[n - 1], 0, 1000);
- end_diagnostic(false);
- }
- }
- }
- while (!(info(r) == end_match_token));
- }
-
- while ((state == token_list) && (loc == 0) &&
- (index != v_template))
- end_token_list();
-
- begin_token_list(ref_count, macro);
- cur_input.name_field = warning_index;
- loc = link(r);
-
- if (n > 0)
- {
- if (param_ptr + n > max_param_stack)
- {
- max_param_stack = param_ptr + n;
-
-#ifdef ALLOCATEPARAMSTACK
- if (max_param_stack > current_param_size)
- param_stack = realloc_param_stack(increment_param_size);
-
- if (max_param_stack > current_param_size)
- {
- overflow("parameter stack size", current_param_size);
- return;
- }
-#else
- if (max_param_stack > param_size)
- {
- overflow("parameter stack size", param_size);
- return;
- }
-#endif
- }
-
- for (m = 0; m <= n - 1; m++)
- param_stack[param_ptr + m] = pstack[m];
-
- param_ptr = param_ptr + n;
- }
-exit:
- scanner_status = save_scanner_status;
- warning_index = save_warning_index;
-}
-/* sec 0379 */
-void insert_relax (void)
-{
- cur_tok = cs_token_flag + cur_cs;
- back_input();
- cur_tok = cs_token_flag + frozen_relax; /* 96/Jan/10 */
- back_input();
- index = inserted;
-}
-/* sec 0366 */
-void expand (void)
-{
- halfword t;
- pointer p, q, r;
- integer j;
- integer cv_backup;
- small_number cvl_backup, radix_backup, co_backup;
- halfword backup_backup;
- small_number save_scanner_status;
-
- cv_backup = cur_val;
- cvl_backup = cur_val_level;
- radix_backup = radix;
- co_backup = cur_order;
- backup_backup = link(backup_head);
-
- if (cur_cmd < call)
- {
- if (tracing_commands > 1)
- show_cur_cmd_chr();
-
- switch (cur_cmd)
- {
- case top_bot_mark:
- if (cur_mark[cur_chr] != 0)
- begin_token_list(cur_mark[cur_chr], mark_text);
- break;
-
- case expand_after:
- get_token();
- t = cur_tok;
- get_token();
-
- if (cur_cmd > max_command)
- expand();
- else
- back_input();
-
- cur_tok = t;
- back_input();
- break;
-
- case no_expand:
- save_scanner_status = scanner_status;
- scanner_status = normal;
- get_token();
- scanner_status = save_scanner_status;
- t = cur_tok;
- back_input();
-
- if (t >= cs_token_flag)
- {
- p = get_avail();
- info(p) = cs_token_flag + frozen_dont_expand; /*96/Jan/10*/
- link(p) = loc;
- start = p;
- loc = p;
- }
- break;
-
- case cs_name:
- r = get_avail();
- p = r;
- do
- {
- get_x_token();
-
- if (cur_cs == 0)
- store_new_token(cur_tok);
- }
- while (!(cur_cs != 0));
-
- if (cur_cmd != end_cs_name)
- {
- print_err("Missing ");
- print_esc("endcsname");
- print_string(" inserted");
- help2("The control sequence marked <to be read again> should",
- "not appear between \\csname and \\endcsname.");
- back_error();
- }
-
- j = first;
- p = link(r);
-
- while (p != 0)
- {
- if (j >= max_buf_stack)
- {
- max_buf_stack = j + 1;
-
-#ifdef ALLOCATEBUFFER
- if (max_buf_stack == current_buf_size)
- buffer = realloc_buffer (increment_buf_size);
-
- if (max_buf_stack == current_buf_size) /* check again after allocation */
- {
- overflow("buffer size", current_buf_size);
- return;
- }
-#else
- if (max_buf_stack == buf_size)
- {
- overflow("buffer size", buf_size); /* buffer size - not dynamic */
- return;
- }
-#endif
- }
-
- buffer[j] = info(p) % 256;
- incr(j);
- p = link(p);
- }
-
- if (j > first + 1)
- {
- no_new_control_sequence = false;
- cur_cs = id_lookup(first, j - first);
- no_new_control_sequence = true;
- }
- else if (j == first)
- cur_cs = null_cs;
- else
- cur_cs = single_base + buffer[first];
-
- flush_list(r);
-
- if (eq_type(cur_cs) == undefined_cs)
- {
- eq_define(cur_cs, relax, 256);
- }
-
- cur_tok = cur_cs + cs_token_flag;
- back_input();
- break;
-
- case convert:
- conv_toks();
- break;
-
- case the:
- ins_the_toks();
- break;
-
- case if_test:
- conditional();
- break;
-
- case fi_or_else:
- if (cur_chr > if_limit)
- if (if_limit == 1)
- insert_relax();
- else
- {
- print_err("Extra ");
- print_cmd_chr(fi_or_else, cur_chr);
- help1("I'm ignoring this; it doesn't match any \\if.");
- error();
- }
- else
- {
- while (cur_chr != fi_code)
- pass_text();
-
- {
- p = cond_ptr;
- if_line = if_line_field(p);
- cur_if = subtype(p);
- if_limit = type(p);
- cond_ptr = link(p);
- free_node(p, if_node_size);
- }
- }
- break;
-
- case input:
- if (cur_chr > 0)
- force_eof = true;
- else if (name_in_progress)
- insert_relax();
- else
- start_input();
- break;
-
- default:
- print_err("Undefined control sequence");
- help5("The control sequence at the end of the top line",
- "of your error message was never \\def'ed. If you have",
- "misspelled it (e.g., `\\hobx'), type `I' and the correct",
- "spelling (e.g., `I\\hbox'). Otherwise just continue,",
- "and I'll forget about whatever was undefined.");
- error();
- break;
- }
- }
- else if (cur_cmd < end_template)
- {
- macro_call();
- }
- else
- {
- cur_tok = cs_token_flag + frozen_endv; /* 96/Jan/10 */
- back_input();
- }
-
- cur_val = cv_backup;
- cur_val_level = cvl_backup;
- radix = radix_backup;
- cur_order = co_backup;
- link(backup_head) = backup_backup;
-}
-/* sec 0380 */
-void get_x_token (void)
-{
-restart:
- get_next();
-
- if (cur_cmd <= max_command)
- goto done;
-
- if (cur_cmd >= call)
- if (cur_cmd < end_template)
- macro_call();
- else
- {
- cur_cs = frozen_endv;
- cur_cmd = endv;
- goto done;
- }
- else
- expand();
-
- goto restart;
-
-done:
- if (cur_cs == 0)
- cur_tok = (cur_cmd * 256) + cur_chr;
- else
- cur_tok = cs_token_flag + cur_cs;
-}
-/* sec 0381 */
-void x_token (void)
-{
- while (cur_cmd > max_command)
- {
- expand();
- get_next();
- }
-
- if (cur_cs == 0)
- cur_tok = (cur_cmd * 256) + cur_chr;
- else
- cur_tok = cs_token_flag + cur_cs;
-}
-/* sec 0403 */
-void scan_left_brace (void)
-{
- do
- {
- get_x_token();
- }
- while (!((cur_cmd != spacer) && (cur_cmd != relax)));
-
- if (cur_cmd != left_brace)
- {
- print_err("Missing { inserted");
- help4("A left brace was mandatory here, so I've put one in.",
- "You might want to delete and/or insert some corrections",
- "so that I will find a matching right brace soon.",
- "(If you're confused by all this, try typing `I}' now.)");
- back_error();
- cur_tok = left_brace_token + '{';
- cur_cmd = left_brace;
- cur_chr = '{';
- incr(align_state);
- }
-}
-/* sec 0405 */
-void scan_optional_equals (void)
-{
- do
- {
- get_x_token();
- }
- while (!(cur_cmd != spacer));
-
- if (cur_tok != other_token + '=')
- back_input();
-}
-/* sec 0407 */
-boolean scan_keyword(const char * s)
-{
- halfword p;
- halfword q;
- const char * k;
-
- p = backup_head;
- link(p) = 0;
- k = s;
-
- while (*k)
- {
- get_x_token();
-
- if ((cur_cs == 0) && ((cur_chr == (*k)) || (cur_chr == (*k) - 'a' + 'A')))
- {
- store_new_token(cur_tok);
- incr(k);
- }
- else if ((cur_cmd != spacer) || (p != backup_head))
- {
- back_input();
-
- if (p != backup_head)
- back_list(link(backup_head));
-
- return false;
- }
- }
-
- flush_list(link(backup_head));
-
- return true;
-}
-/* sec 0408 */
-void mu_error (void)
-{
- print_err("Incompatible glue units");
- help1("I'm going to assume that 1mu=1pt when they're mixed.");
- error();
-}
-/* sec 0433 */
-void scan_eight_bit_int (void)
-{
- scan_int();
-
- if ((cur_val < 0) || (cur_val > 255))
- {
- print_err("Bad register code");
- help2("A register number must be between 0 and 255.",
- "I changed this one to zero.");
- int_error(cur_val);
- cur_val = 0;
- }
-}
-/* sec 0434 */
-void scan_char_num (void)
-{
- scan_int();
-
- if ((cur_val < 0) || (cur_val > 255))
- {
- print_err("Bad character code");
- help2("A character number must be between 0 and 255.",
- "I changed this one to zero.");
- int_error(cur_val);
- cur_val = 0;
- }
-}
-/* sec 0435 */
-void scan_four_bit_int (void)
-{
- scan_int();
-
- if ((cur_val < 0) || (cur_val > 15))
- {
- print_err("Bad number");
- help2("Since I expected to read a number between 0 and 15,",
- "I changed this one to zero.");
- int_error(cur_val);
- cur_val = 0;
- }
-}
-/* sec 0436 */
-void scan_fifteen_bit_int (void)
-{
- scan_int();
-
- if ((cur_val < 0) || (cur_val > 32767))
- {
- print_err("Bad mathchar");
- help2("A mathchar number must be between 0 and 32767.",
- "I changed this one to zero.");
- int_error(cur_val);
- cur_val = 0;
- }
-}
-/* sec 0437 */
-void scan_twenty_seven_bit_int (void)
-{
- scan_int();
-
- if ((cur_val < 0) || (cur_val > 134217727L))
- {
- print_err("Bad delimiter code");
- help2("A numeric delimiter code must be between 0 and 2^{27}-1.",
- "I changed this one to zero.");
- int_error(cur_val);
- cur_val = 0;
- }
-}
-/* sec 0577 */
-void scan_font_ident (void)
-{
- internal_font_number f;
- halfword m;
-
- do
- {
- get_x_token();
- }
- while (!(cur_cmd != spacer));
-
- if (cur_cmd == def_font)
- f = cur_font;
- else if (cur_cmd == set_font)
- f = cur_chr;
- else if (cur_cmd == def_family)
- {
- m = cur_chr;
- scan_four_bit_int();
- f = equiv(m + cur_val);
- }
- else
- {
- print_err("Missing font identifier");
- help2("I was looking for a control sequence whose",
- "current meaning has been defined by \\font.");
- back_error();
- f = null_font;
- }
-
- cur_val = f;
-}
-/* sec 0578 */
-void find_font_dimen_(boolean writing)
-{
- internal_font_number f;
- integer n;
-
- scan_int();
- n = cur_val;
- scan_font_ident();
- f = cur_val;
-
- if (n < 0 || (n == 0 && font_dimen_zero == 0)) /* change 98/Oct/5 */
- cur_val = fmem_ptr;
- else
- {
- if (writing && (n <= space_shrink_code) && (n >= space_code) && (font_glue[f] != 0))
- {
- delete_glue_ref(font_glue[f]);
- font_glue[f] = 0;
- }
-
- if (n > font_params[f])
- if (f < font_ptr)
- cur_val = fmem_ptr;
- else
- {
- do
- {
- #ifdef ALLOCATEFONT
- if (fmem_ptr == current_font_mem_size)
- font_info = realloc_font_info(increment_font_mem_size);
-
- if (fmem_ptr == current_font_mem_size)
- {
- overflow("font memory", current_font_mem_size);
- return;
- }
-#else
- if (fmem_ptr == font_mem_size)
- {
- overflow("font memory", font_mem_size);
- return;
- }
-#endif
- font_info[fmem_ptr].cint = 0;
- incr(fmem_ptr);
- incr(font_params[f]);
- }
- while (!(n == font_params[f]));
-
- cur_val = fmem_ptr - 1;
- }
- else if (n > 0)
- cur_val = n + param_base[f];
- }
-
- if (cur_val == fmem_ptr)
- {
- print_err("Font ");
- print_esc(""); print(font_id_text(f));
- print_string(" has only ");
- print_int(font_params[f]);
- print_string(" fontdimen parameters");
- help2("To increase the number of font parameters, you must",
- "use \\fontdimen immediately after the \\font is loaded.");
- error();
- }
-}
-/* sec 0413 */
-void scan_something_internal_(small_number level, boolean negative)
-{
- halfword m;
- integer p;
-
- m = cur_chr;
-
- switch (cur_cmd)
- {
- case def_code:
- {
- scan_char_num();
-
- if (m == math_code_base)
- scanned_result(math_code(cur_val), int_val);
- else if (m < math_code_base)
- scanned_result(equiv(m + cur_val), int_val);
- else
- scanned_result(eqtb[m + cur_val].cint, int_val);
- }
- break;
-
- case toks_register:
- case assign_toks:
- case def_family:
- case set_font:
- case def_font:
- if (level != tok_val)
- {
- print_err("Missing number, treated as zero");
- help3("A number should have been here; I inserted `0'.",
- "(If you can't figure out why I needed to see a number,",
- "look up `weird error' in the index to The TeXbook.)");
- back_error();
- scanned_result(0, dimen_val);
- }
- else if (cur_cmd <= assign_toks)
- {
- if (cur_cmd < assign_toks)
- {
- scan_eight_bit_int();
- m = toks_base + cur_val;
- }
-
- scanned_result(equiv(m), tok_val);
- }
- else
- {
- back_input();
- scan_font_ident();
- scanned_result(font_id_base + cur_val, ident_val);
- }
- break;
-
- case assign_int:
- scanned_result(eqtb[m].cint, int_val);
- break;
-
- case assign_dimen:
- scanned_result(eqtb[m].cint, dimen_val);
- break;
-
- case assign_glue:
- scanned_result(equiv(m), glue_val);
- break;
-
- case assign_mu_glue:
- scanned_result(equiv(m), mu_val);
- break;
-
- case set_aux:
- if (abs(mode) != m)
- {
- print_err("Improper ");
- print_cmd_chr(set_aux, m);
- help4("You can refer to \\spacefactor only in horizontal mode;",
- "you can refer to \\prevdepth only in vertical mode; and",
- "neither of these is meaningful inside \\write. So",
- "I'm forgetting what you said and using zero instead.");
- error();
-
- if (level != tok_val)
- scanned_result(0, dimen_val);
- else
- scanned_result(0, int_val);
- }
- else if (m == vmode)
- scanned_result(prev_depth, dimen_val);
- else
- scanned_result(space_factor, int_val);
- break;
-
- case set_prev_graf:
- if (mode == 0)
- scanned_result(0, int_val);
- else
- {
- nest[nest_ptr] = cur_list;
- p = nest_ptr;
-
- while (abs(nest[p].mode_field) != vmode)
- decr(p);
-
- scanned_result(nest[p].pg_field, int_val);
- }
- break;
-
- case set_page_int:
- {
- if (m == 0)
- cur_val = dead_cycles;
- else
- cur_val = insert_penalties;
-
- cur_val_level = 0;
- }
- break;
-
- case set_page_dimen:
- {
- if ((page_contents == 0) && (! output_active))
- if (m == 0)
- cur_val = max_dimen;
- else
- cur_val = 0;
- else
- cur_val = page_so_far[m];
-
- cur_val_level = dimen_val;
- }
- break;
-
- case set_shape:
- {
- if (par_shape_ptr == 0)
- cur_val = 0;
- else
- cur_val = info(par_shape_ptr);
-
- cur_val_level = int_val;
- }
- break;
-
- case set_box_dimen:
- {
- scan_eight_bit_int();
-
- if (box(cur_val) == 0)
- cur_val = 0;
- else
- cur_val = mem[box(cur_val) + m].cint;
-
- cur_val_level = dimen_val;
- }
- break;
-
- case char_given:
- case math_given:
- scanned_result(cur_chr, int_val);
- break;
-
- case assign_font_dimen:
- {
- find_font_dimen(false);
- font_info[fmem_ptr].cint = 0;
- scanned_result(font_info[cur_val].cint, dimen_val);
- }
- break;
-
- case assign_font_int:
- {
- scan_font_ident();
-
- if (m == 0)
- scanned_result(hyphen_char[cur_val], int_val);
- else
- scanned_result(skew_char[cur_val], int_val);
- }
- break;
-
- case tex_register:
- {
- scan_eight_bit_int();
-
- switch(m)
- {
- case int_val:
- cur_val = count(cur_val);
- break;
-
- case dimen_val:
- cur_val = dimen(cur_val);
- break;
-
- case glue_val:
- cur_val = skip(cur_val);
- break;
-
- case mu_val:
- cur_val = mu_skip(cur_val);
- break;
- }
-
- cur_val_level = m;
- }
- break;
-
- case last_item:
- if (cur_chr > glue_val)
- {
- if (cur_chr == input_line_no_code)
- cur_val = line;
- else
- cur_val = last_badness;
-
- cur_val_level = int_val;
- }
- else
- {
- if (cur_chr == glue_val)
- cur_val = zero_glue;
- else
- cur_val = 0;
-
- cur_val_level = cur_chr;
-
- if (!is_char_node(tail) && (mode != 0))
- switch(cur_chr)
- {
- case int_val:
- if (type(tail) == penalty_node)
- cur_val = penalty(tail);
- break;
-
- case dimen_val:
- if (type(tail) == kern_node)
- cur_val = width(tail);
- break;
-
- case glue_val:
- if (type(tail) == glue_node)
- {
- cur_val = glue_ptr(tail);
-
- if (subtype(tail) == mu_glue)
- cur_val_level = mu_val;
- }
- break;
- }
- else if ((mode == vmode) && (tail == head))
- switch (cur_chr)
- {
- case int_val:
- cur_val = last_penalty;
- break;
-
- case dimen_val:
- cur_val = last_kern;
- break;
-
- case glue_val:
- if (last_glue != empty_flag)
- cur_val = last_glue;
- break;
- }
- }
- break;
-
- default:
- {
- print_err("You can't use `");
- print_cmd_chr(cur_cmd, cur_chr);
- print_string("' after ");
- print_esc("the");
- help1("I'm forgetting what you said and using zero instead.");
- error();
-
- if (level != tok_val)
- scanned_result(0, dimen_val);
- else
- scanned_result(0, int_val);
- }
- break;
- }
-
- while (cur_val_level > level)
- {
- if (cur_val_level == glue_val)
- cur_val = width(cur_val);
- else if (cur_val_level == mu_val)
- mu_error();
-
- decr(cur_val_level);
- }
-
- if (negative)
- if (cur_val_level >= 2)
- {
- cur_val = new_spec(cur_val);
-
- {
- width(cur_val) = -width(cur_val);
- stretch(cur_val) = -stretch(cur_val);
- shrink(cur_val) = -shrink(cur_val);
- }
- }
- else
- cur_val = -cur_val;
- else if ((cur_val_level >= glue_val) && (cur_val_level <= mu_val))
- add_glue_ref(cur_val);
-}
-/* sec 0341 */
-void get_next (void)
-{
- integer k;
- halfword t;
-/* char cat; */ /* make this an int ? */
- int cat; /* make this an int ? 95/Jan/7 */
- ASCII_code c, cc;
- char d;
-
-restart:
- cur_cs = 0;
-
- if (state != token_list)
- {
-lab_switch:
- if (loc <= limit)
- {
- cur_chr = buffer[loc];
- incr(loc);
-reswitch:
- cur_cmd = cat_code(cur_chr);
-
- switch (state + cur_cmd)
- {
- case any_state_plus(ignore):
- case skip_blanks + spacer:
- case new_line + spacer:
- goto lab_switch;
- break;
-
- case any_state_plus(escape):
- {
- if (loc > limit)
- cur_cs = null_cs;
- else
- {
-start_cs:
- k = loc;
- cur_chr = buffer[k];
- cat = cat_code(cur_chr);
- incr(k);
-
- if (cat == letter)
- state = skip_blanks;
- else if (cat == spacer)
- state = skip_blanks;
- else
- state = mid_line;
-
- if ((cat == letter) && (k <= limit))
- {
- do
- {
- cur_chr = buffer[k];
- cat = cat_code(cur_chr);
- incr(k);
- }
- while (!((cat != letter) || (k > limit)));
-
- {
- if (buffer[k]== cur_chr)
- if (cat == sup_mark)
- if (k < limit)
- {
- c = buffer[k + 1];
-
- if (c < 128)
- {
- d = 2;
- if (is_hex(c))
- if (k + 2 <= limit)
- {
- cc = buffer[k + 2];
-
- if (is_hex(cc))
- incr(d);
- }
-
- if (d > 2)
- {
- hex_to_cur_chr();
- buffer[k - 1] = cur_chr;
- }
- else if (c < 64)
- buffer[k - 1] = c + 64;
- else
- buffer[k - 1] = c - 64;
-
- limit = limit - d;
- first = first - d;
-
- while (k <= limit)
- {
- buffer[k] = buffer[k + d];
- incr(k);
- }
-
- goto start_cs;
- }
- }
- }
-
- if (cat != letter)
- decr(k);
-
- if (k > loc + 1)
- {
- cur_cs = id_lookup(loc, k - loc);
- loc = k;
- goto found;
- }
- }
- else
- {
- if (buffer[k] == cur_chr)
- if (cat == sup_mark)
- if (k < limit)
- {
- c = buffer[k + 1];
-
- if (c < 128) /* ? */
- {
- d = 2;
-
- if (is_hex(c))
- if (k + 2 <= limit)
- {
- cc = buffer[k + 2];
-
- if (is_hex(cc))
- incr(d);
- }
-
- if (d > 2)
- {
- hex_to_cur_chr();
- buffer[k - 1] = cur_chr;
- }
- else if (c < 64)
- buffer[k - 1] = c + 64;
- else
- buffer[k - 1] = c - 64;
-
- limit = limit - d;
- first = first - d;
-
- while (k <= limit)
- {
- buffer[k] = buffer[k + d];
- incr(k);
- }
- goto start_cs;
- }
- }
- }
- cur_cs = single_base + buffer[loc];
- incr(loc);
- }
-found:
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
-
- if (cur_cmd >= outer_call)
- check_outer_validity();
- }
- break;
-
- case any_state_plus(active_char):
- {
- cur_cs = cur_chr + active_base;
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
- state = mid_line;
-
- if (cur_cmd >= outer_call)
- check_outer_validity();
- }
- break;
-
- case any_state_plus(sup_mark):
- {
- if (cur_chr == buffer[loc])
- if (loc < limit)
- {
- c = buffer[loc + 1];
-
- if (c < 128)
- {
- loc = loc + 2;
-
- if (is_hex(c))
- if (loc <= limit)
- {
- cc = buffer[loc];
-
- if (is_hex(cc))
- {
- incr(loc);
- hex_to_cur_chr();
- goto reswitch;
- }
- }
-
- if (c < 64)
- cur_chr = c + 64;
- else
- cur_chr = c - 64;
-
- goto reswitch;
- }
- }
-
- state = mid_line;
- }
- break;
-
- case any_state_plus(invalid_char):
- {
- print_err("Text line contains an invalid character");
- help2("A funny symbol that I can't read has just been input.",
- "Continue, and I'll forget that it ever happened.");
- deletions_allowed = false;
- error();
- deletions_allowed = true;
- goto restart;
- }
- break;
-
- case mid_line + spacer:
- {
- state = skip_blanks;
- cur_chr = ' ';
- }
- break;
-
- case mid_line + car_ret:
- {
- loc = limit + 1;
- cur_cmd = spacer;
- cur_chr = ' ';
- }
- break;
-
- case skip_blanks + car_ret:
- case any_state_plus(comment):
- {
- loc = limit + 1;
- goto lab_switch;
- }
- break;
-
- case new_line + car_ret:
- {
- loc = limit + 1;
- cur_cs = par_loc;
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
-
- if (cur_cmd >= outer_call)
- check_outer_validity();
- }
- break;
-
- case mid_line + left_brace:
- incr(align_state);
- break;
-
- case skip_blanks + left_brace:
- case new_line + left_brace:
- {
- state = mid_line;
- incr(align_state);
- }
- break;
-
- case mid_line + right_brace:
- decr(align_state);
- break;
-
- case skip_blanks + right_brace:
- case new_line + right_brace:
- {
- state = 1;
- decr(align_state);
- }
- break;
-
- case add_delims_to(skip_blanks):
- case add_delims_to(new_line):
- state = 1;
- break;
-
- default:
- break;
- }
- }
- else
- {
- state = new_line;
-
- if (cur_input.name_field > 17)
- {
- incr(line);
- first = start;
-
- if (!force_eof)
- {
- if (input_ln(cur_file, true))
- firm_up_the_line();
- else
- force_eof = true;
- }
-
- if (force_eof)
- {
- print_char(')');
- decr(open_parens);
- update_terminal();
- force_eof = false;
- end_file_reading();
- check_outer_validity();
- goto restart;
- }
-
- if (end_line_char_inactive())
- decr(limit);
- else
- buffer[limit] = end_line_char;
-
- first = limit + 1;
- loc = start;
- }
- else
- {
- if (!(cur_input.name_field == 0))
- {
- cur_cmd = 0;
- cur_chr = 0;
- return;
- }
-
- if (input_ptr > 0)
- {
- end_file_reading();
- goto restart;
- }
-
- if (selector < log_only)
- open_log_file();
-
- if (interaction > nonstop_mode)
- {
- if (end_line_char_inactive())
- incr(limit);
-
- if (limit == start)
- print_nl("(Please type a command or say `\\end')");
-
- print_ln();
- first = start;
- prompt_input("*");
- limit = last;
-
- if (end_line_char_inactive())
- decr(limit);
- else
- buffer[limit]= end_line_char;
-
- first = limit + 1;
- loc = start;
- }
- else
- {
- fatal_error("*** (job aborted, no legal \\end found)");
- return;
- }
- }
-
- check_interrupt();
- goto lab_switch;
- }
- }
- else if (loc != 0)
- {
- t = info(loc);
- loc = link(loc);
-
- if (t >= cs_token_flag)
- {
- cur_cs = t - cs_token_flag;
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
-
- if (cur_cmd >= outer_call)
- if (cur_cmd == dont_expand)
- {
- cur_cs = info(loc) - cs_token_flag;
- loc = 0;
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
-
- if (cur_cmd > max_command)
- {
- cur_cmd = relax;
- cur_chr = no_expand_flag;
- }
- }
- else
- {
- check_outer_validity();
- }
- }
- else
- {
- cur_cmd = t / 256;
- cur_chr = t % 256;
-
- switch (cur_cmd)
- {
- case left_brace:
- incr(align_state);
- break;
-
- case right_brace:
- decr(align_state);
- break;
-
- case out_param:
- {
- begin_token_list(param_stack[limit + cur_chr - 1], parameter);
- goto restart;
- }
- break;
-
- default:
- break;
- }
- }
- }
- else
- {
- end_token_list();
- goto restart;
- }
-
- if (cur_cmd <= car_ret)
- if (cur_cmd >= tab_mark)
- if (align_state == 0)
- {
- if ((scanner_status == aligning) && (cur_align == 0))
- {
- fatal_error("(interwoven alignment preambles are not allowed)");
- return;
- }
-
- cur_cmd = extra_info(cur_align);
- extra_info(cur_align) = cur_chr;
-
- if (cur_cmd == omit)
- begin_token_list(omit_template, v_template);
- else
- begin_token_list(v_part(cur_align), v_template);
-
- align_state = 1000000L;
- goto restart;
- }
+/* Copyright 2014 Clerk Ma\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; either version 2 of the License, or\r
+ (at your option) any later version.\r
+\r
+ This program is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+ General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License\r
+ along with this program; if not, write to the Free Software\r
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\r
+ 02110-1301 USA. */\r
+\r
+#define EXTERN extern\r
+\r
+#include "yandytex.h"\r
+\r
+/* following bit used to be end of tex1.c */\r
+#ifdef STAT\r
+/* sec 0284 */\r
+void restore_trace (pointer p, const char * s)\r
+{\r
+ begin_diagnostic();\r
+ print_char('{');\r
+ prints(s);\r
+ print_char(' ');\r
+ show_eqtb(p);\r
+ print_char('}');\r
+ end_diagnostic(false);\r
+}\r
+#endif\r
+/* sec 0281 */\r
+void unsave (void)\r
+{\r
+ pointer p;\r
+ quarterword l;\r
+ halfword t;\r
+\r
+ if (cur_level > level_one)\r
+ {\r
+ decr(cur_level);\r
+\r
+ while (true)\r
+ {\r
+ decr(save_ptr);\r
+\r
+ if (save_type(save_ptr) == level_boundary)\r
+ goto done;\r
+\r
+ p = save_index(save_ptr);\r
+\r
+ if (save_type(save_ptr) == insert_token)\r
+ {\r
+ t = cur_tok;\r
+ cur_tok = p;\r
+ back_input();\r
+ cur_tok = t;\r
+ }\r
+ else\r
+ {\r
+ if (save_type(save_ptr) == restore_old_value)\r
+ {\r
+ l = save_level(save_ptr);\r
+ decr(save_ptr);\r
+ }\r
+ else\r
+ save_stack[save_ptr] = eqtb[undefined_control_sequence];\r
+ \r
+ if (p < int_base)\r
+ if (eq_level(p) == level_one)\r
+ {\r
+ eq_destroy(save_stack[save_ptr]);\r
+#ifdef STAT\r
+ if (tracing_restores > 0)\r
+ restore_trace(p, "retaining");\r
+#endif\r
+ }\r
+ else\r
+ {\r
+ eq_destroy(eqtb[p]);\r
+ eqtb[p] = save_stack[save_ptr];\r
+#ifdef STAT\r
+ if (tracing_restores > 0)\r
+ restore_trace(p, "restoring");\r
+#endif\r
+ }\r
+ else if (xeq_level[p] != level_one)\r
+ {\r
+ eqtb[p] = save_stack[save_ptr];\r
+ xeq_level[p] = l;\r
+#ifdef STAT\r
+ if (tracing_restores > 0)\r
+ restore_trace(p, "restoring");\r
+#endif\r
+ }\r
+ else\r
+ {\r
+#ifdef STAT\r
+ if (tracing_restores > 0)\r
+ restore_trace(p, "retaining");\r
+#endif\r
+ }\r
+ }\r
+ }\r
+\r
+done:\r
+ cur_group = save_level(save_ptr);\r
+ cur_boundary = save_index(save_ptr);\r
+ }\r
+ else\r
+ {\r
+ confusion("curlevel");\r
+ return;\r
+ }\r
+}\r
+/* sec 0288 */\r
+void prepare_mag (void) \r
+{\r
+ if ((mag_set > 0) && (mag != mag_set))\r
+ {\r
+ print_err("Incompatible magnification (");\r
+ print_int(mag);\r
+ prints(");");\r
+ print_nl(" the previous value will be retained");\r
+ help2("I can handle only one magnification ratio per job. So I've",\r
+ "reverted to the magnification you used earlier on this run.");\r
+ int_error(mag_set);\r
+ geq_word_define(int_base + mag_code, mag_set);\r
+ }\r
+\r
+ if ((mag <= 0) || (mag > 32768L))\r
+ {\r
+ print_err("Illegal magnification has been changed to 1000");\r
+ help1("The magnification ratio must be between 1 and 32768.");\r
+ int_error(mag);\r
+ geq_word_define(int_base + mag_code, 1000);\r
+ }\r
+\r
+ mag_set = mag;\r
+}\r
+/* sec 0295 */\r
+void token_show (pointer p)\r
+{\r
+ if (p != 0)\r
+ show_token_list(link(p), 0, 10000000L);\r
+}\r
+/* sec 0296 */\r
+void print_meaning (void) \r
+{\r
+ print_cmd_chr(cur_cmd, cur_chr);\r
+\r
+ if (cur_cmd >= call)\r
+ {\r
+ print_char(':');\r
+ print_ln();\r
+ token_show(cur_chr);\r
+ }\r
+ else if (cur_cmd == top_bot_mark)\r
+ {\r
+ print_char(':');\r
+ print_ln();\r
+ token_show(cur_mark[cur_chr]);\r
+ }\r
+}\r
+/* sec 0299 */\r
+void show_cur_cmd_chr (void)\r
+{ \r
+ begin_diagnostic();\r
+ print_nl("{");\r
+\r
+ if (mode != shown_mode)\r
+ {\r
+ print_mode(mode);\r
+ prints(": ");\r
+ shown_mode = mode;\r
+ }\r
+\r
+ print_cmd_chr(cur_cmd, cur_chr);\r
+ print_char('}');\r
+ end_diagnostic(false);\r
+}\r
+/* sec 0311 */\r
+void show_context (void)\r
+{\r
+ char old_setting;\r
+ integer nn;\r
+ boolean bottom_line;\r
+ integer i;\r
+ integer j;\r
+ integer l;\r
+ integer m;\r
+ integer n;\r
+ integer p;\r
+ integer q;\r
+\r
+ base_ptr = input_ptr;\r
+ input_stack[base_ptr] = cur_input;\r
+ nn = -1;\r
+ bottom_line = false;\r
+\r
+ while (true)\r
+ {\r
+ cur_input = input_stack[base_ptr];\r
+\r
+ if ((state != token_list))\r
+ if ((name > 17) || (base_ptr == 0))\r
+ bottom_line = true;\r
+\r
+ if ((base_ptr == input_ptr) || bottom_line || (nn < error_context_lines))\r
+ {\r
+ if ((base_ptr == input_ptr) || (state != token_list) ||\r
+ (index != backed_up) || (loc != 0))\r
+ {\r
+ tally = 0;\r
+ old_setting = selector;\r
+\r
+ if (state != token_list)\r
+ {\r
+ if (name <= 17)\r
+ if (name == 0)\r
+ if (base_ptr == 0)\r
+ print_nl("<*>");\r
+ else\r
+ print_nl("<insert> ");\r
+ else\r
+ {\r
+ print_nl("<read ");\r
+\r
+ if (name == 17)\r
+ print_char('*');\r
+ else\r
+ print_int(name - 1);\r
+\r
+ print_char('>');\r
+ }\r
+ else\r
+ {\r
+ if (c_style_flag)\r
+ {\r
+ print_ln();\r
+\r
+ if (name > 17)\r
+ print(name);\r
+\r
+ print_char('(');\r
+ print_int(line);\r
+ prints(") :");\r
+ }\r
+ else\r
+ {\r
+ print_nl("l.");\r
+ print_int(line);\r
+ }\r
+ }\r
+\r
+ print_char(' ');\r
+ begin_pseudoprint();\r
+\r
+ if (buffer[limit] == end_line_char)\r
+ j = limit;\r
+ else\r
+ j = limit + 1;\r
+\r
+ if (j > 0)\r
+ for (i = start; i <= j - 1; i++)\r
+ {\r
+ if (i == loc)\r
+ set_trick_count();\r
+\r
+ print(buffer[i]);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ switch (index)\r
+ {\r
+ case parameter:\r
+ print_nl("<argument> ");\r
+ break;\r
+\r
+ case u_template:\r
+ case v_template:\r
+ print_nl("<template> ");\r
+ break;\r
+\r
+ case backed_up:\r
+ if (loc == 0)\r
+ print_nl("<recently read> ");\r
+ else\r
+ print_nl("<to be read again> ");\r
+ break;\r
+\r
+ case inserted:\r
+ print_nl("<inserted text> ");\r
+ break;\r
+\r
+ case macro:\r
+ print_ln();\r
+ print_cs(name);\r
+ break;\r
+\r
+ case output_text:\r
+ print_nl("<output> ");\r
+ break;\r
+\r
+ case every_par_text:\r
+ print_nl("<everypar> ");\r
+ break;\r
+\r
+ case every_math_text:\r
+ print_nl("<everymath> ");\r
+ break;\r
+\r
+ case every_display_text:\r
+ print_nl("<everydisplay> ");\r
+ break;\r
+\r
+ case every_hbox_text:\r
+ print_nl("<everyhbox> ");\r
+ break;\r
+\r
+ case every_vbox_text:\r
+ print_nl("<everyvbox> ");\r
+ break;\r
+\r
+ case every_job_text:\r
+ print_nl("<everyjob> ");\r
+ break;\r
+\r
+ case every_cr_text:\r
+ print_nl("<everycr> ");\r
+ break;\r
+\r
+ case mark_text:\r
+ print_nl("<mark> ");\r
+ break;\r
+\r
+ case write_text:\r
+ print_nl("<write> ");\r
+ break;\r
+\r
+ default:\r
+ print_nl("?");\r
+ break;\r
+ }\r
+\r
+ begin_pseudoprint();\r
+\r
+ if (index < macro)\r
+ show_token_list(start, loc, 100000L);\r
+ else\r
+ show_token_list(link(start), loc, 100000L);\r
+ }\r
+\r
+ selector = old_setting;\r
+\r
+ if (trick_count == 1000000L)\r
+ set_trick_count();\r
+ \r
+ if (tally < trick_count)\r
+ m = tally - first_count;\r
+ else\r
+ m = trick_count - first_count;\r
+\r
+ if (l + first_count <= half_error_line)\r
+ {\r
+ p = 0;\r
+ n = l + first_count;\r
+ }\r
+ else\r
+ {\r
+ prints("...");\r
+ p = l + first_count - half_error_line + 3;\r
+ n = half_error_line;\r
+ }\r
+\r
+ for (q = p; q <= first_count - 1; q++)\r
+ print_char(trick_buf[q % error_line]);\r
+\r
+ print_ln();\r
+\r
+ for (q = 1; q <= n; q++)\r
+ print_char(' ');\r
+\r
+ if (m + n <= error_line)\r
+ p = first_count + m;\r
+ else\r
+ p = first_count +(error_line - n - 3);\r
+\r
+ for (q = first_count; q <= p - 1; q++)\r
+ print_char(trick_buf[q % error_line]);\r
+\r
+ if (m + n > error_line)\r
+ prints("...");\r
+\r
+ incr(nn);\r
+ }\r
+ }\r
+ else if (nn == error_context_lines)\r
+ {\r
+ print_nl("...");\r
+ incr(nn); \r
+ }\r
+\r
+ if (bottom_line)\r
+ goto done;\r
+\r
+ decr(base_ptr);\r
+ }\r
+\r
+done:\r
+ cur_input = input_stack[input_ptr];\r
+}\r
+/* sec 0323 */\r
+void begin_token_list_ (pointer p, quarterword t)\r
+{\r
+ push_input();\r
+ state = token_list;\r
+ start = p;\r
+ index = t;\r
+\r
+ if (t >= macro)\r
+ {\r
+ add_token_ref(p);\r
+\r
+ if (t == macro)\r
+ limit = param_ptr;\r
+ else\r
+ {\r
+ loc = link(p);\r
+\r
+ if (tracing_macros > 1)\r
+ {\r
+ begin_diagnostic(); \r
+ print_nl("");\r
+\r
+ switch (t)\r
+ {\r
+ case mark_text:\r
+ print_esc("mark");\r
+ break;\r
+\r
+ case write_text:\r
+ print_esc("write");\r
+ break;\r
+\r
+ default:\r
+ print_cmd_chr(assign_toks, t - output_text + output_routine_loc);\r
+ break;\r
+ }\r
+\r
+ prints("->");\r
+ token_show(p);\r
+ end_diagnostic(false);\r
+ }\r
+ }\r
+ }\r
+ else\r
+ loc = p;\r
+}\r
+/* sec 0324 */\r
+void end_token_list (void) \r
+{ \r
+ if (index >= backed_up)\r
+ {\r
+ if (index <= inserted)\r
+ flush_list(start); \r
+ else\r
+ {\r
+ delete_token_ref(start);\r
+\r
+ if (index == macro)\r
+ while (param_ptr > limit)\r
+ {\r
+ decr(param_ptr);\r
+ flush_list(param_stack[param_ptr]);\r
+ }\r
+ }\r
+ }\r
+ else if (index == u_template)\r
+ if (align_state > 500000L)\r
+ align_state = 0;\r
+ else\r
+ {\r
+ fatal_error("(interwoven alignment preambles are not allowed)");\r
+ return;\r
+ }\r
+\r
+ pop_input();\r
+ check_interrupt();\r
+}\r
+/* sec 0325 */\r
+void back_input (void)\r
+{\r
+ pointer p;\r
+\r
+ while ((state == 0) && (loc == 0) &&\r
+ (index != v_template))\r
+ {\r
+ end_token_list();\r
+ }\r
+\r
+ p = get_avail();\r
+ info(p) = cur_tok;\r
+\r
+ if (cur_tok < right_brace_limit)\r
+ if (cur_tok < left_brace_limit)\r
+ decr(align_state);\r
+ else\r
+ incr(align_state);\r
+\r
+ push_input();\r
+ state = token_list;\r
+ start = p;\r
+ index = backed_up;\r
+ loc = p;\r
+}\r
+/* sec 0327 */\r
+void back_error (void)\r
+{\r
+ OK_to_interrupt = false;\r
+ back_input();\r
+ OK_to_interrupt = true;\r
+ error();\r
+}\r
+/* sec 0327 */\r
+void ins_error (void) \r
+{\r
+ OK_to_interrupt = false;\r
+ back_input();\r
+ index = inserted;\r
+ OK_to_interrupt = true;\r
+ error();\r
+}\r
+/* sec 0328 */\r
+void begin_file_reading (void)\r
+{\r
+ if (in_open == max_in_open)\r
+ {\r
+ overflow("text input levels", max_in_open);\r
+ return;\r
+ }\r
+\r
+#ifdef ALLOCATEBUFFER\r
+ if (first == current_buf_size)\r
+ buffer = realloc_buffer(increment_buf_size);\r
+\r
+ if (first == current_buf_size)\r
+ {\r
+ overflow("buffer size", current_buf_size);\r
+ return;\r
+ }\r
+#else\r
+ if (first == buf_size)\r
+ {\r
+ overflow("buffer size", buf_size);\r
+ return;\r
+ }\r
+#endif\r
+\r
+ incr(in_open);\r
+\r
+ if (in_open > high_in_open) /* 1999 Jan 17 */\r
+ high_in_open = in_open;\r
+\r
+ push_input();\r
+ index = in_open;\r
+ line_stack[index] = line;\r
+ start = first;\r
+ state = mid_line;\r
+ name = 0;\r
+}\r
+/* sec 0329 */\r
+void end_file_reading (void)\r
+{\r
+ first = start;\r
+ line = line_stack[index];\r
+\r
+ if (name > 17)\r
+ a_close(cur_file);\r
+\r
+ pop_input();\r
+ decr(in_open);\r
+}\r
+/* called only form tex0.c */\r
+/* sec 0330 */\r
+void clear_for_error_prompt (void) \r
+{\r
+ while ((state != 0) && (name == 0) &&\r
+ (input_ptr > 0) && (loc > limit))\r
+ end_file_reading();\r
+\r
+ print_ln();\r
+}\r
+/* sec 0336 */\r
+void check_outer_validity (void)\r
+{\r
+ pointer p;\r
+ pointer q;\r
+\r
+ if (scanner_status != 0)\r
+ {\r
+ deletions_allowed = false;\r
+\r
+ if (cur_cs != 0)\r
+ {\r
+ if ((state == 0) || (name < 1) || (name > 17))\r
+ {\r
+ p = get_avail();\r
+ info(p) = cs_token_flag + cur_cs;\r
+ back_list(p);\r
+ }\r
+\r
+ cur_cmd = spacer;\r
+ cur_chr = ' ';\r
+ }\r
+\r
+ if (scanner_status > skipping)\r
+ {\r
+ runaway();\r
+\r
+ if (cur_cs == 0)\r
+ print_err("File ended");\r
+ else\r
+ {\r
+ cur_cs = 0;\r
+ print_err("Forbidden control sequence found");\r
+ }\r
+\r
+ prints(" while scanning ");\r
+ p = get_avail();\r
+\r
+ switch (scanner_status)\r
+ {\r
+ case defining:\r
+ prints("definition");\r
+ info(p) = right_brace_token + '}';\r
+ break;\r
+\r
+ case matching:\r
+ prints("use");\r
+ info(p) = par_token;\r
+ long_state = outer_call;\r
+ break;\r
+\r
+ case aligning:\r
+ prints("preamble");\r
+ info(p) = right_brace_token + '}';\r
+ q = p;\r
+ p = get_avail();\r
+ link(p) = q;\r
+ info(p) = cs_token_flag + frozen_cr;\r
+ align_state = -1000000L;\r
+ break;\r
+\r
+ case absorbing:\r
+ prints("text");\r
+ info(p) = right_brace_token + '}';\r
+ break;\r
+ }\r
+\r
+ ins_list(p);\r
+ prints(" of ");\r
+ sprint_cs(warning_index);\r
+ help4("I suspect you have forgotten a `}', causing me",\r
+ "to read past where you wanted me to stop.",\r
+ "I'll try to recover; but if the error is serious,",\r
+ "you'd better type `E' or `X' now and fix your file.");\r
+ error();\r
+ }\r
+ else\r
+ {\r
+ print_err("Incomplete ");\r
+ print_cmd_chr(if_test, cur_if);\r
+ prints("; all text was ignored after line ");\r
+ print_int(skip_line);\r
+ help3("A forbidden control sequence occurred in skipped text.",\r
+ "This kind of error happens when you say `\\if...' and forget",\r
+ "the matching `\\fi'. I've inserted a `\\fi'; this might work.");\r
+\r
+ if (cur_cs != 0)\r
+ cur_cs = 0; \r
+ else\r
+ help_line[2] = "The file ended while I was skipping conditional text.";\r
+\r
+ cur_tok = cs_token_flag + frozen_fi;\r
+ ins_error();\r
+ }\r
+\r
+ deletions_allowed = true;\r
+ }\r
+}\r
+/* sec 0363 */\r
+void firm_up_the_line (void)\r
+{\r
+ integer k;\r
+\r
+ limit = last;\r
+\r
+ if (pausing > 0)\r
+ if (interaction > nonstop_mode)\r
+ {\r
+ ;\r
+ print_ln();\r
+\r
+ if (start < limit)\r
+ for (k = start; k <= limit - 1; k++)\r
+ print(buffer[k]);\r
+\r
+ first = limit;\r
+ prompt_input("=>");\r
+\r
+ if (last > first)\r
+ {\r
+ for (k = first; k <= last - 1; k++)\r
+ buffer[k + start - first] = buffer[k];\r
+\r
+ limit = start + last - first;\r
+ }\r
+ }\r
+}\r
+/* sec 0365 */\r
+void get_token (void)\r
+{ \r
+ no_new_control_sequence = false;\r
+ get_next();\r
+ no_new_control_sequence = true;\r
+\r
+ if (cur_cs == 0)\r
+ cur_tok = (cur_cmd * 256) + cur_chr;\r
+ else\r
+ cur_tok = cs_token_flag + cur_cs;\r
+}\r
+/* sec 0389 */\r
+void macro_call (void)\r
+{\r
+ pointer r;\r
+ pointer p;\r
+ pointer q;\r
+ pointer s;\r
+ pointer t;\r
+ pointer u, v;\r
+ pointer rbrace_ptr;\r
+ small_number n;\r
+ halfword unbalance;\r
+ halfword m;\r
+ pointer ref_count;\r
+ small_number save_scanner_status;\r
+ pointer save_warning_index;\r
+ ASCII_code match_chr;\r
+\r
+ save_scanner_status = scanner_status;\r
+ save_warning_index = warning_index;\r
+ warning_index = cur_cs;\r
+ ref_count = cur_chr;\r
+ r = link(ref_count);\r
+ n = 0;\r
+\r
+ if (tracing_macros > 0)\r
+ {\r
+ begin_diagnostic();\r
+ print_ln();\r
+ print_cs(warning_index);\r
+ token_show(ref_count);\r
+ end_diagnostic(false);\r
+ }\r
+\r
+ if (info(r) != end_match_token)\r
+ {\r
+ scanner_status = matching;\r
+ unbalance = 0;\r
+ long_state = eq_type(cur_cs);\r
+\r
+ if (long_state >= outer_call)\r
+ long_state = long_state - 2;\r
+\r
+ do\r
+ {\r
+ link(temp_head) = 0;\r
+\r
+ if ((info(r) > match_token + 255) || (info(r) < match_token))\r
+ s = 0;\r
+ else\r
+ {\r
+ match_chr = info(r) - match_token;\r
+ s = link(r);\r
+ r = s;\r
+ p = temp_head;\r
+ m = 0;\r
+ }\r
+\r
+continu:\r
+ get_token();\r
+\r
+ if (cur_tok == info(r))\r
+ {\r
+ r = link(r);\r
+\r
+ if ((info(r) >= match_token) && (info(r) <= end_match_token))\r
+ {\r
+ if (cur_tok < left_brace_limit)\r
+ decr(align_state);\r
+\r
+ goto found;\r
+ }\r
+ else\r
+ goto continu;\r
+ }\r
+\r
+ if (s != r)\r
+ if (s == 0)\r
+ {\r
+ print_err("Use of ");\r
+ sprint_cs(warning_index);\r
+ prints(" doesn't match its definition");\r
+ help4("If you say, e.g., `\\def\\a1{...}', then you must always",\r
+ "put `1' after `\\a', since control sequence names are",\r
+ "made up of letters only. The macro here has not been",\r
+ "followed by the required stuff, so I'm ignoring it.");\r
+ error();\r
+ goto exit;\r
+ }\r
+ else\r
+ {\r
+ t = s;\r
+\r
+ do\r
+ {\r
+ store_new_token(info(t));\r
+ incr(m);\r
+ u = link(t);\r
+ v = s;\r
+\r
+ while (true)\r
+ {\r
+ if (u == r)\r
+ if (cur_tok != info(v))\r
+ goto done;\r
+ else\r
+ {\r
+ r = link(v);\r
+ goto continu;\r
+ }\r
+\r
+ if (info(u) != info(v))\r
+ goto done;\r
+\r
+ u = link(u);\r
+ v = link(v);\r
+ }\r
+done:\r
+ t = link(t);\r
+ }\r
+ while (!(t == r));\r
+\r
+ r = s;\r
+ }\r
+\r
+ if (cur_tok == par_token)\r
+ if (long_state != long_call)\r
+ {\r
+ if (long_state == call)\r
+ {\r
+ runaway();\r
+ print_err("Paragraph ended before ");\r
+ sprint_cs(warning_index);\r
+ prints("was complete");\r
+ help3("I suspect you've forgotten a `}', causing me to apply this",\r
+ "control sequence to too much text. How can we recover?",\r
+ "My plan is to forget the whole thing and hope for the best.");\r
+ back_error();\r
+ }\r
+\r
+ pstack[n] = link(temp_head);\r
+ align_state = align_state - unbalance;\r
+\r
+ for (m = 0; m <= n; m++)\r
+ flush_list(pstack[m]);\r
+\r
+ goto exit;\r
+ }\r
+\r
+ if (cur_tok < right_brace_limit)\r
+ if (cur_tok < left_brace_limit)\r
+ {\r
+ unbalance = 1;\r
+\r
+ while (true)\r
+ {\r
+ fast_store_new_token(cur_tok);\r
+ get_token();\r
+\r
+ if (cur_tok == par_token)\r
+ if (long_state != long_call)\r
+ {\r
+ if (long_state == call)\r
+ {\r
+ runaway();\r
+ print_err("Paragraph ended before ");\r
+ sprint_cs(warning_index);\r
+ prints(" was complete");\r
+ help3("I suspect you've forgotten a `}', causing me to apply this",\r
+ "control sequence to too much text. How can we recover?",\r
+ "My plan is to forget the whole thing and hope for the best.");\r
+ back_error();\r
+ }\r
+\r
+ pstack[n] = link(temp_head);\r
+ align_state = align_state - unbalance;\r
+\r
+ for (m = 0; m <= n; m++)\r
+ flush_list(pstack[m]);\r
+ goto exit;\r
+ }\r
+\r
+ if (cur_tok < right_brace_limit)\r
+ if (cur_tok < left_brace_limit)\r
+ incr(unbalance);\r
+ else\r
+ {\r
+ decr(unbalance);\r
+\r
+ if (unbalance == 0)\r
+ goto done1;\r
+ }\r
+ }\r
+done1:\r
+ rbrace_ptr = p;\r
+ store_new_token(cur_tok);\r
+ }\r
+ else\r
+ {\r
+ back_input();\r
+ print_err("Argument of ");\r
+ sprint_cs(warning_index);\r
+ prints(" has an extra }");\r
+ help6("I've run across a `}' that doesn't seem to match anything.",\r
+ "For example, `\\def\\a#1{...}' and `\\a}' would produce",\r
+ "this error. If you simply proceed now, the `\\par' that",\r
+ "I've just inserted will cause me to report a runaway",\r
+ "argument that might be the root of the problem. But if",\r
+ "your `}' was spurious, just type `2' and it will go away.");\r
+ incr(align_state);\r
+ long_state = call;\r
+ cur_tok = par_token;\r
+ ins_error();\r
+ goto continu;\r
+ }\r
+ else\r
+ {\r
+ if (cur_tok == space_token)\r
+ if (info(r) <= end_match_token)\r
+ if (info(r) >= match_token)\r
+ goto continu;\r
+\r
+ store_new_token(cur_tok);\r
+ }\r
+\r
+ incr(m);\r
+\r
+ if (info(r) > end_match_token)\r
+ goto continu;\r
+\r
+ if (info(r) < match_token)\r
+ goto continu;\r
+\r
+found:\r
+ if (s != 0)\r
+ {\r
+ if ((m == 1) && (info(p) < right_brace_limit) && (p != temp_head))\r
+ {\r
+ link(rbrace_ptr) = 0;\r
+ free_avail(p);\r
+ p = link(temp_head);\r
+ pstack[n] = link(p);\r
+ free_avail(p);\r
+ }\r
+ else\r
+ pstack[n] = link(temp_head);\r
+\r
+ incr(n);\r
+\r
+ if (tracing_macros > 0)\r
+ {\r
+ begin_diagnostic();\r
+ //print_nl(match_chr);\r
+ print_nl(""); print(match_chr);\r
+ print_int(n);\r
+ prints("<-");\r
+ show_token_list(pstack[n - 1], 0, 1000);\r
+ end_diagnostic(false);\r
+ }\r
+ }\r
+ }\r
+ while (!(info(r) == end_match_token));\r
+ }\r
+\r
+ while ((state == token_list) && (loc == 0) &&\r
+ (index != v_template))\r
+ end_token_list();\r
+\r
+ begin_token_list(ref_count, macro);\r
+ name = warning_index;\r
+ loc = link(r);\r
+\r
+ if (n > 0)\r
+ {\r
+ if (param_ptr + n > max_param_stack)\r
+ {\r
+ max_param_stack = param_ptr + n;\r
+\r
+#ifdef ALLOCATEPARAMSTACK\r
+ if (max_param_stack > current_param_size)\r
+ param_stack = realloc_param_stack(increment_param_size);\r
+\r
+ if (max_param_stack > current_param_size)\r
+ {\r
+ overflow("parameter stack size", current_param_size);\r
+ return;\r
+ }\r
+#else\r
+ if (max_param_stack > param_size)\r
+ {\r
+ overflow("parameter stack size", param_size);\r
+ return;\r
+ }\r
+#endif\r
+ }\r
+\r
+ for (m = 0; m <= n - 1; m++)\r
+ param_stack[param_ptr + m] = pstack[m];\r
+\r
+ param_ptr = param_ptr + n;\r
+ }\r
+\r
+exit:\r
+ scanner_status = save_scanner_status;\r
+ warning_index = save_warning_index;\r
+}\r
+/* sec 0379 */\r
+void insert_relax (void)\r
+{\r
+ cur_tok = cs_token_flag + cur_cs;\r
+ back_input();\r
+ cur_tok = cs_token_flag + frozen_relax;\r
+ back_input();\r
+ index = inserted;\r
+}\r
+/* sec 0366 */\r
+void expand (void)\r
+{\r
+ halfword t;\r
+ pointer p, q, r;\r
+ integer j;\r
+ integer cv_backup;\r
+ small_number cvl_backup, radix_backup, co_backup;\r
+ pointer backup_backup;\r
+ small_number save_scanner_status;\r
+\r
+ cv_backup = cur_val;\r
+ cvl_backup = cur_val_level;\r
+ radix_backup = radix;\r
+ co_backup = cur_order;\r
+ backup_backup = link(backup_head);\r
+\r
+ if (cur_cmd < call)\r
+ {\r
+ if (tracing_commands > 1)\r
+ show_cur_cmd_chr();\r
+\r
+ switch (cur_cmd)\r
+ {\r
+ case top_bot_mark:\r
+ if (cur_mark[cur_chr] != 0)\r
+ begin_token_list(cur_mark[cur_chr], mark_text);\r
+ break;\r
+\r
+ case expand_after:\r
+ get_token();\r
+ t = cur_tok;\r
+ get_token();\r
+\r
+ if (cur_cmd > max_command)\r
+ expand();\r
+ else\r
+ back_input();\r
+\r
+ cur_tok = t;\r
+ back_input();\r
+ break;\r
+\r
+ case no_expand:\r
+ save_scanner_status = scanner_status;\r
+ scanner_status = normal;\r
+ get_token();\r
+ scanner_status = save_scanner_status;\r
+ t = cur_tok;\r
+ back_input();\r
+\r
+ if (t >= cs_token_flag)\r
+ {\r
+ p = get_avail();\r
+ info(p) = cs_token_flag + frozen_dont_expand;\r
+ link(p) = loc;\r
+ start = p;\r
+ loc = p;\r
+ }\r
+ break;\r
+\r
+ case cs_name:\r
+ r = get_avail();\r
+ p = r;\r
+\r
+ do\r
+ {\r
+ get_x_token();\r
+ \r
+ if (cur_cs == 0)\r
+ store_new_token(cur_tok);\r
+ }\r
+ while (!(cur_cs != 0));\r
+\r
+ if (cur_cmd != end_cs_name)\r
+ {\r
+ print_err("Missing ");\r
+ print_esc("endcsname");\r
+ prints(" inserted");\r
+ help2("The control sequence marked <to be read again> should",\r
+ "not appear between \\csname and \\endcsname.");\r
+ back_error();\r
+ }\r
+\r
+ j = first;\r
+ p = link(r);\r
+\r
+ while (p != 0)\r
+ {\r
+ if (j >= max_buf_stack)\r
+ {\r
+ max_buf_stack = j + 1;\r
+\r
+#ifdef ALLOCATEBUFFER\r
+ if (max_buf_stack == current_buf_size)\r
+ buffer = realloc_buffer (increment_buf_size);\r
+\r
+ if (max_buf_stack == current_buf_size)\r
+ {\r
+ overflow("buffer size", current_buf_size);\r
+ return;\r
+ }\r
+#else\r
+ if (max_buf_stack == buf_size)\r
+ {\r
+ overflow("buffer size", buf_size);\r
+ return;\r
+ }\r
+#endif\r
+ }\r
+\r
+ buffer[j] = info(p) % 256;\r
+ incr(j);\r
+ p = link(p);\r
+ }\r
+\r
+ if (j > first + 1)\r
+ {\r
+ no_new_control_sequence = false;\r
+ cur_cs = id_lookup(first, j - first);\r
+ no_new_control_sequence = true;\r
+ }\r
+ else if (j == first)\r
+ cur_cs = null_cs;\r
+ else\r
+ cur_cs = single_base + buffer[first];\r
+\r
+ flush_list(r);\r
+\r
+ if (eq_type(cur_cs) == undefined_cs)\r
+ {\r
+ eq_define(cur_cs, relax, 256);\r
+ }\r
+\r
+ cur_tok = cur_cs + cs_token_flag;\r
+ back_input();\r
+ break;\r
+\r
+ case convert:\r
+ conv_toks();\r
+ break;\r
+\r
+ case the:\r
+ ins_the_toks();\r
+ break;\r
+\r
+ case if_test:\r
+ conditional();\r
+ break;\r
+\r
+ case fi_or_else:\r
+ if (cur_chr > if_limit)\r
+ if (if_limit == 1)\r
+ insert_relax();\r
+ else\r
+ {\r
+ print_err("Extra ");\r
+ print_cmd_chr(fi_or_else, cur_chr);\r
+ help1("I'm ignoring this; it doesn't match any \\if.");\r
+ error();\r
+ }\r
+ else\r
+ {\r
+ while (cur_chr != fi_code)\r
+ pass_text();\r
+\r
+ {\r
+ p = cond_ptr;\r
+ if_line = if_line_field(p);\r
+ cur_if = subtype(p);\r
+ if_limit = type(p);\r
+ cond_ptr = link(p);\r
+ free_node(p, if_node_size);\r
+ }\r
+ }\r
+ break;\r
+\r
+ case input:\r
+ if (cur_chr > 0)\r
+ force_eof = true;\r
+ else if (name_in_progress)\r
+ insert_relax();\r
+ else\r
+ start_input();\r
+ break;\r
+\r
+ default:\r
+ print_err("Undefined control sequence");\r
+ help5("The control sequence at the end of the top line",\r
+ "of your error message was never \\def'ed. If you have",\r
+ "misspelled it (e.g., `\\hobx'), type `I' and the correct",\r
+ "spelling (e.g., `I\\hbox'). Otherwise just continue,",\r
+ "and I'll forget about whatever was undefined.");\r
+ error();\r
+ break;\r
+ }\r
+ }\r
+ else if (cur_cmd < end_template)\r
+ {\r
+ macro_call();\r
+ }\r
+ else\r
+ {\r
+ cur_tok = cs_token_flag + frozen_endv;\r
+ back_input();\r
+ }\r
+\r
+ cur_val = cv_backup;\r
+ cur_val_level = cvl_backup;\r
+ radix = radix_backup;\r
+ cur_order = co_backup;\r
+ link(backup_head) = backup_backup;\r
+}\r
+/* sec 0380 */\r
+void get_x_token (void)\r
+{\r
+restart:\r
+ get_next();\r
+\r
+ if (cur_cmd <= max_command)\r
+ goto done;\r
+\r
+ if (cur_cmd >= call)\r
+ if (cur_cmd < end_template)\r
+ macro_call();\r
+ else\r
+ {\r
+ cur_cs = frozen_endv;\r
+ cur_cmd = endv;\r
+ goto done;\r
+ }\r
+ else\r
+ expand();\r
+\r
+ goto restart;\r
+\r
+done:\r
+ if (cur_cs == 0)\r
+ cur_tok = (cur_cmd * 256) + cur_chr;\r
+ else\r
+ cur_tok = cs_token_flag + cur_cs;\r
+}\r
+/* sec 0381 */\r
+void x_token (void)\r
+{\r
+ while (cur_cmd > max_command)\r
+ {\r
+ expand();\r
+ get_next();\r
+ }\r
+\r
+ if (cur_cs == 0)\r
+ cur_tok = (cur_cmd * 256) + cur_chr;\r
+ else\r
+ cur_tok = cs_token_flag + cur_cs;\r
+}\r
+/* sec 0403 */\r
+void scan_left_brace (void)\r
+{\r
+ do\r
+ {\r
+ get_x_token();\r
+ }\r
+ while (!((cur_cmd != spacer) && (cur_cmd != relax)));\r
+\r
+ if (cur_cmd != left_brace)\r
+ {\r
+ print_err("Missing { inserted");\r
+ help4("A left brace was mandatory here, so I've put one in.",\r
+ "You might want to delete and/or insert some corrections",\r
+ "so that I will find a matching right brace soon.",\r
+ "(If you're confused by all this, try typing `I}' now.)");\r
+ back_error();\r
+ cur_tok = left_brace_token + '{';\r
+ cur_cmd = left_brace;\r
+ cur_chr = '{';\r
+ incr(align_state);\r
+ }\r
+}\r
+/* sec 0405 */\r
+void scan_optional_equals (void)\r
+{\r
+ do\r
+ {\r
+ get_x_token();\r
+ }\r
+ while (!(cur_cmd != spacer));\r
+\r
+ if (cur_tok != other_token + '=')\r
+ back_input();\r
+}\r
+/* sec 0407 */\r
+boolean scan_keyword (const char * s)\r
+{\r
+ pointer p;\r
+ pointer q;\r
+ const char * k;\r
+\r
+ p = backup_head;\r
+ link(p) = 0;\r
+ k = s;\r
+\r
+ while (*k)\r
+ {\r
+ get_x_token(); \r
+\r
+ if ((cur_cs == 0) && ((cur_chr == (*k)) || (cur_chr == (*k) - 'a' + 'A')))\r
+ {\r
+ store_new_token(cur_tok);\r
+ incr(k);\r
+ }\r
+ else if ((cur_cmd != spacer) || (p != backup_head))\r
+ {\r
+ back_input();\r
+\r
+ if (p != backup_head)\r
+ back_list(link(backup_head));\r
+\r
+ return false;\r
+ }\r
+ }\r
+\r
+ flush_list(link(backup_head));\r
+\r
+ return true;\r
+}\r
+/* sec 0408 */\r
+void mu_error (void)\r
+{\r
+ print_err("Incompatible glue units");\r
+ help1("I'm going to assume that 1mu=1pt when they're mixed.");\r
+ error();\r
+}\r
+/* sec 0433 */\r
+void scan_eight_bit_int (void)\r
+{\r
+ scan_int();\r
+\r
+ if ((cur_val < 0) || (cur_val > 255))\r
+ {\r
+ print_err("Bad register code");\r
+ help2("A register number must be between 0 and 255.",\r
+ "I changed this one to zero.");\r
+ int_error(cur_val);\r
+ cur_val = 0;\r
+ }\r
+}\r
+/* sec 0434 */\r
+void scan_char_num (void)\r
+{\r
+ scan_int();\r
+\r
+ if ((cur_val < 0) || (cur_val > 255))\r
+ {\r
+ print_err("Bad character code");\r
+ help2("A character number must be between 0 and 255.",\r
+ "I changed this one to zero.");\r
+ int_error(cur_val);\r
+ cur_val = 0;\r
+ }\r
+}\r
+/* sec 0435 */\r
+void scan_four_bit_int (void)\r
+{\r
+ scan_int();\r
+\r
+ if ((cur_val < 0) || (cur_val > 15))\r
+ {\r
+ print_err("Bad number");\r
+ help2("Since I expected to read a number between 0 and 15,",\r
+ "I changed this one to zero.");\r
+ int_error(cur_val);\r
+ cur_val = 0;\r
+ }\r
+}\r
+/* sec 0436 */\r
+void scan_fifteen_bit_int (void) \r
+{\r
+ scan_int();\r
+\r
+ if ((cur_val < 0) || (cur_val > 32767))\r
+ {\r
+ print_err("Bad mathchar");\r
+ help2("A mathchar number must be between 0 and 32767.",\r
+ "I changed this one to zero.");\r
+ int_error(cur_val);\r
+ cur_val = 0;\r
+ }\r
+}\r
+/* sec 0437 */\r
+void scan_twenty_seven_bit_int (void)\r
+{\r
+ scan_int();\r
+\r
+ if ((cur_val < 0) || (cur_val > 134217727L))\r
+ {\r
+ print_err("Bad delimiter code");\r
+ help2("A numeric delimiter code must be between 0 and 2^{27}-1.",\r
+ "I changed this one to zero.");\r
+ int_error(cur_val);\r
+ cur_val = 0;\r
+ }\r
+}\r
+/* sec 0577 */\r
+void scan_font_ident (void) \r
+{\r
+ internal_font_number f;\r
+ halfword m;\r
+\r
+ do\r
+ {\r
+ get_x_token();\r
+ }\r
+ while (!(cur_cmd != spacer));\r
+\r
+ if (cur_cmd == def_font)\r
+ f = cur_font;\r
+ else if (cur_cmd == set_font)\r
+ f = cur_chr; \r
+ else if (cur_cmd == def_family)\r
+ {\r
+ m = cur_chr;\r
+ scan_four_bit_int();\r
+ f = equiv(m + cur_val);\r
+ }\r
+ else\r
+ {\r
+ print_err("Missing font identifier");\r
+ help2("I was looking for a control sequence whose",\r
+ "current meaning has been defined by \\font.");\r
+ back_error();\r
+ f = null_font;\r
+ }\r
+\r
+ cur_val = f;\r
+}\r
+/* sec 0578 */\r
+void find_font_dimen (boolean writing)\r
+{\r
+ internal_font_number f;\r
+ integer n;\r
+\r
+ scan_int();\r
+ n = cur_val;\r
+ scan_font_ident();\r
+ f = cur_val;\r
+\r
+ if (n < 0)\r
+ cur_val = fmem_ptr;\r
+ else\r
+ {\r
+ if (writing && (n <= space_shrink_code) && (n >= space_code) && (font_glue[f] != 0)) \r
+ {\r
+ delete_glue_ref(font_glue[f]);\r
+ font_glue[f] = 0;\r
+ }\r
+\r
+ if (n > font_params[f])\r
+ if (f < font_ptr)\r
+ cur_val = fmem_ptr;\r
+ else\r
+ {\r
+ do\r
+ {\r
+ #ifdef ALLOCATEFONT\r
+ if (fmem_ptr == current_font_mem_size)\r
+ font_info = realloc_font_info(increment_font_mem_size);\r
+\r
+ if (fmem_ptr == current_font_mem_size)\r
+ {\r
+ overflow("font memory", current_font_mem_size);\r
+ return;\r
+ }\r
+#else\r
+ if (fmem_ptr == font_mem_size)\r
+ {\r
+ overflow("font memory", font_mem_size);\r
+ return;\r
+ }\r
+#endif\r
+ font_info[fmem_ptr].cint = 0;\r
+ incr(fmem_ptr);\r
+ incr(font_params[f]);\r
+ }\r
+ while (!(n == font_params[f]));\r
+\r
+ cur_val = fmem_ptr - 1;\r
+ }\r
+ else if (n > 0)\r
+ cur_val = n + param_base[f];\r
+ }\r
+\r
+ if (cur_val == fmem_ptr)\r
+ {\r
+ print_err("Font ");\r
+ print_esc(""); print(font_id_text(f));\r
+ prints(" has only ");\r
+ print_int(font_params[f]);\r
+ prints(" fontdimen parameters");\r
+ help2("To increase the number of font parameters, you must",\r
+ "use \\fontdimen immediately after the \\font is loaded.");\r
+ error();\r
+ }\r
+}\r
+/* sec 0413 */\r
+void scan_something_internal (small_number level, boolean negative)\r
+{\r
+ halfword m;\r
+ integer p;\r
+\r
+ m = cur_chr;\r
+\r
+ switch (cur_cmd)\r
+ {\r
+ case def_code:\r
+ {\r
+ scan_char_num();\r
+\r
+ if (m == math_code_base)\r
+ scanned_result(math_code(cur_val), int_val);\r
+ else if (m < math_code_base)\r
+ scanned_result(equiv(m + cur_val), int_val);\r
+ else\r
+ scanned_result(eqtb[m + cur_val].cint, int_val);\r
+ }\r
+ break;\r
+\r
+ case toks_register:\r
+ case assign_toks:\r
+ case def_family:\r
+ case set_font:\r
+ case def_font:\r
+ if (level != tok_val)\r
+ {\r
+ print_err("Missing number, treated as zero");\r
+ help3("A number should have been here; I inserted `0'.",\r
+ "(If you can't figure out why I needed to see a number,",\r
+ "look up `weird error' in the index to The TeXbook.)");\r
+ back_error();\r
+ scanned_result(0, dimen_val);\r
+ }\r
+ else if (cur_cmd <= assign_toks)\r
+ {\r
+ if (cur_cmd < assign_toks)\r
+ {\r
+ scan_eight_bit_int();\r
+ m = toks_base + cur_val;\r
+ }\r
+\r
+ scanned_result(equiv(m), tok_val);\r
+ }\r
+ else\r
+ {\r
+ back_input();\r
+ scan_font_ident();\r
+ scanned_result(font_id_base + cur_val, ident_val);\r
+ }\r
+ break;\r
+\r
+ case assign_int:\r
+ scanned_result(eqtb[m].cint, int_val);\r
+ break;\r
+\r
+ case assign_dimen:\r
+ scanned_result(eqtb[m].cint, dimen_val);\r
+ break; \r
+\r
+ case assign_glue:\r
+ scanned_result(equiv(m), glue_val);\r
+ break;\r
+\r
+ case assign_mu_glue:\r
+ scanned_result(equiv(m), mu_val);\r
+ break;\r
+\r
+ case set_aux:\r
+ if (abs(mode) != m)\r
+ {\r
+ print_err("Improper ");\r
+ print_cmd_chr(set_aux, m);\r
+ help4("You can refer to \\spacefactor only in horizontal mode;",\r
+ "you can refer to \\prevdepth only in vertical mode; and",\r
+ "neither of these is meaningful inside \\write. So",\r
+ "I'm forgetting what you said and using zero instead.");\r
+ error();\r
+\r
+ if (level != tok_val)\r
+ scanned_result(0, dimen_val);\r
+ else\r
+ scanned_result(0, int_val);\r
+ }\r
+ else if (m == vmode)\r
+ scanned_result(prev_depth, dimen_val);\r
+ else\r
+ scanned_result(space_factor, int_val);\r
+ break;\r
+\r
+ case set_prev_graf:\r
+ if (mode == 0)\r
+ scanned_result(0, int_val);\r
+ else\r
+ {\r
+ nest[nest_ptr] = cur_list;\r
+ p = nest_ptr;\r
+\r
+ while (abs(nest[p].mode_field) != vmode)\r
+ decr(p);\r
+\r
+ scanned_result(nest[p].pg_field, int_val);\r
+ }\r
+ break;\r
+\r
+ case set_page_int:\r
+ {\r
+ if (m == 0)\r
+ cur_val = dead_cycles; \r
+ else\r
+ cur_val = insert_penalties;\r
+\r
+ cur_val_level = 0;\r
+ }\r
+ break;\r
+\r
+ case set_page_dimen:\r
+ {\r
+ if ((page_contents == 0) && (! output_active))\r
+ if (m == 0)\r
+ cur_val = max_dimen;\r
+ else\r
+ cur_val = 0;\r
+ else\r
+ cur_val = page_so_far[m];\r
+\r
+ cur_val_level = dimen_val;\r
+ }\r
+ break;\r
+\r
+ case set_shape:\r
+ {\r
+ if (par_shape_ptr == 0)\r
+ cur_val = 0; \r
+ else\r
+ cur_val = info(par_shape_ptr);\r
+\r
+ cur_val_level = int_val;\r
+ }\r
+ break;\r
+\r
+ case set_box_dimen:\r
+ {\r
+ scan_eight_bit_int();\r
+\r
+ if (box(cur_val) == 0)\r
+ cur_val = 0;\r
+ else\r
+ cur_val = mem[box(cur_val) + m].cint;\r
+\r
+ cur_val_level = dimen_val;\r
+ }\r
+ break;\r
+\r
+ case char_given:\r
+ case math_given:\r
+ scanned_result(cur_chr, int_val);\r
+ break;\r
+\r
+ case assign_font_dimen:\r
+ {\r
+ find_font_dimen(false);\r
+ font_info[fmem_ptr].cint = 0;\r
+ scanned_result(font_info[cur_val].cint, dimen_val);\r
+ }\r
+ break;\r
+\r
+ case assign_font_int:\r
+ {\r
+ scan_font_ident();\r
+\r
+ if (m == 0)\r
+ scanned_result(hyphen_char[cur_val], int_val);\r
+ else\r
+ scanned_result(skew_char[cur_val], int_val);\r
+ }\r
+ break;\r
+\r
+ case tex_register:\r
+ {\r
+ scan_eight_bit_int();\r
+\r
+ switch (m)\r
+ {\r
+ case int_val:\r
+ cur_val = count(cur_val);\r
+ break;\r
+\r
+ case dimen_val:\r
+ cur_val = dimen(cur_val);\r
+ break;\r
+\r
+ case glue_val:\r
+ cur_val = skip(cur_val);\r
+ break;\r
+\r
+ case mu_val:\r
+ cur_val = mu_skip(cur_val);\r
+ break;\r
+ }\r
+ \r
+ cur_val_level = m;\r
+ }\r
+ break;\r
+\r
+ case last_item:\r
+ if (cur_chr > glue_val)\r
+ {\r
+ if (cur_chr == input_line_no_code)\r
+ cur_val = line;\r
+ else\r
+ cur_val = last_badness;\r
+\r
+ cur_val_level = int_val;\r
+ }\r
+ else\r
+ {\r
+ if (cur_chr == glue_val)\r
+ cur_val = zero_glue;\r
+ else\r
+ cur_val = 0;\r
+\r
+ cur_val_level = cur_chr;\r
+\r
+ if (!is_char_node(tail) && (mode != 0))\r
+ switch (cur_chr)\r
+ {\r
+ case int_val:\r
+ if (type(tail) == penalty_node)\r
+ cur_val = penalty(tail);\r
+ break;\r
+\r
+ case dimen_val:\r
+ if (type(tail) == kern_node)\r
+ cur_val = width(tail);\r
+ break;\r
+\r
+ case glue_val:\r
+ if (type(tail) == glue_node)\r
+ {\r
+ cur_val = glue_ptr(tail);\r
+\r
+ if (subtype(tail) == mu_glue)\r
+ cur_val_level = mu_val;\r
+ }\r
+ break;\r
+ }\r
+ else if ((mode == vmode) && (tail == head))\r
+ switch (cur_chr)\r
+ {\r
+ case int_val:\r
+ cur_val = last_penalty;\r
+ break;\r
+\r
+ case dimen_val:\r
+ cur_val = last_kern;\r
+ break;\r
+\r
+ case glue_val:\r
+ if (last_glue != empty_flag)\r
+ cur_val = last_glue;\r
+ break;\r
+ }\r
+ }\r
+ break;\r
+\r
+ default:\r
+ {\r
+ print_err("You can't use `");\r
+ print_cmd_chr(cur_cmd, cur_chr);\r
+ prints("' after ");\r
+ print_esc("the");\r
+ help1("I'm forgetting what you said and using zero instead.");\r
+ error();\r
+\r
+ if (level != tok_val)\r
+ scanned_result(0, dimen_val);\r
+ else\r
+ scanned_result(0, int_val);\r
+ }\r
+ break;\r
+ }\r
+\r
+ while (cur_val_level > level)\r
+ {\r
+ if (cur_val_level == glue_val)\r
+ cur_val = width(cur_val);\r
+ else if (cur_val_level == mu_val)\r
+ mu_error();\r
+\r
+ decr(cur_val_level);\r
+ }\r
+\r
+ if (negative)\r
+ if (cur_val_level >= 2)\r
+ {\r
+ cur_val = new_spec(cur_val);\r
+\r
+ {\r
+ width(cur_val) = -width(cur_val);\r
+ stretch(cur_val) = -stretch(cur_val);\r
+ shrink(cur_val) = -shrink(cur_val);\r
+ }\r
+ }\r
+ else\r
+ cur_val = -cur_val;\r
+ else if ((cur_val_level >= glue_val) && (cur_val_level <= mu_val))\r
+ add_glue_ref(cur_val);\r
+}\r
+/* sec 0341 */\r
+void get_next (void)\r
+{\r
+ integer k;\r
+ halfword t;\r
+ /* char cat; */\r
+ int cat;\r
+ ASCII_code c, cc;\r
+ char d;\r
+\r
+restart:\r
+ cur_cs = 0;\r
+\r
+ if (state != token_list)\r
+ {\r
+lab_switch:\r
+ if (loc <= limit)\r
+ {\r
+ cur_chr = buffer[loc];\r
+ incr(loc);\r
+\r
+reswitch:\r
+ cur_cmd = cat_code(cur_chr);\r
+\r
+ switch (state + cur_cmd)\r
+ {\r
+ case any_state_plus(ignore):\r
+ case skip_blanks + spacer:\r
+ case new_line + spacer:\r
+ goto lab_switch;\r
+ break;\r
+\r
+ case any_state_plus(escape):\r
+ {\r
+ if (loc > limit)\r
+ cur_cs = null_cs;\r
+ else\r
+ {\r
+start_cs:\r
+ k = loc;\r
+ cur_chr = buffer[k];\r
+ cat = cat_code(cur_chr);\r
+ incr(k);\r
+\r
+ if (cat == letter)\r
+ state = skip_blanks;\r
+ else if (cat == spacer)\r
+ state = skip_blanks;\r
+ else\r
+ state = mid_line;\r
+\r
+ if ((cat == letter) && (k <= limit))\r
+ {\r
+ do\r
+ {\r
+ cur_chr = buffer[k];\r
+ cat = cat_code(cur_chr);\r
+ incr(k);\r
+ }\r
+ while (!((cat != letter) || (k > limit)));\r
+\r
+ {\r
+ if (buffer[k]== cur_chr)\r
+ if (cat == sup_mark)\r
+ if (k < limit)\r
+ {\r
+ c = buffer[k + 1];\r
+\r
+ if (c < 128)\r
+ {\r
+ d = 2;\r
+ if (is_hex(c))\r
+ if (k + 2 <= limit)\r
+ {\r
+ cc = buffer[k + 2];\r
+\r
+ if (is_hex(cc))\r
+ incr(d);\r
+ }\r
+\r
+ if (d > 2)\r
+ {\r
+ hex_to_cur_chr();\r
+ buffer[k - 1] = cur_chr;\r
+ }\r
+ else if (c < 64)\r
+ buffer[k - 1] = c + 64;\r
+ else\r
+ buffer[k - 1] = c - 64;\r
+\r
+ limit = limit - d;\r
+ first = first - d;\r
+\r
+ while (k <= limit)\r
+ {\r
+ buffer[k] = buffer[k + d];\r
+ incr(k);\r
+ }\r
+\r
+ goto start_cs;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (cat != letter)\r
+ decr(k);\r
+\r
+ if (k > loc + 1)\r
+ {\r
+ cur_cs = id_lookup(loc, k - loc);\r
+ loc = k;\r
+ goto found;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (buffer[k] == cur_chr)\r
+ if (cat == sup_mark)\r
+ if (k < limit)\r
+ {\r
+ c = buffer[k + 1];\r
+\r
+ if (c < 128)\r
+ {\r
+ d = 2;\r
+\r
+ if (is_hex(c))\r
+ if (k + 2 <= limit)\r
+ {\r
+ cc = buffer[k + 2];\r
+\r
+ if (is_hex(cc))\r
+ incr(d);\r
+ }\r
+\r
+ if (d > 2)\r
+ {\r
+ hex_to_cur_chr();\r
+ buffer[k - 1] = cur_chr;\r
+ }\r
+ else if (c < 64)\r
+ buffer[k - 1] = c + 64;\r
+ else\r
+ buffer[k - 1] = c - 64;\r
+\r
+ limit = limit - d;\r
+ first = first - d;\r
+\r
+ while (k <= limit)\r
+ {\r
+ buffer[k] = buffer[k + d];\r
+ incr(k);\r
+ }\r
+\r
+ goto start_cs;\r
+ }\r
+ }\r
+ }\r
+\r
+ cur_cs = single_base + buffer[loc];\r
+ incr(loc);\r
+ }\r
+found:\r
+ cur_cmd = eq_type(cur_cs);\r
+ cur_chr = equiv(cur_cs);\r
+ \r
+ if (cur_cmd >= outer_call)\r
+ check_outer_validity();\r
+ }\r
+ break;\r
+\r
+ case any_state_plus(active_char):\r
+ {\r
+ cur_cs = cur_chr + active_base;\r
+ cur_cmd = eq_type(cur_cs);\r
+ cur_chr = equiv(cur_cs);\r
+ state = mid_line;\r
+ \r
+ if (cur_cmd >= outer_call)\r
+ check_outer_validity();\r
+ }\r
+ break;\r
+\r
+ case any_state_plus(sup_mark):\r
+ {\r
+ if (cur_chr == buffer[loc])\r
+ if (loc < limit)\r
+ {\r
+ c = buffer[loc + 1];\r
+\r
+ if (c < 128)\r
+ {\r
+ loc = loc + 2;\r
+\r
+ if (is_hex(c))\r
+ if (loc <= limit)\r
+ {\r
+ cc = buffer[loc];\r
+\r
+ if (is_hex(cc))\r
+ {\r
+ incr(loc);\r
+ hex_to_cur_chr();\r
+ goto reswitch;\r
+ }\r
+ }\r
+\r
+ if (c < 64)\r
+ cur_chr = c + 64;\r
+ else\r
+ cur_chr = c - 64;\r
+\r
+ goto reswitch;\r
+ }\r
+ }\r
+\r
+ state = mid_line;\r
+ }\r
+ break;\r
+\r
+ case any_state_plus(invalid_char):\r
+ {\r
+ print_err("Text line contains an invalid character");\r
+ help2("A funny symbol that I can't read has just been input.",\r
+ "Continue, and I'll forget that it ever happened.");\r
+ deletions_allowed = false;\r
+ error();\r
+ deletions_allowed = true;\r
+ goto restart;\r
+ }\r
+ break;\r
+\r
+ case mid_line + spacer:\r
+ {\r
+ state = skip_blanks;\r
+ cur_chr = ' ';\r
+ }\r
+ break;\r
+\r
+ case mid_line + car_ret:\r
+ {\r
+ loc = limit + 1;\r
+ cur_cmd = spacer;\r
+ cur_chr = ' ';\r
+ }\r
+ break;\r
+\r
+ case skip_blanks + car_ret:\r
+ case any_state_plus(comment):\r
+ {\r
+ loc = limit + 1;\r
+ goto lab_switch;\r
+ }\r
+ break;\r
+\r
+ case new_line + car_ret:\r
+ {\r
+ loc = limit + 1;\r
+ cur_cs = par_loc;\r
+ cur_cmd = eq_type(cur_cs);\r
+ cur_chr = equiv(cur_cs);\r
+ \r
+ if (cur_cmd >= outer_call)\r
+ check_outer_validity();\r
+ }\r
+ break;\r
+\r
+ case mid_line + left_brace:\r
+ incr(align_state);\r
+ break;\r
+\r
+ case skip_blanks + left_brace:\r
+ case new_line + left_brace:\r
+ {\r
+ state = mid_line;\r
+ incr(align_state);\r
+ }\r
+ break;\r
+\r
+ case mid_line + right_brace:\r
+ decr(align_state);\r
+ break;\r
+\r
+ case skip_blanks + right_brace:\r
+ case new_line + right_brace:\r
+ {\r
+ state = mid_line;\r
+ decr(align_state);\r
+ }\r
+ break;\r
+\r
+ case add_delims_to(skip_blanks):\r
+ case add_delims_to(new_line):\r
+ state = 1;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ state = new_line;\r
+\r
+ if (name > 17)\r
+ {\r
+ incr(line);\r
+ first = start;\r
+\r
+ if (!force_eof)\r
+ {\r
+ if (input_ln(cur_file, true))\r
+ firm_up_the_line();\r
+ else\r
+ force_eof = true;\r
+ }\r
+\r
+ if (force_eof)\r
+ {\r
+ print_char(')');\r
+ decr(open_parens);\r
+ update_terminal();\r
+ force_eof = false;\r
+ end_file_reading();\r
+ check_outer_validity();\r
+ goto restart;\r
+ }\r
+\r
+ if (end_line_char_inactive())\r
+ decr(limit);\r
+ else\r
+ buffer[limit] = end_line_char;\r
+\r
+ first = limit + 1;\r
+ loc = start;\r
+ }\r
+ else\r
+ {\r
+ if (!(name == 0))\r
+ {\r
+ cur_cmd = 0;\r
+ cur_chr = 0;\r
+ return;\r
+ }\r
+\r
+ if (input_ptr > 0)\r
+ {\r
+ end_file_reading();\r
+ goto restart;\r
+ }\r
+\r
+ if (selector < log_only)\r
+ open_log_file();\r
+\r
+ if (interaction > nonstop_mode)\r
+ {\r
+ if (end_line_char_inactive())\r
+ incr(limit);\r
+\r
+ if (limit == start)\r
+ print_nl("(Please type a command or say `\\end')");\r
+\r
+ print_ln();\r
+ first = start;\r
+ prompt_input("*");\r
+ limit = last;\r
+\r
+ if (end_line_char_inactive())\r
+ decr(limit);\r
+ else\r
+ buffer[limit]= end_line_char;\r
+\r
+ first = limit + 1;\r
+ loc = start;\r
+ }\r
+ else\r
+ {\r
+ fatal_error("*** (job aborted, no legal \\end found)");\r
+ return;\r
+ }\r
+ }\r
+\r
+ check_interrupt();\r
+ goto lab_switch;\r
+ }\r
+ }\r
+ else if (loc != 0)\r
+ {\r
+ t = info(loc);\r
+ loc = link(loc);\r
+\r
+ if (t >= cs_token_flag)\r
+ {\r
+ cur_cs = t - cs_token_flag;\r
+ cur_cmd = eq_type(cur_cs);\r
+ cur_chr = equiv(cur_cs);\r
+\r
+ if (cur_cmd >= outer_call)\r
+ if (cur_cmd == dont_expand)\r
+ {\r
+ cur_cs = info(loc) - cs_token_flag;\r
+ loc = 0;\r
+ cur_cmd = eq_type(cur_cs);\r
+ cur_chr = equiv(cur_cs);\r
+\r
+ if (cur_cmd > max_command)\r
+ {\r
+ cur_cmd = relax;\r
+ cur_chr = no_expand_flag;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ check_outer_validity();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ cur_cmd = t / 256;\r
+ cur_chr = t % 256;\r
+\r
+ switch (cur_cmd)\r
+ {\r
+ case left_brace:\r
+ incr(align_state);\r
+ break;\r
+\r
+ case right_brace:\r
+ decr(align_state);\r
+ break;\r
+\r
+ case out_param:\r
+ {\r
+ begin_token_list(param_stack[limit + cur_chr - 1], parameter);\r
+ goto restart;\r
+ }\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ end_token_list();\r
+ goto restart;\r
+ }\r
+\r
+ if (cur_cmd <= car_ret)\r
+ if (cur_cmd >= tab_mark)\r
+ if (align_state == 0)\r
+ {\r
+ if ((scanner_status == aligning) && (cur_align == 0))\r
+ {\r
+ fatal_error("(interwoven alignment preambles are not allowed)");\r
+ return;\r
+ }\r
+\r
+ cur_cmd = extra_info(cur_align);\r
+ extra_info(cur_align) = cur_chr;\r
+\r
+ if (cur_cmd == omit)\r
+ begin_token_list(omit_template, v_template);\r
+ else\r
+ begin_token_list(v_part(cur_align), v_template);\r
+\r
+ align_state = 1000000L;\r
+ goto restart;\r
+ }\r
}
\ No newline at end of file