1 /* Copyright 2014 Clerk Ma
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 /* following bit used to be end of tex1.c */
25 void restore_trace_(halfword p, char * s)
33 end_diagnostic(false);
43 if (cur_level > level_one)
49 if (save_type(save_ptr) == level_boundary)
52 p = save_index(save_ptr);
54 if (save_type(save_ptr) == insert_token)
63 if (save_type(save_ptr) == restore_old_value)
65 l = save_level(save_ptr);
69 save_stack[save_ptr] = eqtb[undefined_control_sequence];
72 if (eq_level(p) == level_one)
74 eq_destroy(save_stack[save_ptr]);
76 if (tracing_restores > 0)
77 restore_trace(p, "retaining");
83 eqtb[p] = save_stack[save_ptr];
85 if (tracing_restores > 0)
86 restore_trace(p, "restoring");
89 else if (xeq_level[p] != level_one)
91 eqtb[p] = save_stack[save_ptr];
94 if (tracing_restores > 0)
95 restore_trace(p, "restoring");
101 if (tracing_restores > 0)
102 restore_trace(p, "retaining");
108 cur_group = save_level(save_ptr);
109 cur_boundary = save_index(save_ptr);
113 confusion("curlevel");
114 return; // abort_flag set
117 /* This is where the old tex2.c used to start */
119 void prepare_mag (void)
121 if ((mag_set > 0) && (mag != mag_set))
123 print_err("Incompatible magnification (");
126 print_nl(" the previous value will be retained");
127 help2("I can handle only one magnification ratio per job. So I've",
128 "reverted to the magnification you used earlier on this run.");
130 geq_word_define(int_base + mag_code, mag_set);
133 if ((mag <= 0) || (mag > 32768L))
135 print_err("Illegal magnification has been changed to 1000");
136 help1("The magnification ratio must be between 1 and 32768.");
138 geq_word_define(int_base + mag_code, 1000);
144 void token_show_ (halfword p)
147 show_token_list(link(p), 0, 10000000L);
150 void print_meaning (void)
152 print_cmd_chr(cur_cmd, cur_chr);
160 else if (cur_cmd == top_bot_mark)
164 token_show(cur_mark[cur_chr]);
168 void show_cur_cmd_chr (void)
173 if (mode != shown_mode)
180 print_cmd_chr(cur_cmd, cur_chr);
182 end_diagnostic(false);
185 void show_context (void)
198 base_ptr = input_ptr;
199 input_stack[base_ptr] = cur_input;
205 cur_input = input_stack[base_ptr];
207 if ((cur_input.state_field != 0))
208 if ((cur_input.name_field > 17) || (base_ptr == 0))
211 if ((base_ptr == input_ptr) || bottomline || (nn < error_context_lines))
213 if ((base_ptr == input_ptr) || (cur_input.state_field != token_list) ||
214 (cur_input.index_field != backed_up) || (cur_input.loc_field != 0))
217 old_setting = selector;
219 if (cur_input.state_field != 0)
221 if (cur_input.name_field <= 17)
222 if ((cur_input.name_field == 0))
226 print_nl("<insert> ");
230 if (cur_input.name_field == 17)
233 print_int(cur_input.name_field - 1);
241 /* show current input file name - ignore if from terminal */
242 if (cur_input.name_field > 17) /* redundant ? */
243 print(cur_input.name_field);
246 print_int(line); /* line number */
253 print_nl("l."); /* l. ? 573 ????? 98/Dec/8 check ! */
254 print_int(line); /* line number */
264 trick_count = 1000000L;
267 if (buffer[cur_input.limit_field] == end_line_char)
268 j = cur_input.limit_field;
270 j = cur_input.limit_field + 1;
273 for (i = cur_input.start_field; i <= j - 1; i++)
275 if (i == cur_input.loc_field)
278 trick_count = tally + 1 + error_line - half_error_line;
280 if (trick_count < error_line)
281 trick_count = error_line;
288 switch (cur_input.index_field)
291 print_nl("<argument> ");
296 print_nl("<template> ");
300 if (cur_input.loc_field == 0)
301 print_nl("<recently read> ");
303 print_nl("<to be read again> ");
307 print_nl("<inserted text> ");
312 print_cs(cur_input.name_field);
316 print_nl("<output> ");
320 print_nl("<everypar> ");
323 case every_math_text:
324 print_nl("<everymath> ");
327 case every_display_text:
328 print_nl("<everydisplay> ");
331 case every_hbox_text:
332 print_nl("<everyhbox> ");
335 case every_vbox_text:
336 print_nl("<everyvbox> ");
340 print_nl("<everyjob> ");
344 print_nl("<everycr> ");
352 print_nl("<write> ");
364 trick_count = 1000000L;
367 if (cur_input.index_field < macro)
368 show_token_list(cur_input.start_field, cur_input.loc_field, 100000L);
370 show_token_list(link(cur_input.start_field), cur_input.loc_field, 100000L);
373 selector = old_setting;
375 if (trick_count == 1000000L)
378 trick_count = tally + 1 + error_line - half_error_line;
380 if (trick_count < error_line)
381 trick_count = error_line;
384 if (tally < trick_count)
385 m = tally - first_count;
387 m = trick_count - first_count;
389 if (l + first_count <= half_error_line)
397 p = l + first_count - half_error_line + 3;
401 for (q = p; q <= first_count - 1; q++)
402 print_char(trick_buf[q % error_line]);
406 for (q = 1; q <= n; q++)
409 if (m + n <= error_line)
412 p = first_count +(error_line - n - 3);
414 for (q = first_count; q <= p - 1; q++)
415 print_char(trick_buf[q % error_line]);
417 if (m + n > error_line)
422 else if (nn == error_context_lines)
434 cur_input = input_stack[input_ptr];
436 //#pragma optimize("g", off) /* 98/Dec/10 experiment */
438 void begin_token_list_ (halfword p, quarterword t)
441 if (input_ptr > max_in_stack)
443 max_in_stack = input_ptr;
445 #ifdef ALLOCATEINPUTSTACK
446 if (input_ptr == current_stack_size)
447 input_stack = realloc_input_stack(increment_stack_size);
449 if (input_ptr == current_stack_size) /* check again after allocation */
451 overflow("input stack size", current_stack_size);
452 return; // abort_flag set
455 if (input_ptr == stack_size) /* input stack - not dynamic */
457 overflow("input stack size", stack_size);
458 return; // abort_flag set
463 input_stack[input_ptr] = cur_input;
467 cur_input.state_field = token_list;
468 cur_input.start_field = p;
469 cur_input.index_field = t;
476 cur_input.limit_field = param_ptr;
479 cur_input.loc_field = link(p);
481 if (tracing_macros > 1)
497 print_cmd_chr(assign_toks, t + (hash_size + 1307));
503 end_diagnostic(false);
508 cur_input.loc_field = p;
510 //#pragma optimize("", on) /* 98/Dec/10 experiment */
512 void end_token_list (void)
514 if (cur_input.index_field >= backed_up)
516 if (cur_input.index_field <= inserted)
517 flush_list(cur_input.start_field);
520 delete_token_ref(cur_input.start_field);
521 if (cur_input.index_field == macro)
522 while (param_ptr > cur_input.limit_field)
525 flush_list(param_stack[param_ptr]);
529 else if (cur_input.index_field == u_template)
530 if (align_state > 500000L)
534 fatal_error("(interwoven alignment preambles are not allowed)");
535 return; // abort_flag set
540 cur_input = input_stack[input_ptr];
546 pause_for_instructions();
551 void back_input (void)
555 while ((cur_input.state_field == 0) && (cur_input.loc_field == 0) &&
556 (cur_input.index_field != v_template))
564 if (cur_tok < right_brace_limit)
565 if (cur_tok < left_brace_limit)
571 if (input_ptr > max_in_stack)
573 max_in_stack = input_ptr;
574 #ifdef ALLOCATEINPUTSTACK
575 if (input_ptr == current_stack_size)
576 input_stack = realloc_input_stack(increment_stack_size);
578 if (input_ptr == current_stack_size) /* check again after allocation */
580 overflow("input stack size", current_stack_size);
581 return; // abort_flag set
584 if (input_ptr == stack_size) /* stack size - not dynamic */
586 overflow("input stack size", stack_size);
587 return; // abort_flag set
591 input_stack[input_ptr] = cur_input;
595 cur_input.state_field = token_list;
596 cur_input.start_field = p;
597 cur_input.index_field = backed_up;
598 cur_input.loc_field = p;
601 void back_error (void)
603 OK_to_interrupt = false;
605 OK_to_interrupt = true;
609 void ins_error (void)
611 OK_to_interrupt = false;
613 cur_input.index_field = inserted;
614 OK_to_interrupt = true;
618 void begin_file_reading (void)
620 if (in_open == max_in_open)
622 overflow("text input levels", max_in_open); /* text input levels - NOT DYNAMIC */
623 return; // abort_flag set
625 #ifdef ALLOCATEBUFFER
626 if (first == current_buf_size)
627 buffer = realloc_buffer(increment_buf_size);
629 if (first == current_buf_size) /* check again after allocation */
631 overflow("buffer size", current_buf_size);
632 return; // abort_flag set
635 if (first == buf_size)
637 overflow("buffer size", buf_size); /* buffer size - not dynamic */
638 return; // abort_flag set
642 if (in_open > high_in_open) /* 1999 Jan 17 */
643 high_in_open = in_open;
645 if (input_ptr > max_in_stack)
647 max_in_stack = input_ptr;
648 #ifdef ALLOCATEINPUTSTACK
649 if (input_ptr == current_stack_size)
650 input_stack = realloc_input_stack(increment_stack_size);
651 if (input_ptr == current_stack_size)
653 overflow("input stack size", current_stack_size); /* check again after allocation */
654 return; // abort_flag set
657 if (input_ptr == stack_size)
659 overflow("input stack size", stack_size); /* input stack - not dynamic */
660 return; // abort_flag set
664 input_stack[input_ptr] = cur_input;
667 cur_input.index_field = in_open;
668 line_stack[cur_input.index_field] = line;
669 cur_input.start_field = first;
670 cur_input.state_field = 1;
671 cur_input.name_field = 0;
674 void end_file_reading (void)
676 first = cur_input.start_field;
677 line = line_stack[cur_input.index_field];
679 if (cur_input.name_field > 17)
680 (void) a_close(input_file[cur_input.index_field]);
684 cur_input = input_stack[input_ptr];
688 /* called only form tex0.c */
690 void clear_for_error_prompt (void)
692 while ((cur_input.state_field != 0) &&
693 (cur_input.name_field == 0) && (input_ptr > 0) &&
694 (cur_input.loc_field > cur_input.limit_field))
700 void check_outer_validity (void)
705 if (scanner_status != 0)
707 deletions_allowed = false;
711 if ((cur_input.state_field == 0) || (cur_input.name_field < 1) || (cur_input.name_field > 17))
714 info(p) = cs_token_flag + cur_cs;
722 if (scanner_status > skipping)
727 print_err("File ended");
731 print_err("Forbidden control sequence found");
734 print_string(" while scanning ");
737 switch (scanner_status)
740 print_string("definition");
741 info(p) = right_brace_token + '}';
747 long_state = outer_call;
751 print_string("preamble");
752 info(p) = right_brace_token + '}';
756 info(p) = cs_token_flag + frozen_cr; /*96/Jan/10*/
757 align_state = -1000000L;
761 print_string("text");
762 info(p) = right_brace_token + '}';
766 print_string(" of ");
767 sprint_cs(warning_index);
768 help4("I suspect you have forgotten a `}', causing me",
769 "to read past where you wanted me to stop.",
770 "I'll try to recover; but if the error is serious,",
771 "you'd better type `E' or `X' now and fix your file.");
776 print_err("Incomplete ");
777 print_cmd_chr(if_test, cur_if);
778 print_string("; all text was ignored after line ");
779 print_int(skip_line);
780 help3("A forbidden control sequence occurred in skipped text.",
781 "This kind of error happens when you say `\\if...' and forget",
782 "the matching `\\fi'. I've inserted a `\\fi'; this might work.");
787 help_line[2] = "The file ended while I was skipping conditional text.";
789 cur_tok = cs_token_flag + frozen_fi; /* 96/Jan/10 */
792 deletions_allowed = true;
795 /*****************************************************************************/
796 /* get_next() moved from here to end for pragma optimize reasons 96/Sep/12 */
798 /*****************************************************************************/
800 void firm_up_the_line (void)
804 cur_input.limit_field = last;
807 if (interaction > nonstop_mode)
812 if (cur_input.start_field < cur_input.limit_field)
813 for (k = cur_input.start_field; k <= cur_input.limit_field - 1; k++)
816 first = cur_input.limit_field;
826 for (k = first; k <= last - 1; k++)
827 buffer[k + cur_input.start_field - first] = buffer[k];
829 cur_input.limit_field = cur_input.start_field + last - first;
834 void get_token (void)
836 no_new_control_sequence = false;
838 no_new_control_sequence = true;
841 cur_tok = (cur_cmd * 256) + cur_chr;
843 cur_tok = cs_token_flag + cur_cs;
846 void macro_call (void)
859 small_number savescannerstatus;
860 halfword savewarningindex;
861 ASCII_code match_chr;
863 savescannerstatus = scanner_status;
864 savewarningindex = warning_index;
865 warning_index = cur_cs;
870 if (tracing_macros > 0)
874 print_cs(warning_index);
875 token_show(refcount);
876 end_diagnostic(false);
879 if (info(r) != end_match_token)
881 scanner_status = matching;
883 long_state = eq_type(cur_cs);
885 if (long_state >= outer_call)
886 long_state = long_state - 2;
892 if ((info(r) > match_token + 255) || (info(r) < match_token))
896 match_chr = info(r) - match_token;
905 if (cur_tok == info(r))
909 if ((info(r) >= match_token) && (info(r) <= end_match_token))
911 if (cur_tok < left_brace_limit)
923 print_err("Use of ");
924 sprint_cs(warning_index);
925 print_string(" doesn't match its definition");
926 help4("If you say, e.g., `\\def\\a1{...}', then you must always",
927 "put `1' after `\\a', since control sequence names are",
928 "made up of letters only. The macro here has not been",
929 "followed by the required stuff, so I'm ignoring it.");
941 mem[q].hh.lh = mem[t].hh.lh;
952 if (cur_tok != info(v))
960 if (info(u) != info(v))
974 if (cur_tok == par_token)
975 if (long_state != long_call)
977 if (long_state == call)
980 print_err("Paragraph ended before ");
981 sprint_cs(warning_index);
982 print_string("was complete");
983 help3("I suspect you've forgotten a `}', causing me to apply this",
984 "control sequence to too much text. How can we recover?",
985 "My plan is to forget the whole thing and hope for the best.");
989 pstack[n] = link(temp_head);
990 align_state = align_state - unbalance;
992 for (m = 0; m <= n; m++)
993 flush_list(pstack[m]);
998 if (cur_tok < right_brace_limit)
999 if (cur_tok < left_brace_limit)
1013 avail = mem[q].hh.rh;
1022 mem[q].hh.lh = cur_tok;
1028 if (cur_tok == par_token)
1029 if (long_state != long_call)
1031 if (long_state == call)
1034 print_err("Paragraph ended before ");
1035 sprint_cs(warning_index);
1036 print_string(" was complete");
1037 help3("I suspect you've forgotten a `}', causing me to apply this",
1038 "control sequence to too much text. How can we recover?",
1039 "My plan is to forget the whole thing and hope for the best.");
1043 pstack[n] = link(temp_head);
1044 align_state = align_state - unbalance;
1046 for (m = 0; m <= n; m++)
1047 flush_list(pstack[m]);
1051 if (cur_tok < right_brace_limit)
1052 if (cur_tok < left_brace_limit)
1068 mem[q].hh.lh = cur_tok;
1075 print_err("Argument of ");
1076 sprint_cs(warning_index);
1077 print_string(" has an extra }");
1078 help6("I've run across a `}' that doesn't seem to match anything.",
1079 "For example, `\\def\\a#1{...}' and `\\a}' would produce",
1080 "this error. If you simply proceed now, the `\\par' that",
1081 "I've just inserted will cause me to report a runaway",
1082 "argument that might be the root of the problem. But if",
1083 "your `}' was spurious, just type `2' and it will go away.");
1086 cur_tok = par_token;
1092 if (cur_tok == space_token)
1093 if (info(r) <= end_match_token)
1094 if (info(r) >= match_token)
1099 mem[p].hh.rh = q; /* p may be used without having ... */
1100 mem[q].hh.lh = cur_tok;
1105 incr(m); /* m may be used without having been ... */
1107 if (info(r) > end_match_token)
1110 if (info(r) < match_token)
1115 if ((m == 1) && (info(p) < right_brace_limit) && (p != temp_head))
1117 link(rbraceptr) = 0; /* rbraceptr may be used without ... */
1119 p = link(temp_head);
1120 pstack[n] = link(p);
1124 pstack[n] = link(temp_head);
1128 if (tracing_macros > 0)
1131 //print_nl(match_chr); /* matchchar may be used without ... */
1132 print_nl(""); print(match_chr);
1135 show_token_list(pstack[n - 1], 0, 1000);
1136 end_diagnostic(false);
1140 while(!(info(r) == end_match_token));
1143 while((cur_input.state_field == token_list) && (cur_input.loc_field == 0) &&
1144 (cur_input.index_field != v_template))
1147 begin_token_list(refcount, macro);
1148 cur_input.name_field = warning_index;
1149 cur_input.loc_field = link(r);
1153 if (param_ptr + n > max_param_stack)
1155 max_param_stack = param_ptr + n;
1157 #ifdef ALLOCATEPARAMSTACK
1158 if (max_param_stack > current_param_size)
1159 param_stack = realloc_param_stack(increment_param_size);
1161 if (max_param_stack > current_param_size) /* check again after allocation */
1163 overflow("parameter stack size", current_param_size);
1164 return; // abort_flag set
1167 if (max_param_stack > param_size)
1169 overflow("parameter stack size", param_size); /* parameter stack - not dynamic */
1170 return; // abort_flag set
1175 for (m = 0; m <= n - 1; m++)
1176 param_stack[param_ptr + m] = pstack[m];
1178 param_ptr = param_ptr + n;
1181 scanner_status = savescannerstatus;
1182 warning_index = savewarningindex;
1185 void insert_relax (void)
1187 cur_tok = cs_token_flag + cur_cs;
1189 cur_tok = cs_token_flag + frozen_relax; /* 96/Jan/10 */
1191 cur_input.index_field = inserted;
1200 small_number cvlbackup, radixbackup, cobackup;
1201 halfword backupbackup;
1202 small_number savescannerstatus;
1205 cvlbackup = cur_val_level;
1206 radixbackup = radix;
1207 cobackup = cur_order;
1208 backupbackup = link(backup_head);
1212 if (tracing_commands > 1)
1218 if (cur_mark[cur_chr] != 0)
1219 begin_token_list(cur_mark[cur_chr], mark_text);
1227 if (cur_cmd > max_command)
1237 savescannerstatus = scanner_status;
1238 scanner_status = normal;
1240 scanner_status = savescannerstatus;
1244 if (t >= cs_token_flag)
1247 info(p) = cs_token_flag + frozen_dont_expand; /*96/Jan/10*/
1248 link(p) = cur_input.loc_field;
1249 cur_input.start_field = p;
1250 cur_input.loc_field = p;
1265 mem[q].hh.lh = cur_tok;
1269 while(!(cur_cs != 0));
1271 if (cur_cmd != end_cs_name)
1273 print_err("Missing ");
1274 print_esc("endcsname");
1275 print_string(" inserted");
1276 help2("The control sequence marked <to be read again> should",
1277 "not appear between \\csname and \\endcsname.");
1286 if (j >= max_buf_stack)
1288 max_buf_stack = j + 1;
1290 #ifdef ALLOCATEBUFFER
1291 if (max_buf_stack == current_buf_size)
1292 buffer = realloc_buffer (increment_buf_size);
1294 if (max_buf_stack == current_buf_size) /* check again after allocation */
1296 overflow("buffer size", current_buf_size);
1297 return; // abort_flag set
1300 if (max_buf_stack == buf_size)
1302 overflow("buffer size", buf_size); /* buffer size - not dynamic */
1303 return; // abort_flag set
1308 buffer[j] = info(p) % 256;
1315 no_new_control_sequence = false;
1316 cur_cs = id_lookup(first, j - first);
1317 no_new_control_sequence = true;
1319 else if (j == first)
1322 cur_cs = single_base + buffer[first];
1326 if (eq_type(cur_cs) == undefined_cs)
1328 eq_define(cur_cs, relax, 256);
1331 cur_tok = cur_cs + cs_token_flag;
1348 if (cur_chr > if_limit)
1353 print_err("Extra ");
1354 print_cmd_chr(fi_or_else, cur_chr);
1355 help1("I'm ignoring this; it doesn't match any \\if.");
1360 while(cur_chr != fi_code)
1365 if_line = if_line_field(p);
1366 cur_if = subtype(p);
1369 free_node(p, if_node_size);
1377 else if (name_in_progress)
1384 print_err("Undefined control sequence");
1385 help5("The control sequence at the end of the top line",
1386 "of your error message was never \\def'ed. If you have",
1387 "misspelled it (e.g., `\\hobx'), type `I' and the correct",
1388 "spelling (e.g., `I\\hbox'). Otherwise just continue,",
1389 "and I'll forget about whatever was undefined.");
1394 else if (cur_cmd < end_template)
1400 cur_tok = cs_token_flag + frozen_endv; /* 96/Jan/10 */
1405 cur_val_level = cvlbackup;
1406 radix = radixbackup;
1407 cur_order = cobackup;
1408 link(backup_head) = backupbackup;
1411 void get_x_token (void)
1416 if (cur_cmd <= max_command)
1418 if (cur_cmd >= call)
1419 if (cur_cmd < end_template)
1423 cur_cs = frozen_endv; /* 96/Jan/10 */
1433 cur_tok = (cur_cmd * 256) + cur_chr;
1435 cur_tok = cs_token_flag + cur_cs;
1440 while (cur_cmd > max_command)
1447 cur_tok = (cur_cmd * 256) + cur_chr;
1449 cur_tok = cs_token_flag + cur_cs;
1452 void scan_left_brace (void)
1458 while(!((cur_cmd != spacer) && (cur_cmd != relax)));
1460 if (cur_cmd != left_brace)
1462 print_err("Missing { inserted");
1463 help4("A left brace was mandatory here, so I've put one in.",
1464 "You might want to delete and/or insert some corrections",
1465 "so that I will find a matching right brace soon.",
1466 "(If you're confused by all this, try typing `I}' now.)");
1468 cur_tok = left_brace_token + '{';
1469 cur_cmd = left_brace;
1475 void scan_optional_equals (void)
1481 while(!(cur_cmd != spacer));
1483 if (cur_tok != other_token + '=')
1487 bool scan_keyword_(char * s)
1501 if ((cur_cs == 0) && ((cur_chr == (*k)) || (cur_chr == (*k) - 'a' + 'A')))
1506 mem[q].hh.lh = cur_tok;
1512 else if ((cur_cmd != spacer) || (p != backup_head))
1516 if (p != backup_head)
1517 back_list(link(backup_head));
1523 flush_list(link(backup_head));
1528 void mu_error (void)
1530 print_err("Incompatible glue units");
1531 help1("I'm going to assume that 1mu=1pt when they're mixed.");
1535 void scan_eight_bit_int (void)
1539 if ((cur_val < 0) || (cur_val > 255))
1541 print_err("Bad register code");
1542 help2("A register number must be between 0 and 255.",
1543 "I changed this one to zero.");
1549 void scan_char_num (void)
1553 if ((cur_val < 0) || (cur_val > 255))
1555 print_err("Bad character code");
1556 help2("A character number must be between 0 and 255.",
1557 "I changed this one to zero.");
1563 void scan_four_bit_int (void)
1567 if ((cur_val < 0) || (cur_val > 15))
1569 print_err("Bad number");
1570 help2("Since I expected to read a number between 0 and 15,",
1571 "I changed this one to zero.");
1577 void scan_fifteen_bit_int (void)
1580 if ((cur_val < 0) || (cur_val > 32767))
1582 print_err("Bad mathchar");
1583 help2("A mathchar number must be between 0 and 32767.",
1584 "I changed this one to zero.");
1590 void scan_twenty_seven_bit_int (void)
1594 if ((cur_val < 0) || (cur_val > 134217727L)) /* 2^27 - 1 */
1596 print_err("Bad delimiter code");
1597 help2("A numeric delimiter code must be between 0 and 2^{27}-1.",
1598 "I changed this one to zero.");
1604 void scan_font_ident (void)
1606 internal_font_number f;
1613 while (!(cur_cmd != spacer));
1615 if (cur_cmd == def_font)
1617 else if (cur_cmd == set_font)
1619 else if (cur_cmd == def_family)
1622 scan_four_bit_int();
1623 f = equiv(m + cur_val);
1627 print_err("Missing font identifier");
1628 help2("I was looking for a control sequence whose",
1629 "current meaning has been defined by \\font.");
1637 void find_font_dimen_(bool writing)
1639 internal_font_number f;
1647 if (n < 0 || (n == 0 && font_dimen_zero == 0)) /* change 98/Oct/5 */
1651 if (writing && (n <= space_shrink_code) && (n >= space_code) && (font_glue[f] != 0))
1653 delete_glue_ref(font_glue[f]);
1657 if (n > font_params[f])
1665 if (fmem_ptr == current_font_mem_size) /* 93/Nov/28 ??? */
1667 font_info = realloc_font_info(increment_font_mem_size);
1670 if (fmem_ptr == current_font_mem_size) /* 94/Jan/24 */
1672 overflow("font memory", current_font_mem_size); /* font memory */
1673 return; // abort_flag set
1676 if (fmem_ptr == font_mem_size)
1678 overflow("font memory", font_mem_size); /* font memory */
1679 return; // abort_flag set
1682 font_info[fmem_ptr].cint = 0;
1684 incr(font_params[f]);
1686 while(!(n == font_params[f]));
1688 cur_val = fmem_ptr - 1;
1691 cur_val = n + param_base[f]; /* 98/Oct/5 */
1693 // cur_val = (&font_check[f] - &font_info[0]); /* 98/Oct/5 */
1694 /* checksum = (((font_check[f].b0) << 8 | font_check[f].b1) << 8 |
1695 font_check[f].b2) << 8 | font_check[f].b3; */
1697 /* compiler error: '-' : incompatible types - from 'union fmemoryword *' to 'struct fourunsignedchars *' */
1698 if (cur_val == fmem_ptr)
1701 /* print_esc(hash[(hash_size + 524) + f].rh); */
1702 print_esc(""); print(font_id_text(f));
1703 print_string(" has only ");
1704 print_int(font_params[f]);
1705 print_string(" fontdimen parameters");
1706 help2("To increase the number of font parameters, you must",
1707 "use \\fontdimen immediately after the \\font is loaded.");
1712 void scan_something_internal_(small_number level, bool negative)
1725 if (m == math_code_base)
1727 cur_val = math_code(cur_val);
1728 cur_val_level = int_val;
1730 else if (m < math_code_base)
1732 cur_val = equiv(m + cur_val);
1733 cur_val_level = int_val;
1737 cur_val = eqtb[m + cur_val].cint;
1738 cur_val_level = int_val;
1748 if (level != tok_val)
1750 print_err("Missing number, treated as zero");
1751 help3("A number should have been here; I inserted `0'.",
1752 "(If you can't figure out why I needed to see a number,",
1753 "look up `weird error' in the index to The TeXbook.)");
1757 cur_val_level = dimen_val;
1760 else if (cur_cmd <= assign_toks)
1762 if (cur_cmd < assign_toks)
1764 scan_eight_bit_int();
1765 m = toks_base + cur_val;
1769 cur_val = eqtb[m].hh.rh;
1770 cur_val_level = tok_val;
1779 cur_val = font_id_base + cur_val; /* 96/Jan/10 */
1780 cur_val_level = ident_val;
1787 cur_val = eqtb[m].cint;
1788 cur_val_level = int_val;
1794 cur_val = eqtb[m].cint;
1795 cur_val_level = dimen_val;
1801 cur_val = eqtb[m].hh.rh;
1802 cur_val_level = glue_val;
1806 case assign_mu_glue:
1808 cur_val = eqtb[m].hh.rh;
1809 cur_val_level = mu_val;
1816 print_err("Improper ");
1817 print_cmd_chr(set_aux, m);
1818 help4("You can refer to \\spacefactor only in horizontal mode;",
1819 "you can refer to \\prevdepth only in vertical mode; and",
1820 "neither of these is meaningful inside \\write. So",
1821 "I'm forgetting what you said and using zero instead.");
1824 if (level != tok_val)
1827 cur_val_level = dimen_val;
1832 cur_val_level = int_val;
1835 else if (m == vmode)
1837 cur_val = cur_list.aux_field.cint;
1838 cur_val_level = dimen_val;
1842 cur_val = space_factor;
1843 cur_val_level = int_val;
1851 cur_val_level = int_val;
1855 nest[nest_ptr] = cur_list;
1858 while (abs(nest[p].mode_field)!= vmode)
1862 cur_val = nest[p].pg_field;
1863 cur_val_level = int_val;
1871 cur_val = dead_cycles;
1873 cur_val = insert_penalties;
1879 case set_page_dimen:
1881 if ((page_contents == 0) && (! output_active))
1883 cur_val = 1073741823L; /* 2^30 - 1 */
1887 cur_val = page_so_far[m];
1889 cur_val_level = dimen_val;
1895 if (par_shape_ptr == 0)
1898 cur_val = info(par_shape_ptr);
1900 cur_val_level = int_val;
1906 scan_eight_bit_int();
1908 if (box(cur_val) == 0)
1911 cur_val = mem[box(cur_val) + m].cint;
1913 cur_val_level = dimen_val;
1921 cur_val_level = int_val;
1925 case assign_font_dimen:
1927 find_font_dimen(false);
1928 font_info[fmem_ptr].cint = 0;
1930 cur_val = font_info[cur_val].cint;
1931 cur_val_level = dimen_val;
1936 case assign_font_int:
1942 cur_val = hyphen_char[cur_val];
1943 cur_val_level = int_val;
1947 cur_val = skew_char[cur_val];
1948 cur_val_level = int_val;
1955 scan_eight_bit_int();
1960 cur_val = count(cur_val);
1964 cur_val = dimen(cur_val);
1968 cur_val = skip(cur_val);
1972 cur_val = mu_skip(cur_val);
1981 if (cur_chr > glue_val)
1983 if (cur_chr == input_line_no_code)
1986 cur_val = last_badness;
1988 cur_val_level = int_val;
1992 if (cur_chr == glue_val)
1993 cur_val = zero_glue;
1997 cur_val_level = cur_chr;
1999 if (!(tail >= hi_mem_min) && (mode != 0))
2003 if (type(tail) == penalty_node)
2004 cur_val = penalty(tail);
2008 if (type(tail) == kern_node)
2009 cur_val = width(tail);
2013 if (type(tail) == glue_node)
2015 cur_val = glue_ptr(tail);
2017 if (subtype(tail) == mu_glue)
2018 cur_val_level = mu_val;
2022 else if ((mode == 1) && (tail == cur_list.head_field))
2026 cur_val = last_penalty;
2030 cur_val = last_kern;
2034 if (last_glue != empty_flag)
2035 cur_val = last_glue;
2043 print_err("You can't use `");
2044 print_cmd_chr(cur_cmd, cur_chr);
2045 print_string("' after ");
2047 help1("I'm forgetting what you said and using zero instead.");
2050 if (level != tok_val)
2053 cur_val_level = dimen_val;
2058 cur_val_level = int_val;
2064 while (cur_val_level > level)
2066 if (cur_val_level == glue_val)
2067 cur_val = width(cur_val);
2068 else if (cur_val_level == mu_val)
2071 decr(cur_val_level);
2075 if (cur_val_level >= 2)
2077 cur_val = new_spec(cur_val);
2080 width(cur_val) = - (integer) width(cur_val);
2081 stretch(cur_val) = - (integer) stretch(cur_val);
2082 shrink(cur_val) = - (integer) shrink(cur_val);
2086 cur_val = - (integer) cur_val;
2087 else if ((cur_val_level >= glue_val) && (cur_val_level <= mu_val))
2088 add_glue_ref(cur_val);
2091 void get_next (void)
2095 /* char cat; */ /* make this an int ? */
2096 int cat; /* make this an int ? 95/Jan/7 */
2103 if (cur_input.state_field != token_list)
2106 if (cur_input.loc_field <= cur_input.limit_field)
2108 cur_chr = buffer[cur_input.loc_field];
2109 incr(cur_input.loc_field);
2111 cur_cmd = cat_code(cur_chr);
2113 switch (cur_input.state_field + cur_cmd)
2115 case any_state_plus(ignore):
2116 case skip_blanks + spacer:
2117 case new_line + spacer:
2121 case any_state_plus(escape):
2123 if (cur_input.loc_field > cur_input.limit_field)
2128 k = cur_input.loc_field;
2129 cur_chr = buffer[k];
2130 cat = cat_code(cur_chr);
2134 cur_input.state_field = skip_blanks;
2135 else if (cat == spacer)
2136 cur_input.state_field = skip_blanks;
2138 cur_input.state_field = mid_line;
2140 if ((cat == letter) && (k <= cur_input.limit_field))
2144 cur_chr = buffer[k];
2145 cat = cat_code(cur_chr);
2148 while(!((cat != letter) || (k > cur_input.limit_field)));
2151 if (buffer[k]== cur_chr)
2152 if (cat == sup_mark)
2153 if (k < cur_input.limit_field)
2160 if ((((c >= 48) && (c <= 57)) || ((c >= 97) && (c <= 102))))
2161 if (k + 2 <= cur_input.limit_field)
2165 if ((((cc >= 48) && (cc <= 57)) || ((cc >= 97) && (cc <= 102))))
2177 cur_chr = 16 * cur_chr + cc - 48;
2179 cur_chr = 16 * cur_chr + cc - 87;
2181 buffer[k - 1] = cur_chr;
2184 buffer[k - 1] = c + 64;
2186 buffer[k - 1] = c - 64;
2188 cur_input.limit_field = cur_input.limit_field - d;
2191 while (k <= cur_input.limit_field)
2193 buffer[k] = buffer[k + d];
2205 if (k > cur_input.loc_field + 1)
2207 cur_cs = id_lookup(cur_input.loc_field, k - cur_input.loc_field);
2208 cur_input.loc_field = k;
2214 if (buffer[k] == cur_chr)
2215 if (cat == sup_mark)
2216 if (k < cur_input.limit_field)
2220 if (c < 128) /* ? */
2223 if ((((c >= 48) && (c <= 57)) || ((c >= 97) && (c <= 102))))
2224 if (k + 2 <= cur_input.limit_field)
2228 if ((((cc >= 48) && (cc <= 57)) || ((cc >= 97) && (cc <= 102))))
2239 if (cc <= 57) /* cc may be used without ... */
2240 cur_chr = 16 * cur_chr + cc - 48;
2242 cur_chr = 16 * cur_chr + cc - 87;
2244 buffer[k - 1] = cur_chr;
2247 buffer[k - 1] = c + 64;
2249 buffer[k - 1] = c - 64;
2251 cur_input.limit_field = cur_input.limit_field - d;
2254 while (k <= cur_input.limit_field)
2256 buffer[k] = buffer[k + d];
2263 cur_cs = single_base + buffer[cur_input.loc_field];
2264 incr(cur_input.loc_field);
2267 cur_cmd = eq_type(cur_cs);
2268 cur_chr = equiv(cur_cs);
2270 if (cur_cmd >= outer_call)
2271 check_outer_validity();
2275 case any_state_plus(active_char):
2277 cur_cs = cur_chr + active_base;
2278 cur_cmd = eq_type(cur_cs);
2279 cur_chr = equiv(cur_cs);
2280 cur_input.state_field = mid_line;
2282 if (cur_cmd >= outer_call)
2283 check_outer_validity();
2287 case any_state_plus(sup_mark):
2289 if (cur_chr == buffer[cur_input.loc_field])
2290 if (cur_input.loc_field < cur_input.limit_field)
2292 c = buffer[cur_input.loc_field + 1];
2296 cur_input.loc_field = cur_input.loc_field + 2;
2298 if ((((c >= 48) && (c <= 57)) || ((c >= 97) && (c <= 102))))
2299 if (cur_input.loc_field <= cur_input.limit_field)
2301 cc = buffer[cur_input.loc_field];
2303 if ((((cc >= 48) && (cc <= 57)) || ((cc >= 97) && (cc <= 102))))
2305 incr(cur_input.loc_field);
2313 cur_chr = 16 * cur_chr + cc - 48;
2315 cur_chr = 16 * cur_chr + cc - 87;
2330 cur_input.state_field = mid_line;
2334 case any_state_plus(invalid_char):
2336 print_err("Text line contains an invalid character");
2337 help2("A funny symbol that I can't read has just been input.",
2338 "Continue, and I'll forget that it ever happened.");
2339 deletions_allowed = false;
2341 deletions_allowed = true;
2346 case mid_line + spacer:
2348 cur_input.state_field = skip_blanks;
2353 case mid_line + car_ret:
2355 cur_input.loc_field = cur_input.limit_field + 1;
2361 case skip_blanks + car_ret:
2362 case any_state_plus(comment):
2364 cur_input.loc_field = cur_input.limit_field + 1;
2369 case new_line + car_ret:
2371 cur_input.loc_field = cur_input.limit_field + 1;
2373 cur_cmd = eq_type(cur_cs);
2374 cur_chr = equiv(cur_cs);
2376 if (cur_cmd >= outer_call)
2377 check_outer_validity();
2381 case mid_line + left_brace:
2385 case skip_blanks + left_brace:
2386 case new_line + left_brace:
2388 cur_input.state_field = mid_line;
2393 case mid_line + right_brace:
2397 case skip_blanks + right_brace:
2398 case new_line + right_brace:
2400 cur_input.state_field = 1;
2405 case add_delims_to(skip_blanks):
2406 case add_delims_to(new_line):
2407 cur_input.state_field = 1;
2416 cur_input.state_field = new_line;
2418 if (cur_input.name_field > 17)
2421 first = cur_input.start_field;
2425 if (input_ln(input_file[cur_input.index_field], true))
2440 check_outer_validity();
2444 if ((end_line_char < 0) || (end_line_char > 255))
2445 decr(cur_input.limit_field);
2447 buffer[cur_input.limit_field] = end_line_char;
2449 first = cur_input.limit_field + 1;
2450 cur_input.loc_field = cur_input.start_field;
2454 if (!(cur_input.name_field == 0))
2467 if (selector < log_only)
2470 if (interaction > nonstop_mode)
2472 if ((end_line_char < 0) || (end_line_char > 255))
2473 incr(cur_input.limit_field);
2475 if (cur_input.limit_field == cur_input.start_field)
2476 print_nl("(Please type a command or say `\\end')");
2479 first = cur_input.start_field;
2487 cur_input.limit_field = last;
2489 if ((end_line_char < 0) || (end_line_char > 255))
2490 decr(cur_input.limit_field);
2492 buffer[cur_input.limit_field]= end_line_char;
2494 first = cur_input.limit_field + 1;
2495 cur_input.loc_field = cur_input.start_field;
2499 fatal_error("*** (job aborted, no legal \\end found)");
2500 return; // abort_flag set
2507 pause_for_instructions();
2514 else if (cur_input.loc_field != 0)
2516 t = info(cur_input.loc_field);
2517 cur_input.loc_field = link(cur_input.loc_field);
2519 if (t >= cs_token_flag)
2521 cur_cs = t - cs_token_flag;
2522 cur_cmd = eq_type(cur_cs);
2523 cur_chr = equiv(cur_cs);
2525 if (cur_cmd >= outer_call)
2526 if (cur_cmd == dont_expand)
2528 cur_cs = info(cur_input.loc_field) - cs_token_flag;
2529 cur_input.loc_field = 0;
2530 cur_cmd = eq_type(cur_cs);
2531 cur_chr = equiv(cur_cs);
2533 if (cur_cmd > max_command)
2536 cur_chr = no_expand_flag;
2541 check_outer_validity();
2561 begin_token_list(param_stack[cur_input.limit_field + cur_chr - 1], parameter);
2577 if (cur_cmd <= car_ret)
2578 if (cur_cmd >= tab_mark)
2579 if (align_state == 0)
2581 if ((scanner_status == aligning) && (cur_align == 0))
2583 fatal_error("(interwoven alignment preambles are not allowed)");
2584 return; // abort_flag set
2587 cur_cmd = extra_info(cur_align);
2588 extra_info(cur_align) = cur_chr;
2590 if (cur_cmd == omit)
2591 begin_token_list(omit_template, v_template);
2593 begin_token_list(v_part(cur_align), v_template);
2595 align_state = 1000000L;