2 Copyright 2014 Clerk Ma
\r
4 This program is free software; you can redistribute it and/or modify
\r
5 it under the terms of the GNU General Public License as published by
\r
6 the Free Software Foundation; either version 2 of the License, or
\r
7 (at your option) any later version.
\r
9 This program is distributed in the hope that it will be useful, but
\r
10 WITHOUT ANY WARRANTY; without even the implied warranty of
\r
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
12 General Public License for more details.
\r
14 You should have received a copy of the GNU General Public License
\r
15 along with this program; if not, write to the Free Software
\r
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
\r
20 #define EXTERN extern
\r
22 #include "yandytex.h"
\r
25 void scan_int (void)
\r
43 while (!(cur_cmd != spacer));
\r
45 if (cur_tok == other_token + '-')
\r
47 negative = !negative;
\r
48 cur_tok = other_token + '+';
\r
51 while (!(cur_tok != other_token + '+'));
\r
53 if (cur_tok == alpha_token)
\r
57 if (cur_tok < cs_token_flag)
\r
61 if (cur_cmd <= right_brace)
\r
62 if (cur_cmd == right_brace)
\r
67 else if (cur_tok < cs_token_flag + single_base)
\r
68 cur_val = cur_tok - cs_token_flag - active_base;
\r
70 cur_val = cur_tok - cs_token_flag - single_base;
\r
74 print_err("Improper alphabetic constant");
\r
75 help2("A one-character control sequence belongs after a ` mark.",
\r
76 "So I'm essentially inserting \\0 here.");
\r
84 if (cur_cmd != spacer)
\r
88 else if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))
\r
90 scan_something_internal(int_val, false);
\r
95 m = 214748364L; /* 7FFFFFFF hex */
\r
97 if (cur_tok == octal_token)
\r
100 m = 268435456L; /* 2^28 */
\r
103 else if (cur_tok == hex_token)
\r
106 m = 134217728L; /* 2^27 8000000 hex */
\r
115 if ((cur_tok < zero_token + radix) && (cur_tok >= zero_token) && (cur_tok <= zero_token + 9))
\r
116 d = cur_tok - zero_token;
\r
117 else if (radix == 16)
\r
118 if ((cur_tok <= A_token + 5) && (cur_tok >= A_token))
\r
119 d = cur_tok - A_token + 10;
\r
120 else if ((cur_tok <= other_A_token + 5) && (cur_tok >= other_A_token))
\r
121 d = cur_tok - other_A_token;
\r
129 if ((cur_val >= m) && ((cur_val > m) || (d > 7) || (radix != 10)))
\r
133 print_err("Number too big");
\r
134 help2("I can only go up to 2147483647='17777777777=\"7FFFFFFF,",
\r
135 "so I'm using that number instead of yours.");
\r
137 cur_val = 2147483647L; /* 7FFFFFFF hex */
\r
142 cur_val = cur_val * radix + d;
\r
150 print_err("Missing number, treated as zero");
\r
151 help3("A number should have been here; I inserted `0'.",
\r
152 "(If you can't figure out why I needed to see a number,",
\r
153 "look up `weird error' in the index to The TeXbook.)");
\r
156 else if (cur_cmd != spacer)
\r
161 cur_val = - (integer) cur_val;
\r
164 void scan_dimen (boolean mu, boolean inf, boolean shortcut)
\r
168 integer num, denom;
\r
169 small_number k, kk;
\r
172 integer save_cur_val;
\r
175 arith_error = false;
\r
176 cur_order = normal;
\r
189 while (!(cur_cmd != spacer));
\r
191 if (cur_tok == other_token + '-')
\r
193 negative = ! negative;
\r
194 cur_tok = other_token + '+';
\r
197 while (!(cur_tok != other_token + '+'));
\r
199 if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))
\r
203 scan_something_internal(mu_val, false);
\r
205 if (cur_val_level >= glue_val)
\r
207 v = width(cur_val);
\r
208 delete_glue_ref(cur_val);
\r
212 if (cur_val_level == mu_val)
\r
215 if (cur_val_level != int_val)
\r
220 scan_something_internal(dimen_val, false);
\r
222 if (cur_val_level == dimen_val)
\r
230 if (cur_tok == continental_point_token)
\r
231 cur_tok = point_token;
\r
233 if (cur_tok != point_token)
\r
243 if (cur_tok == continental_point_token)
\r
244 cur_tok = point_token;
\r
246 if ((radix == 10) && (cur_tok == point_token))
\r
256 if ((cur_tok > zero_token + 9) || (cur_tok < zero_token))
\r
263 info(q) = cur_tok - zero_token;
\r
270 for (kk = k; kk >= 1; kk--)
\r
272 dig[kk - 1] = info(p);
\r
278 f = round_decimals(k);
\r
280 if (cur_cmd != spacer)
\r
288 negative = !negative;
\r
289 cur_val = - (integer) cur_val;
\r
294 if (scan_keyword("fil"))
\r
298 while (scan_keyword("l"))
\r
300 if (cur_order == filll)
\r
302 print_err("Illegal unit of measure (");
\r
303 prints("replaced by filll)");
\r
304 help1("I dddon't go any higher than filll.");
\r
311 goto attach_fraction;
\r
315 save_cur_val = cur_val;
\r
321 while (!(cur_cmd != spacer));
\r
323 if ((cur_cmd < min_internal) || (cur_cmd > max_internal))
\r
329 scan_something_internal(mu_val, false);
\r
331 if (cur_val_level >= glue_val)
\r
333 v = width(cur_val);
\r
334 delete_glue_ref(cur_val);
\r
338 if (cur_val_level != mu_val)
\r
345 scan_something_internal(dimen_val, false);
\r
355 if (scan_keyword("em"))
\r
356 v = quad(cur_font);
\r
357 else if (scan_keyword("ex"))
\r
358 v = x_height(cur_font);
\r
365 if (cur_cmd != spacer)
\r
370 cur_val = nx_plus_y(save_cur_val, v, xn_over_d(v, f, 65536L));
\r
376 if (scan_keyword("mu"))
\r
377 goto attach_fraction;
\r
380 print_err("Illegal unit of measure (");
\r
381 prints("mu inserted)");
\r
382 help4("The unit of measurement in math glue must be mu.",
\r
383 "To recover gracefully from this error, it's best to",
\r
384 "delete the erroneous units; e.g., type `2' to delete",
\r
385 "two letters. (See Chapter 27 of The TeXbook.)");
\r
387 goto attach_fraction;
\r
391 if (scan_keyword("true"))
\r
397 cur_val = xn_over_d(cur_val, 1000, mag);
\r
398 f = (1000 * f + 65536L * tex_remainder) / mag;
\r
399 cur_val = cur_val + (f / 65536L);
\r
404 if (scan_keyword("pt"))
\r
405 goto attach_fraction;
\r
407 if (scan_keyword("in"))
\r
408 set_conversion(7227, 100);
\r
409 else if (scan_keyword("pc"))
\r
410 set_conversion(12, 1);
\r
411 else if (scan_keyword("cm"))
\r
412 set_conversion(7227, 254);
\r
413 else if (scan_keyword("mm"))
\r
414 set_conversion(7227, 2540);
\r
415 else if (scan_keyword("bp"))
\r
416 set_conversion(7227, 7200);
\r
417 else if (scan_keyword("dd"))
\r
418 set_conversion(1238, 1157);
\r
419 else if (scan_keyword("cc"))
\r
420 set_conversion(14856, 1157);
\r
421 else if (scan_keyword("Q"))
\r
422 set_conversion(7227, 10160);
\r
423 else if (scan_keyword("H"))
\r
424 set_conversion(7227, 10160);
\r
425 else if (scan_keyword("twip"))
\r
426 set_conversion(1, 20);
\r
427 else if (scan_keyword("sp"))
\r
431 print_err("Illegal unit of measure (");
\r
432 prints("pt inserted)");
\r
433 help6("Dimensions can be in units of em, ex, in, pt, pc,",
\r
434 "cm, mm, dd, cc, bp, or sp; but yours is a new one!",
\r
435 "I'll assume that you meant to say pt, for printer's points.",
\r
436 "To recover gracefully from this error, it's best to",
\r
437 "delete the erroneous units; e.g., type `2' to delete",
\r
438 "two letters. (See Chapter 27 of The TeXbook.)");
\r
443 cur_val = xn_over_d(cur_val, num, denom);
\r
444 f = (num * f + 65536L * tex_remainder) / denom;
\r
445 cur_val = cur_val +(f / 65536L);
\r
450 if (cur_val >= 16384) /* 2^14 */
\r
451 arith_error = true;
\r
453 cur_val = cur_val * unity + f;
\r
459 if (cur_cmd != spacer)
\r
464 if (arith_error || (abs(cur_val) >= 1073741824L)) /* 2^30 */
\r
466 print_err("Dimension too large");
\r
467 help2("I can't work with sizes bigger than about 19 feet.",
\r
468 "Continue and I'll use the largest value I can.");
\r
470 cur_val = max_dimen;
\r
471 arith_error = false;
\r
475 cur_val = - (integer) cur_val;
\r
478 void scan_glue (small_number level)
\r
484 mu = (level == mu_val);
\r
493 while (!(cur_cmd != spacer));
\r
495 if (cur_tok == other_token + '-')
\r
497 negative = !negative;
\r
498 cur_tok = other_token + '+';
\r
501 while (!(cur_tok != other_token + '+'));
\r
503 if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))
\r
505 scan_something_internal(level, negative);
\r
507 if (cur_val_level >= glue_val)
\r
509 if (cur_val_level != level)
\r
515 if (cur_val_level == int_val)
\r
516 scan_dimen(mu, false, true);
\r
517 else if (level == mu_val)
\r
523 scan_dimen(mu, false, false);
\r
526 cur_val = - (integer) cur_val;
\r
529 q = new_spec(zero_glue);
\r
530 width(q) = cur_val;
\r
532 if (scan_keyword("plus"))
\r
534 scan_dimen(mu, true, false);
\r
535 stretch(q) = cur_val;
\r
536 stretch_order(q) = cur_order;
\r
539 if (scan_keyword("minus"))
\r
541 scan_dimen(mu, true, false);
\r
542 shrink(q) = cur_val;
\r
543 shrink_order(q) = cur_order;
\r
549 pointer scan_rule_spec (void)
\r
555 if (cur_cmd == vrule)
\r
556 width(q) = default_rule;
\r
559 height(q) = default_rule;
\r
565 if (scan_keyword("width"))
\r
567 scan_dimen(false, false, false);
\r
568 width(q) = cur_val;
\r
572 if (scan_keyword("height"))
\r
574 scan_dimen(false, false, false);
\r
575 height(q) = cur_val;
\r
579 if (scan_keyword("depth"))
\r
581 scan_dimen(false, false, false);
\r
582 depth(q) = cur_val;
\r
589 pointer str_toks (pool_pointer b)
\r
601 while (k < pool_ptr)
\r
608 t = other_token + t;
\r
610 fast_store_new_token(t);
\r
619 pointer the_toks (void)
\r
626 scan_something_internal(tok_val, false);
\r
628 if (cur_val_level >= ident_val)
\r
633 if (cur_val_level == ident_val)
\r
634 store_new_token(cs_token_flag + cur_val);
\r
635 else if (cur_val != 0)
\r
641 fast_store_new_token(info(r));
\r
650 old_setting = selector;
\r
651 selector = new_string;
\r
654 switch (cur_val_level)
\r
657 print_int(cur_val);
\r
662 print_scaled(cur_val);
\r
669 print_spec(cur_val, "pt");
\r
670 delete_glue_ref(cur_val);
\r
676 print_spec(cur_val, "mu");
\r
677 delete_glue_ref(cur_val);
\r
682 selector = old_setting;
\r
683 return str_toks(b);
\r
687 void ins_the_toks (void)
\r
689 link(garbage) = the_toks();
\r
690 ins_list(link(temp_head));
\r
693 void conv_toks (void)
\r
697 small_number save_scanner_status;
\r
705 case roman_numeral_code:
\r
711 save_scanner_status = scanner_status;
\r
712 scanner_status = 0;
\r
714 scanner_status = save_scanner_status;
\r
717 case font_name_code:
\r
721 case job_name_code:
\r
727 old_setting = selector;
\r
728 selector = new_string;
\r
734 print_int(cur_val);
\r
737 case roman_numeral_code:
\r
738 print_roman_int(cur_val);
\r
745 print_char(cur_chr);
\r
752 case font_name_code:
\r
753 print(font_name[cur_val]);
\r
755 if (font_size[cur_val] != font_dsize[cur_val])
\r
758 print_scaled(font_size[cur_val]);
\r
763 case job_name_code:
\r
768 selector = old_setting;
\r
769 link(garbage) = str_toks(b);
\r
770 begin_token_list(link(temp_head), 4);
\r
773 pointer scan_toks (boolean macro_def, boolean xpand)
\r
779 halfword unbalance;
\r
780 halfword hash_brace;
\r
783 scanner_status = defining;
\r
785 scanner_status = absorbing;
\r
787 warning_index = cur_cs;
\r
788 def_ref = get_avail();
\r
789 token_ref_count(def_ref) = 0;
\r
800 if (cur_tok < right_brace_limit)
\r
803 if (cur_cmd == mac_param)
\r
805 s = match_token + cur_chr;
\r
808 if (cur_cmd == left_brace)
\r
810 hash_brace = cur_tok;
\r
811 store_new_token(cur_tok);
\r
812 store_new_token(end_match_token);
\r
816 if (t == zero_token + 9)
\r
818 print_err("You already have nine parameters");
\r
819 help1("I'm going to ignore the # sign you just used.");
\r
828 print_err("Parameters must be numbered consecutively");
\r
829 help2("I've inserted the digit you should have used after the #.",
\r
830 "Type `1' to delete what you did use.");
\r
838 store_new_token(cur_tok);
\r
842 store_new_token(end_match_token);
\r
844 if (cur_cmd == right_brace)
\r
846 print_err("Missing { inserted");
\r
848 help2("Where was the left brace? You said something like `\\def\\a}',",
\r
849 "which I'm going to interpret as `\\def\\a{}'.");
\r
870 if (cur_cmd <= max_command)
\r
873 if (cur_cmd != the)
\r
881 if (link(temp_head) != 0)
\r
883 link(p) = link(temp_head);
\r
894 if (cur_tok < right_brace_limit)
\r
895 if (cur_cmd < right_brace)
\r
901 if (unbalance == 0)
\r
904 else if (cur_cmd == mac_param)
\r
914 if (cur_cmd != mac_param)
\r
915 if ((cur_tok <= zero_token) || (cur_tok > t))
\r
917 print_err("Illegal parameter number in definition of ");
\r
918 sprint_cs(warning_index);
\r
919 help3("You meant to type ## instead of #, right?",
\r
920 "Or maybe a } was forgotten somewhere earlier, and things",
\r
921 "are all screwed up? I'm going to assume that you meant ##.");
\r
926 cur_tok = out_param_token - '0' + cur_chr;
\r
929 store_new_token(cur_tok);
\r
933 scanner_status = 0;
\r
935 if (hash_brace != 0)
\r
936 store_new_token(hash_brace);
\r
941 void read_toks (integer n, pointer r)
\r
946 /* small_number m; */
\r
949 scanner_status = defining;
\r
951 def_ref = get_avail();
\r
952 token_ref_count(def_ref) = 0;
\r
954 store_new_token(end_match_token);
\r
956 if ((n < 0) || (n > 15))
\r
962 align_state = 1000000L;
\r
966 begin_file_reading();
\r
969 if (read_open[m] == closed)
\r
970 if (interaction > nonstop_mode)
\r
982 fatal_error("*** (cannot \\read from terminal in nonstop modes)");
\r
985 else if (read_open[m] == just_open)
\r
986 if (input_ln(read_file[m], false))
\r
987 read_open[m] = normal;
\r
990 a_close(read_file[m]);
\r
991 read_open[m] = closed;
\r
995 if (!input_ln(read_file[m], true))
\r
997 a_close(read_file[m]);
\r
998 read_open[m] = closed;
\r
1000 if (align_state != 1000000L)
\r
1003 print_err("File ended within ");
\r
1004 print_esc("read");
\r
1005 help1("This \\read has unbalanced braces.");
\r
1006 align_state = 1000000L;
\r
1014 if (end_line_char_inactive())
\r
1017 buffer[limit] = end_line_char;
\r
1019 first = limit + 1;
\r
1030 if (align_state < 1000000L)
\r
1036 while (!(cur_tok == 0));
\r
1038 align_state = 1000000L;
\r
1042 store_new_token(cur_tok);
\r
1046 end_file_reading();
\r
1048 while (!(align_state == 1000000L));
\r
1050 cur_val = def_ref;
\r
1051 scanner_status = normal;
\r
1055 void pass_text (void)
\r
1058 small_number save_scanner_status;
\r
1060 save_scanner_status = scanner_status;
\r
1061 scanner_status = skipping;
\r
1069 if (cur_cmd == fi_or_else)
\r
1074 if (cur_chr == fi_code)
\r
1077 else if (cur_cmd == if_test)
\r
1082 scanner_status = save_scanner_status;
\r
1085 void change_if_limit (small_number l, pointer p)
\r
1089 if (p == cond_ptr)
\r
1114 void conditional (void)
\r
1120 small_number save_scanner_status;
\r
1121 pointer save_cond_ptr;
\r
1122 small_number this_if;
\r
1125 p = get_node(if_node_size);
\r
1126 link(p) = cond_ptr;
\r
1127 type(p) = if_limit;
\r
1128 subtype(p) = cur_if;
\r
1129 if_line_field(p) = if_line;
\r
1132 if_limit = if_code;
\r
1136 save_cond_ptr = cond_ptr;
\r
1137 this_if = cur_chr;
\r
1141 case if_char_code:
\r
1144 get_x_token_or_active_char();
\r
1146 if ((cur_cmd > active_char) || (cur_chr > 255))
\r
1157 get_x_token_or_active_char();
\r
1159 if ((cur_cmd > active_char) || (cur_chr > 255))
\r
1165 if (this_if == if_char_code)
\r
1166 b = (n == cur_chr);
\r
1168 b = (m == cur_cmd);
\r
1175 if (this_if == if_int_code)
\r
1178 scan_dimen(false, false, false);
\r
1186 while (!(cur_cmd != spacer));
\r
1188 if ((cur_tok >= other_token + '<') && (cur_tok <= other_token + '>'))
\r
1189 r = cur_tok - other_token;
\r
1192 print_err("Missing = inserted for ");
\r
1193 print_cmd_chr(if_test, this_if);
\r
1194 help1("I was expecting to see `<', `=', or `>'. Didn't.");
\r
1199 if (this_if == if_int_code)
\r
1202 scan_dimen(false, false, false);
\r
1207 b = (n < cur_val);
\r
1211 b = (n == cur_val);
\r
1215 b = (n > cur_val);
\r
1226 case if_vmode_code:
\r
1227 b = (abs(mode) == vmode);
\r
1230 case if_hmode_code:
\r
1231 b = (abs(mode) == hmode);
\r
1234 case if_mmode_code:
\r
1235 b = (abs(mode) == mmode);
\r
1238 case if_inner_code:
\r
1242 case if_void_code:
\r
1243 case if_hbox_code:
\r
1244 case if_vbox_code:
\r
1246 scan_eight_bit_int();
\r
1249 if (this_if == if_void_code)
\r
1253 else if (this_if == if_hbox_code)
\r
1254 b = (type(p) == hlist_node);
\r
1256 b = (type(p) == vlist_node);
\r
1262 save_scanner_status = scanner_status;
\r
1263 scanner_status = 0;
\r
1272 else if (cur_cmd < call)
\r
1273 b = (cur_chr == q);
\r
1276 p = link(cur_chr);
\r
1277 q = link(equiv(n));
\r
1283 while ((p != 0) && (q != 0))
\r
1284 if (info(p) != info(q))
\r
1292 b = ((p == 0) && (q == 0));
\r
1296 scanner_status = save_scanner_status;
\r
1302 scan_four_bit_int();
\r
1303 b = (read_open[cur_val] == closed);
\r
1307 case if_true_code:
\r
1311 case if_false_code:
\r
1315 case if_case_code:
\r
1320 if (tracing_commands > 1)
\r
1322 begin_diagnostic();
\r
1326 end_diagnostic(false);
\r
1333 if (cond_ptr == save_cond_ptr)
\r
1334 if (cur_chr == or_code)
\r
1337 goto common_ending;
\r
1338 else if (cur_chr == fi_code)
\r
1341 if_line = if_line_field(p);
\r
1342 cur_if = subtype(p);
\r
1343 if_limit = type(p);
\r
1344 cond_ptr = link(p);
\r
1345 free_node(p, if_node_size);
\r
1349 change_if_limit(or_code, save_cond_ptr);
\r
1355 if (tracing_commands > 1)
\r
1357 begin_diagnostic();
\r
1362 prints("{false}");
\r
1364 end_diagnostic(false);
\r
1369 change_if_limit(else_code, save_cond_ptr);
\r
1377 if (cond_ptr == save_cond_ptr)
\r
1379 if (cur_chr != or_code)
\r
1380 goto common_ending;
\r
1382 print_err("Extra ");
\r
1384 help1("I'm ignoring this; it doesn't match any \\if.");
\r
1387 else if (cur_chr == fi_code)
\r
1390 if_line = if_line_field(p);
\r
1391 cur_if = subtype(p);
\r
1392 if_limit = type(p);
\r
1393 cond_ptr = link(p);
\r
1394 free_node(p, if_node_size);
\r
1399 if (cur_chr == fi_code)
\r
1402 if_line = if_line_field(p);
\r
1403 cur_if = subtype(p);
\r
1404 if_limit = type(p);
\r
1405 cond_ptr = link(p);
\r
1406 free_node(p, if_node_size);
\r
1409 if_limit = fi_code;
\r
1412 void begin_name (void)
\r
1414 area_delimiter = 0;
\r
1415 ext_delimiter = 0;
\r
1418 boolean more_name (ASCII_code c)
\r
1420 if (quoted_file_name == false && c == ' ')
\r
1422 else if (quoted_file_name != false && c == '"')
\r
1424 quoted_file_name = false; /* catch next space character */
\r
1425 return true; /* accept ending quote, but throw away */
\r
1432 // for DOS/Windows
\r
1433 if ((c == '/' || c == '\\' || c == ':'))
\r
1435 area_delimiter = cur_length;
\r
1436 ext_delimiter = 0;
\r
1438 else if (c == '.')
\r
1439 ext_delimiter = cur_length;
\r
1446 void end_name (void)
\r
1448 #ifdef ALLOCATESTRING
\r
1449 if (str_ptr + 3 > current_max_strings)
\r
1450 str_start = realloc_str_start(increment_max_strings + 3);
\r
1452 if (str_ptr + 3 > current_max_strings)
\r
1454 overflow("number of strings", current_max_strings - init_str_ptr);
\r
1458 if (str_ptr + 3 > max_strings)
\r
1460 overflow("number of strings", max_strings - init_str_ptr);
\r
1465 if (area_delimiter == 0) // no area delimiter ':' '/' or '\' found
\r
1466 cur_area = 335; // "" default area
\r
1469 cur_area = str_ptr;
\r
1470 str_start[str_ptr + 1] = str_start[str_ptr] + area_delimiter;
\r
1474 if (ext_delimiter == 0) // no extension delimiter '.' found
\r
1476 cur_ext = 335; // "" default extension
\r
1477 cur_name = make_string();
\r
1481 cur_name = str_ptr;
\r
1482 str_start[str_ptr + 1] = str_start[str_ptr] + ext_delimiter - area_delimiter - 1;
\r
1484 cur_ext = make_string();
\r
1488 void pack_file_name (str_number n, str_number a, str_number e)
\r
1496 for (j = str_start[a]; j <= str_start[a + 1] - 1; j++)
\r
1497 append_to_name(str_pool[j]);
\r
1499 for (j = str_start[n]; j <= str_start[n + 1] - 1; j++)
\r
1500 append_to_name(str_pool[j]);
\r
1502 for (j = str_start[e]; j <= str_start[e + 1] - 1; j++)
\r
1503 append_to_name(str_pool[j]);
\r
1505 if (k < file_name_size)
\r
1508 name_length = file_name_size - 1;
\r
1510 for (k = name_length + 1; k <= file_name_size; k++)
\r
1511 name_of_file[k] = ' ';
\r
1513 name_of_file[file_name_size] = '\0'; /* paranoia */
\r
1516 name_of_file [name_length + 1] = '\0';
\r
1519 printf(" pack_file_name `%s' (%lld) ", name_of_file + 1, name_length);
\r
1521 name_of_file [name_length + 1] = ' ';
\r
1524 /* Called only from two places tex9.c for format name - specified and default */
\r
1525 /* for specified format name args are 0, a, b name in buffer[a] --- buffer[b] */
\r
1526 /* for default args are format_default_length-4, 1, 0 */
\r
1528 void pack_buffered_name_(small_number n, integer a, integer b)
\r
1534 if (n + b - a + 5 > file_name_size)
\r
1535 b = a + file_name_size - n - 5;
\r
1539 for (j = 1; j <= n; j++)
\r
1540 append_to_name(xord[TEX_format_default[j]]);
\r
1542 for (j = a; j <= b; j++)
\r
1543 append_to_name(buffer[j]);
\r
1545 for (j = format_default_length - 3; j <= format_default_length; j++)
\r
1546 append_to_name(xord[TEX_format_default[j]]);
\r
1548 if (k < file_name_size)
\r
1551 name_length = file_name_size - 1;
\r
1553 for (k = name_length + 1; k <= file_name_size; k++)
\r
1554 name_of_file[k]= ' ';
\r
1556 name_of_file[file_name_size] = '\0';
\r
1559 str_number make_name_string (void)
\r
1563 #ifdef ALLOCATESTRING
\r
1564 if (pool_ptr + name_length > current_pool_size)
\r
1565 str_pool = realloc_str_pool(increment_pool_size + name_length);
\r
1567 if (str_ptr == current_max_strings)
\r
1568 str_start = realloc_str_start(increment_max_strings);
\r
1570 if ((pool_ptr + name_length > current_pool_size) || (str_ptr == current_max_strings) || (cur_length > 0))
\r
1572 if ((pool_ptr + name_length > pool_size) || (str_ptr == max_strings) || (cur_length > 0))
\r
1579 for (k = 1; k <= name_length; k++)
\r
1580 append_char(xord[name_of_file[k]]);
\r
1582 return make_string();
\r
1586 //str_number a_make_name_string (alpha_file * f)
\r
1587 str_number a_make_name_string_(void)
\r
1589 return make_name_string();
\r
1592 //str_number b_make_name_string_(byte_file * f)
\r
1593 str_number b_make_name_string_(void)
\r
1595 return make_name_string();
\r
1598 //str_number w_make_name_string_(word_file * f)
\r
1599 str_number w_make_name_string_(void)
\r
1601 return make_name_string();
\r
1604 void scan_file_name (void)
\r
1606 name_in_progress = true;
\r
1613 while (!(cur_cmd != spacer));
\r
1615 quoted_file_name = false;
\r
1617 if (allow_quoted_names)
\r
1619 if (cur_chr == '"')
\r
1621 quoted_file_name = true;
\r
1628 if ((cur_cmd > other_char) || (cur_chr > 255))
\r
1634 if (!more_name(cur_chr))
\r
1642 name_in_progress = false;
\r
1644 /* argument is string .fmt, .log, .pdf, or .dvi */
\r
1646 void pack_job_name_(str_number s)
\r
1648 cur_area = 335; /* "" */
\r
1650 cur_name = job_name;
\r
1651 pack_file_name(cur_name, cur_area, cur_ext);
\r
1654 void prompt_file_name_(const char * s, str_number e)
\r
1658 if (interaction == scroll_mode)
\r
1661 if (!strcmp("input file name", s))
\r
1662 print_err("I can't find file `");
\r
1664 print_err("I can't write on file `");
\r
1666 print_file_name(cur_name, cur_area, cur_ext);
\r
1669 if (e == 785) /* .tex */
\r
1672 print_nl("Please type another ");
\r
1675 if (interaction < scroll_mode)
\r
1677 fatal_error("*** (job aborted, file error in nonstop mode)");
\r
1682 show_line(" (or Ctrl-Z to exit)", 0);
\r
1684 prompt_input(": ");
\r
1690 while ((buffer[k] == ' ') && (k < last))
\r
1693 quoted_file_name = false;
\r
1695 if (allow_quoted_names && k < last) /* check whether quoted name */
\r
1697 if (buffer[k]== '"')
\r
1699 quoted_file_name = true;
\r
1709 /* convert tilde '~' to pseudo tilde */
\r
1710 if (pseudo_tilde != 0 && buffer[k]== '~')
\r
1711 buffer[k] = pseudo_tilde;
\r
1713 /* convert space ' ' to pseudo space */
\r
1714 if (pseudo_space != 0 && buffer[k]== ' ')
\r
1715 buffer[k] = pseudo_space;
\r
1717 if (!more_name(buffer[k]))
\r
1727 if (cur_ext == 335) /* "" */
\r
1728 cur_ext = e; /* use default extension */
\r
1730 pack_file_name(cur_name, cur_area, cur_ext);
\r
1733 void open_log_file (void)
\r
1740 old_setting = selector;
\r
1742 if (job_name == 0)
\r
1743 job_name = get_job_name(790);
\r
1746 pack_job_name(".log");
\r
1748 while (!a_open_out(log_file))
\r
1750 selector = term_only;
\r
1751 prompt_file_name("transcript file name", ".log");
\r
1754 log_name = a_make_name_string(log_file);
\r
1755 selector = log_only;
\r
1756 log_opened = true;
\r
1759 fprintf(log_file, "%s (%s %s)", banner, application, yandyversion);
\r
1761 if (format_ident > 0)
\r
1762 slow_print(format_ident);
\r
1766 if (civilize_flag)
\r
1772 months = " JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
\r
1774 for (k = 3 * month - 2; k <= 3 * month; k++)
\r
1775 putc(months[k], log_file);
\r
1779 if (civilize_flag)
\r
1785 print_two(tex_time / 60);
\r
1787 print_two(tex_time % 60);
\r
1790 input_stack[input_ptr] = cur_input;
\r
1792 l = input_stack[0].limit_field;
\r
1794 if (buffer[l] == end_line_char)
\r
1797 for (k = 1; k <= l; k++)
\r
1802 if (show_fmt_flag)
\r
1804 if (format_file != NULL)
\r
1806 fprintf(log_file, "(%s)\n", format_file);
\r
1807 free(format_file);
\r
1808 format_file = NULL;
\r
1812 selector = old_setting + 2;
\r
1815 void start_input (void)
\r
1818 pack_file_name(cur_name, cur_area, cur_ext);
\r
1822 begin_file_reading();
\r
1824 if (a_open_in(cur_file, kpse_tex_format))
\r
1827 end_file_reading();
\r
1828 prompt_file_name("input file name", ".tex");
\r
1832 name = a_make_name_string(cur_file);
\r
1834 if (job_name == 0)
\r
1836 job_name = get_job_name(cur_name);
\r
1837 //job_name = cur_name;
\r
1841 if (term_offset + length(name) > max_print_line - 2)
\r
1843 else if ((term_offset > 0) || (file_offset > 0))
\r
1847 incr(open_parens);
\r
1849 if (open_parens > max_open_parens)
\r
1850 max_open_parens = open_parens;
\r
1853 update_terminal();
\r
1859 if (input_ln(cur_file, false))
\r
1862 firm_up_the_line();
\r
1864 if (end_line_char_inactive())
\r
1867 buffer[limit] = end_line_char;
\r
1869 first = limit + 1;
\r
1874 internal_font_number read_font_info (pointer u, str_number nom, str_number aire, scaled s)
\r
1877 boolean file_opened;
\r
1878 halfword lf, lh, nw, nh, nd, ni, nl, nk, ne, np;
\r
1880 internal_font_number f;
\r
1881 internal_font_number g;
\r
1882 eight_bits a, b, c, d;
\r
1885 integer bch_label;
\r
1892 file_opened = false;
\r
1893 pack_file_name(nom, aire, 805); /* .tfm */
\r
1895 if (!b_open_in(tfm_file))
\r
1898 file_opened = true;
\r
1909 if ((bc > ec + 1) || (ec > 255))
\r
1935 if (lf != 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np)
\r
1938 if ((nw == 0) || (nh == 0) || (nd == 0) || (ni == 0))
\r
1947 #ifdef ALLOCATEFONT
\r
1948 if ((fmem_ptr + lf > current_font_mem_size))
\r
1949 font_info = realloc_font_info (increment_font_mem_size + lf);
\r
1951 if ((font_ptr == font_max) || (fmem_ptr + lf > current_font_mem_size))
\r
1953 if ((font_ptr == font_max) || (fmem_ptr + lf > font_mem_size))
\r
1957 printf("font_ptr %lld font_max %d fmem_ptr %lld lf %d font_mem_size %ld\n",
\r
1958 font_ptr, font_max, fmem_ptr, lf, font_mem_size);
\r
1960 start_font_error_message();
\r
1961 prints(" not loaded: Not enough room left");
\r
1962 help4("I'm afraid I won't be able to make use of this font,",
\r
1963 "because my memory for character-size data is too small.",
\r
1964 "If you're really stuck, ask a wizard to enlarge me.",
\r
1965 "Or maybe try `I\\font<same font id>=<name of loaded font>'.");
\r
1971 char_base[f] = fmem_ptr - bc;
\r
1972 width_base[f] = char_base[f] + ec + 1;
\r
1973 height_base[f] = width_base[f] + nw;
\r
1974 depth_base[f] = height_base[f] + nh;
\r
1975 italic_base[f] = depth_base[f] + nd;
\r
1976 lig_kern_base[f] = italic_base[f] + ni;
\r
1977 kern_base[f] = lig_kern_base[f] + nl - kern_base_offset;
\r
1978 exten_base[f] = kern_base[f] + kern_base_offset + nk;
\r
1979 param_base[f] = exten_base[f] + ne;
\r
1985 store_four_quarters(font_check[f]);
\r
1989 z = z * 256 + fbyte;
\r
1991 z = (z * 16) + (fbyte / 16);
\r
2005 font_dsize[f] = z;
\r
2011 z = xn_over_d(z, - (integer) s, 1000);
\r
2016 for (k = fmem_ptr; k <= width_base[f] - 1; k++)
\r
2018 store_four_quarters(font_info[k].qqqq);
\r
2020 if ((a >= nw) || (b / 16 >= nh) || (b % 16 >= nd) || (c / 4 >= ni))
\r
2037 check_byte_range(d);
\r
2039 while (d < k + bc - fmem_ptr)
\r
2041 qw = char_info(f, d);
\r
2043 if (char_tag(qw) != list_tag)
\r
2049 if (d == k + bc - fmem_ptr)
\r
2064 while (z >= 8388608L) /* 2^23 */
\r
2067 alpha = alpha + alpha;
\r
2070 beta = (char) (256 / alpha);
\r
2071 alpha = alpha * z;
\r
2074 for (k = width_base[f]; k <= lig_kern_base[f] - 1; k++)
\r
2075 store_scaled(font_info[k].cint);
\r
2077 if (font_info[width_base[f]].cint != 0)
\r
2080 if (font_info[height_base[f]].cint != 0)
\r
2083 if (font_info[depth_base[f]].cint != 0)
\r
2086 if (font_info[italic_base[f]].cint != 0)
\r
2090 bch_label = 32767; /* '77777 */
\r
2095 for (k = lig_kern_base[f]; k <= kern_base[f] + kern_base_offset - 1; k++)
\r
2097 store_four_quarters(font_info[k].qqqq);
\r
2101 if (256 * c + d >= nl)
\r
2105 if (k == lig_kern_base[f])
\r
2111 check_existence(b);
\r
2114 check_existence(d);
\r
2115 else if (256 * (c - 128) + d >= nk)
\r
2119 if (k - lig_kern_base[f] + a + 1 >= nl)
\r
2125 bch_label = 256 * c + d;
\r
2128 for (k = kern_base[f] + kern_base_offset; k <= exten_base[f] - 1; k++)
\r
2129 store_scaled(font_info[k].cint);
\r
2131 for (k = exten_base[f]; k <= param_base[f] - 1; k++)
\r
2133 store_four_quarters(font_info[k].qqqq);
\r
2136 check_existence(a);
\r
2139 check_existence(b);
\r
2142 check_existence(c);
\r
2144 check_existence(d);
\r
2148 for (k = 1; k <= np; k++)
\r
2158 sw = sw * 256 + fbyte;
\r
2160 sw = sw * 256 + fbyte;
\r
2162 font_info[param_base[f]].cint = (sw * 16) + (fbyte / 16);
\r
2165 store_scaled(font_info[param_base[f] + k - 1].cint);
\r
2167 if (feof(tfm_file))
\r
2170 for (k = np + 1; k <= 7; k++)
\r
2171 font_info[param_base[f] + k - 1].cint = 0;
\r
2175 font_params[f] = np;
\r
2177 font_params[f] = 7;
\r
2179 hyphen_char[f] = default_hyphen_char;
\r
2180 skew_char[f] = default_skew_char;
\r
2182 if (bch_label < nl)
\r
2183 bchar_label[f] = bch_label + lig_kern_base[f];
\r
2185 bchar_label[f] = non_address;
\r
2187 font_bchar[f] = bchar;
\r
2188 font_false_bchar[f] = bchar;
\r
2193 qw = char_info(f, bchar);
\r
2195 if (char_exists(qw))
\r
2196 font_false_bchar[f] = 256;
\r
2199 font_name[f] = nom;
\r
2200 font_area[f] = aire;
\r
2204 adjust(char_base);
\r
2205 adjust(width_base);
\r
2206 adjust(lig_kern_base);
\r
2207 adjust(kern_base);
\r
2208 adjust(exten_base);
\r
2209 decr(param_base[f]);
\r
2210 fmem_ptr = fmem_ptr + lf;
\r
2216 start_font_error_message();
\r
2219 prints(" not loadable: Bad metric (TFM) file");
\r
2221 prints(" not loadable: Metric (TFM) file not found");
\r
2223 help5("I wasn't able to read the size data for this font,",
\r
2224 "so I will ignore the font specification.",
\r
2225 "[Wizards can fix TFM files using TFtoPL/PLtoTF.]",
\r
2226 "You might try inserting a different font spec;",
\r
2227 "e.g., type `I\\font<same font id>=<substitute font name>'.");
\r
2232 b_close(tfm_file);
\r