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
21 #include "yandytex.h"
\r
24 void scan_int (void)
\r
42 while (!(cur_cmd != spacer));
\r
44 if (cur_tok == other_token + '-')
\r
46 negative = !negative;
\r
47 cur_tok = other_token + '+';
\r
50 while (!(cur_tok != other_token + '+'));
\r
52 if (cur_tok == alpha_token)
\r
56 if (cur_tok < cs_token_flag)
\r
60 if (cur_cmd <= right_brace)
\r
61 if (cur_cmd == right_brace)
\r
66 else if (cur_tok < cs_token_flag + single_base)
\r
67 cur_val = cur_tok - cs_token_flag - active_base;
\r
69 cur_val = cur_tok - cs_token_flag - single_base;
\r
73 print_err("Improper alphabetic constant");
\r
74 help2("A one-character control sequence belongs after a ` mark.",
\r
75 "So I'm essentially inserting \\0 here.");
\r
83 if (cur_cmd != spacer)
\r
87 else if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))
\r
89 scan_something_internal(int_val, false);
\r
94 m = 214748364L; /* 7FFFFFFF hex */
\r
96 if (cur_tok == octal_token)
\r
99 m = 268435456L; /* 2^28 */
\r
102 else if (cur_tok == hex_token)
\r
105 m = 134217728L; /* 2^27 8000000 hex */
\r
114 if ((cur_tok < zero_token + radix) && (cur_tok >= zero_token) && (cur_tok <= zero_token + 9))
\r
115 d = cur_tok - zero_token;
\r
116 else if (radix == 16)
\r
117 if ((cur_tok <= A_token + 5) && (cur_tok >= A_token))
\r
118 d = cur_tok - A_token + 10;
\r
119 else if ((cur_tok <= other_A_token + 5) && (cur_tok >= other_A_token))
\r
120 d = cur_tok - other_A_token;
\r
128 if ((cur_val >= m) && ((cur_val > m) || (d > 7) || (radix != 10)))
\r
132 print_err("Number too big");
\r
133 help2("I can only go up to 2147483647='17777777777=\"7FFFFFFF,",
\r
134 "so I'm using that number instead of yours.");
\r
136 cur_val = 2147483647L; /* 7FFFFFFF hex */
\r
141 cur_val = cur_val * radix + d;
\r
149 print_err("Missing number, treated as zero");
\r
150 help3("A number should have been here; I inserted `0'.",
\r
151 "(If you can't figure out why I needed to see a number,",
\r
152 "look up `weird error' in the index to The TeXbook.)");
\r
155 else if (cur_cmd != spacer)
\r
160 cur_val = - (integer) cur_val;
\r
163 void scan_dimen (boolean mu, boolean inf, boolean shortcut)
\r
167 integer num, denom;
\r
168 small_number k, kk;
\r
171 integer save_cur_val;
\r
174 arith_error = false;
\r
175 cur_order = normal;
\r
188 while (!(cur_cmd != spacer));
\r
190 if (cur_tok == other_token + '-')
\r
192 negative = ! negative;
\r
193 cur_tok = other_token + '+';
\r
196 while (!(cur_tok != other_token + '+'));
\r
198 if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))
\r
202 scan_something_internal(mu_val, false);
\r
204 if (cur_val_level >= glue_val)
\r
206 v = width(cur_val);
\r
207 delete_glue_ref(cur_val);
\r
211 if (cur_val_level == mu_val)
\r
214 if (cur_val_level != int_val)
\r
219 scan_something_internal(dimen_val, false);
\r
221 if (cur_val_level == dimen_val)
\r
229 if (cur_tok == continental_point_token)
\r
230 cur_tok = point_token;
\r
232 if (cur_tok != point_token)
\r
242 if (cur_tok == continental_point_token)
\r
243 cur_tok = point_token;
\r
245 if ((radix == 10) && (cur_tok == point_token))
\r
255 if ((cur_tok > zero_token + 9) || (cur_tok < zero_token))
\r
262 info(q) = cur_tok - zero_token;
\r
269 for (kk = k; kk >= 1; kk--)
\r
271 dig[kk - 1] = info(p);
\r
277 f = round_decimals(k);
\r
279 if (cur_cmd != spacer)
\r
287 negative = !negative;
\r
288 cur_val = - (integer) cur_val;
\r
293 if (scan_keyword("fil"))
\r
297 while (scan_keyword("l"))
\r
299 if (cur_order == filll)
\r
301 print_err("Illegal unit of measure (");
\r
302 prints("replaced by filll)");
\r
303 help1("I dddon't go any higher than filll.");
\r
310 goto attach_fraction;
\r
314 save_cur_val = cur_val;
\r
320 while (!(cur_cmd != spacer));
\r
322 if ((cur_cmd < min_internal) || (cur_cmd > max_internal))
\r
328 scan_something_internal(mu_val, false);
\r
330 if (cur_val_level >= glue_val)
\r
332 v = width(cur_val);
\r
333 delete_glue_ref(cur_val);
\r
337 if (cur_val_level != mu_val)
\r
344 scan_something_internal(dimen_val, false);
\r
354 if (scan_keyword("em"))
\r
355 v = quad(cur_font);
\r
356 else if (scan_keyword("ex"))
\r
357 v = x_height(cur_font);
\r
364 if (cur_cmd != spacer)
\r
369 cur_val = nx_plus_y(save_cur_val, v, xn_over_d(v, f, 65536L));
\r
375 if (scan_keyword("mu"))
\r
376 goto attach_fraction;
\r
379 print_err("Illegal unit of measure (");
\r
380 prints("mu inserted)");
\r
381 help4("The unit of measurement in math glue must be mu.",
\r
382 "To recover gracefully from this error, it's best to",
\r
383 "delete the erroneous units; e.g., type `2' to delete",
\r
384 "two letters. (See Chapter 27 of The TeXbook.)");
\r
386 goto attach_fraction;
\r
390 if (scan_keyword("true"))
\r
396 cur_val = xn_over_d(cur_val, 1000, mag);
\r
397 f = (1000 * f + 65536L * tex_remainder) / mag;
\r
398 cur_val = cur_val + (f / 65536L);
\r
403 if (scan_keyword("pt"))
\r
404 goto attach_fraction;
\r
406 if (scan_keyword("in"))
\r
407 set_conversion(7227, 100);
\r
408 else if (scan_keyword("pc"))
\r
409 set_conversion(12, 1);
\r
410 else if (scan_keyword("cm"))
\r
411 set_conversion(7227, 254);
\r
412 else if (scan_keyword("mm"))
\r
413 set_conversion(7227, 2540);
\r
414 else if (scan_keyword("bp"))
\r
415 set_conversion(7227, 7200);
\r
416 else if (scan_keyword("dd"))
\r
417 set_conversion(1238, 1157);
\r
418 else if (scan_keyword("cc"))
\r
419 set_conversion(14856, 1157);
\r
420 else if (scan_keyword("Q"))
\r
421 set_conversion(7227, 10160);
\r
422 else if (scan_keyword("H"))
\r
423 set_conversion(7227, 10160);
\r
424 else if (scan_keyword("twip"))
\r
425 set_conversion(1, 20);
\r
426 else if (scan_keyword("sp"))
\r
430 print_err("Illegal unit of measure (");
\r
431 prints("pt inserted)");
\r
432 help6("Dimensions can be in units of em, ex, in, pt, pc,",
\r
433 "cm, mm, dd, cc, bp, or sp; but yours is a new one!",
\r
434 "I'll assume that you meant to say pt, for printer's points.",
\r
435 "To recover gracefully from this error, it's best to",
\r
436 "delete the erroneous units; e.g., type `2' to delete",
\r
437 "two letters. (See Chapter 27 of The TeXbook.)");
\r
442 cur_val = xn_over_d(cur_val, num, denom);
\r
443 f = (num * f + 65536L * tex_remainder) / denom;
\r
444 cur_val = cur_val + (f / 65536L);
\r
449 if (cur_val >= 16384) /* 2^14 */
\r
450 arith_error = true;
\r
452 cur_val = cur_val * unity + f;
\r
458 if (cur_cmd != spacer)
\r
463 if (arith_error || (abs(cur_val) >= 1073741824L)) /* 2^30 */
\r
465 print_err("Dimension too large");
\r
466 help2("I can't work with sizes bigger than about 19 feet.",
\r
467 "Continue and I'll use the largest value I can.");
\r
469 cur_val = max_dimen;
\r
470 arith_error = false;
\r
474 cur_val = - (integer) cur_val;
\r
477 void scan_glue (small_number level)
\r
483 mu = (level == mu_val);
\r
492 while (!(cur_cmd != spacer));
\r
494 if (cur_tok == other_token + '-')
\r
496 negative = !negative;
\r
497 cur_tok = other_token + '+';
\r
500 while (!(cur_tok != other_token + '+'));
\r
502 if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))
\r
504 scan_something_internal(level, negative);
\r
506 if (cur_val_level >= glue_val)
\r
508 if (cur_val_level != level)
\r
514 if (cur_val_level == int_val)
\r
515 scan_dimen(mu, false, true);
\r
516 else if (level == mu_val)
\r
522 scan_dimen(mu, false, false);
\r
525 cur_val = - (integer) cur_val;
\r
528 q = new_spec(zero_glue);
\r
529 width(q) = cur_val;
\r
531 if (scan_keyword("plus"))
\r
533 scan_dimen(mu, true, false);
\r
534 stretch(q) = cur_val;
\r
535 stretch_order(q) = cur_order;
\r
538 if (scan_keyword("minus"))
\r
540 scan_dimen(mu, true, false);
\r
541 shrink(q) = cur_val;
\r
542 shrink_order(q) = cur_order;
\r
548 pointer scan_rule_spec (void)
\r
554 if (cur_cmd == vrule)
\r
555 width(q) = default_rule;
\r
558 height(q) = default_rule;
\r
564 if (scan_keyword("width"))
\r
566 scan_dimen(false, false, false);
\r
567 width(q) = cur_val;
\r
571 if (scan_keyword("height"))
\r
573 scan_dimen(false, false, false);
\r
574 height(q) = cur_val;
\r
578 if (scan_keyword("depth"))
\r
580 scan_dimen(false, false, false);
\r
581 depth(q) = cur_val;
\r
588 pointer str_toks (pool_pointer b)
\r
600 while (k < pool_ptr)
\r
607 t = other_token + t;
\r
609 fast_store_new_token(t);
\r
618 pointer the_toks (void)
\r
625 scan_something_internal(tok_val, false);
\r
627 if (cur_val_level >= ident_val)
\r
632 if (cur_val_level == ident_val)
\r
633 store_new_token(cs_token_flag + cur_val);
\r
634 else if (cur_val != 0)
\r
640 fast_store_new_token(info(r));
\r
649 old_setting = selector;
\r
650 selector = new_string;
\r
653 switch (cur_val_level)
\r
656 print_int(cur_val);
\r
661 print_scaled(cur_val);
\r
668 print_spec(cur_val, "pt");
\r
669 delete_glue_ref(cur_val);
\r
675 print_spec(cur_val, "mu");
\r
676 delete_glue_ref(cur_val);
\r
681 selector = old_setting;
\r
682 return str_toks(b);
\r
686 void ins_the_toks (void)
\r
688 link(garbage) = the_toks();
\r
689 ins_list(link(temp_head));
\r
692 void conv_toks (void)
\r
696 small_number save_scanner_status;
\r
704 case roman_numeral_code:
\r
710 save_scanner_status = scanner_status;
\r
711 scanner_status = 0;
\r
713 scanner_status = save_scanner_status;
\r
716 case font_name_code:
\r
720 case job_name_code:
\r
726 old_setting = selector;
\r
727 selector = new_string;
\r
733 print_int(cur_val);
\r
736 case roman_numeral_code:
\r
737 print_roman_int(cur_val);
\r
744 print_char(cur_chr);
\r
751 case font_name_code:
\r
752 print(font_name[cur_val]);
\r
754 if (font_size[cur_val] != font_dsize[cur_val])
\r
757 print_scaled(font_size[cur_val]);
\r
762 case job_name_code:
\r
767 selector = old_setting;
\r
768 link(garbage) = str_toks(b);
\r
769 begin_token_list(link(temp_head), 4);
\r
772 pointer scan_toks (boolean macro_def, boolean xpand)
\r
778 halfword unbalance;
\r
779 halfword hash_brace;
\r
782 scanner_status = defining;
\r
784 scanner_status = absorbing;
\r
786 warning_index = cur_cs;
\r
787 def_ref = get_avail();
\r
788 token_ref_count(def_ref) = 0;
\r
799 if (cur_tok < right_brace_limit)
\r
802 if (cur_cmd == mac_param)
\r
804 s = match_token + cur_chr;
\r
807 if (cur_cmd == left_brace)
\r
809 hash_brace = cur_tok;
\r
810 store_new_token(cur_tok);
\r
811 store_new_token(end_match_token);
\r
815 if (t == zero_token + 9)
\r
817 print_err("You already have nine parameters");
\r
818 help1("I'm going to ignore the # sign you just used.");
\r
827 print_err("Parameters must be numbered consecutively");
\r
828 help2("I've inserted the digit you should have used after the #.",
\r
829 "Type `1' to delete what you did use.");
\r
837 store_new_token(cur_tok);
\r
841 store_new_token(end_match_token);
\r
843 if (cur_cmd == right_brace)
\r
845 print_err("Missing { inserted");
\r
847 help2("Where was the left brace? You said something like `\\def\\a}',",
\r
848 "which I'm going to interpret as `\\def\\a{}'.");
\r
869 if (cur_cmd <= max_command)
\r
872 if (cur_cmd != the)
\r
880 if (link(temp_head) != 0)
\r
882 link(p) = link(temp_head);
\r
893 if (cur_tok < right_brace_limit)
\r
894 if (cur_cmd < right_brace)
\r
900 if (unbalance == 0)
\r
903 else if (cur_cmd == mac_param)
\r
913 if (cur_cmd != mac_param)
\r
914 if ((cur_tok <= zero_token) || (cur_tok > t))
\r
916 print_err("Illegal parameter number in definition of ");
\r
917 sprint_cs(warning_index);
\r
918 help3("You meant to type ## instead of #, right?",
\r
919 "Or maybe a } was forgotten somewhere earlier, and things",
\r
920 "are all screwed up? I'm going to assume that you meant ##.");
\r
925 cur_tok = out_param_token - '0' + cur_chr;
\r
928 store_new_token(cur_tok);
\r
932 scanner_status = 0;
\r
934 if (hash_brace != 0)
\r
935 store_new_token(hash_brace);
\r
940 void read_toks (integer n, pointer r)
\r
945 /* small_number m; */
\r
948 scanner_status = defining;
\r
950 def_ref = get_avail();
\r
951 token_ref_count(def_ref) = 0;
\r
953 store_new_token(end_match_token);
\r
955 if ((n < 0) || (n > 15))
\r
961 align_state = 1000000L;
\r
965 begin_file_reading();
\r
968 if (read_open[m] == closed)
\r
969 if (interaction > nonstop_mode)
\r
974 wake_up_terminal();
\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';
\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
1525 void pack_buffered_name_(small_number n, integer a, integer b)
\r
1531 if (n + b - a + 5 > file_name_size)
\r
1532 b = a + file_name_size - n - 5;
\r
1536 for (j = 1; j <= n; j++)
\r
1537 append_to_name(xord[TEX_format_default[j]]);
\r
1539 for (j = a; j <= b; j++)
\r
1540 append_to_name(buffer[j]);
\r
1542 for (j = format_default_length - 3; j <= format_default_length; j++)
\r
1543 append_to_name(xord[TEX_format_default[j]]);
\r
1545 if (k < file_name_size)
\r
1548 name_length = file_name_size - 1;
\r
1550 for (k = name_length + 1; k <= file_name_size; k++)
\r
1551 name_of_file[k]= ' ';
\r
1553 name_of_file[file_name_size] = '\0';
\r
1556 str_number make_name_string (void)
\r
1560 #ifdef ALLOCATESTRING
\r
1561 if (pool_ptr + name_length > current_pool_size)
\r
1562 str_pool = realloc_str_pool(increment_pool_size + name_length);
\r
1564 if (str_ptr == current_max_strings)
\r
1565 str_start = realloc_str_start(increment_max_strings);
\r
1567 if ((pool_ptr + name_length > current_pool_size) || (str_ptr == current_max_strings) || (cur_length > 0))
\r
1569 if ((pool_ptr + name_length > pool_size) || (str_ptr == max_strings) || (cur_length > 0))
\r
1576 for (k = 1; k <= name_length; k++)
\r
1577 append_char(xord[name_of_file[k]]);
\r
1579 return make_string();
\r
1583 //str_number a_make_name_string (alpha_file * f)
\r
1584 str_number a_make_name_string_(void)
\r
1586 return make_name_string();
\r
1589 //str_number b_make_name_string_(byte_file * f)
\r
1590 str_number b_make_name_string_(void)
\r
1592 return make_name_string();
\r
1595 //str_number w_make_name_string_(word_file * f)
\r
1596 str_number w_make_name_string_(void)
\r
1598 return make_name_string();
\r
1601 void scan_file_name (void)
\r
1603 name_in_progress = true;
\r
1610 while (!(cur_cmd != spacer));
\r
1612 quoted_file_name = false;
\r
1614 if (allow_quoted_names)
\r
1616 if (cur_chr == '"')
\r
1618 quoted_file_name = true;
\r
1625 if ((cur_cmd > other_char) || (cur_chr > 255))
\r
1631 if (!more_name(cur_chr))
\r
1639 name_in_progress = false;
\r
1641 /* argument is string .fmt, .log, .pdf, or .dvi */
\r
1643 void pack_job_name_(str_number s)
\r
1645 cur_area = 335; /* "" */
\r
1647 cur_name = job_name;
\r
1648 pack_file_name(cur_name, cur_area, cur_ext);
\r
1651 void prompt_file_name_(const char * s, str_number e)
\r
1655 if (interaction == scroll_mode)
\r
1656 wake_up_terminal();
\r
1658 if (!strcmp("input file name", s))
\r
1659 print_err("I can't find file `");
\r
1661 print_err("I can't write on file `");
\r
1663 print_file_name(cur_name, cur_area, cur_ext);
\r
1666 if (e == 785) /* .tex */
\r
1669 print_nl("Please type another ");
\r
1672 if (interaction < scroll_mode)
\r
1674 fatal_error("*** (job aborted, file error in nonstop mode)");
\r
1679 show_line(" (or Ctrl-Z to exit)", 0);
\r
1681 prompt_input(": ");
\r
1687 while ((buffer[k] == ' ') && (k < last))
\r
1690 quoted_file_name = false;
\r
1692 if (allow_quoted_names && k < last) /* check whether quoted name */
\r
1694 if (buffer[k]== '"')
\r
1696 quoted_file_name = true;
\r
1706 /* convert tilde '~' to pseudo tilde */
\r
1707 if (pseudo_tilde != 0 && buffer[k]== '~')
\r
1708 buffer[k] = pseudo_tilde;
\r
1710 /* convert space ' ' to pseudo space */
\r
1711 if (pseudo_space != 0 && buffer[k]== ' ')
\r
1712 buffer[k] = pseudo_space;
\r
1714 if (!more_name(buffer[k]))
\r
1724 if (cur_ext == 335) /* "" */
\r
1725 cur_ext = e; /* use default extension */
\r
1727 pack_file_name(cur_name, cur_area, cur_ext);
\r
1730 void open_log_file (void)
\r
1737 old_setting = selector;
\r
1739 if (job_name == 0)
\r
1740 job_name = get_job_name(790);
\r
1743 pack_job_name(".log");
\r
1745 while (!a_open_out(log_file))
\r
1747 selector = term_only;
\r
1748 prompt_file_name("transcript file name", ".log");
\r
1751 log_name = a_make_name_string(log_file);
\r
1752 selector = log_only;
\r
1753 log_opened = true;
\r
1756 log_printf("%s (%s %s)", banner, application, yandyversion);
\r
1758 if (format_ident > 0)
\r
1759 slow_print(format_ident);
\r
1763 if (civilize_flag)
\r
1769 months = " JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
\r
1771 for (k = 3 * month - 2; k <= 3 * month; k++)
\r
1772 putc(months[k], log_file);
\r
1776 if (civilize_flag)
\r
1782 print_two(tex_time / 60);
\r
1784 print_two(tex_time % 60);
\r
1787 input_stack[input_ptr] = cur_input;
\r
1789 l = input_stack[0].limit_field;
\r
1791 if (buffer[l] == end_line_char)
\r
1794 for (k = 1; k <= l; k++)
\r
1799 if (show_fmt_flag)
\r
1801 if (format_file != NULL)
\r
1803 log_printf("(%s)\n", format_file);
\r
1804 free(format_file);
\r
1805 format_file = NULL;
\r
1809 selector = old_setting + 2;
\r
1812 void start_input (void)
\r
1815 pack_file_name(cur_name, cur_area, cur_ext);
\r
1819 begin_file_reading();
\r
1821 if (a_open_in(cur_file, kpse_tex_format))
\r
1824 end_file_reading();
\r
1825 prompt_file_name("input file name", ".tex");
\r
1829 name = a_make_name_string(cur_file);
\r
1831 if (job_name == 0)
\r
1833 job_name = get_job_name(cur_name);
\r
1834 //job_name = cur_name;
\r
1838 if (term_offset + length(name) > max_print_line - 2)
\r
1840 else if ((term_offset > 0) || (file_offset > 0))
\r
1844 incr(open_parens);
\r
1846 if (open_parens > max_open_parens)
\r
1847 max_open_parens = open_parens;
\r
1850 update_terminal();
\r
1856 if (input_ln(cur_file, false))
\r
1859 firm_up_the_line();
\r
1861 if (end_line_char_inactive())
\r
1864 buffer[limit] = end_line_char;
\r
1866 first = limit + 1;
\r
1871 internal_font_number read_font_info (pointer u, str_number nom, str_number aire, scaled s)
\r
1874 boolean file_opened;
\r
1875 halfword lf, lh, nw, nh, nd, ni, nl, nk, ne, np;
\r
1877 internal_font_number f;
\r
1878 internal_font_number g;
\r
1879 eight_bits a, b, c, d;
\r
1882 integer bch_label;
\r
1889 file_opened = false;
\r
1890 pack_file_name(nom, aire, 805); /* .tfm */
\r
1892 if (!b_open_in(tfm_file))
\r
1895 file_opened = true;
\r
1906 if ((bc > ec + 1) || (ec > 255))
\r
1932 if (lf != 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np)
\r
1935 if ((nw == 0) || (nh == 0) || (nd == 0) || (ni == 0))
\r
1944 #ifdef ALLOCATEFONT
\r
1945 if ((fmem_ptr + lf > current_font_mem_size))
\r
1946 font_info = realloc_font_info (increment_font_mem_size + lf);
\r
1948 if ((font_ptr == font_max) || (fmem_ptr + lf > current_font_mem_size))
\r
1950 if ((font_ptr == font_max) || (fmem_ptr + lf > font_mem_size))
\r
1954 printf("font_ptr %lld font_max %d fmem_ptr %lld lf %d font_mem_size %ld\n",
\r
1955 font_ptr, font_max, fmem_ptr, lf, font_mem_size);
\r
1957 start_font_error_message();
\r
1958 prints(" not loaded: Not enough room left");
\r
1959 help4("I'm afraid I won't be able to make use of this font,",
\r
1960 "because my memory for character-size data is too small.",
\r
1961 "If you're really stuck, ask a wizard to enlarge me.",
\r
1962 "Or maybe try `I\\font<same font id>=<name of loaded font>'.");
\r
1968 char_base[f] = fmem_ptr - bc;
\r
1969 width_base[f] = char_base[f] + ec + 1;
\r
1970 height_base[f] = width_base[f] + nw;
\r
1971 depth_base[f] = height_base[f] + nh;
\r
1972 italic_base[f] = depth_base[f] + nd;
\r
1973 lig_kern_base[f] = italic_base[f] + ni;
\r
1974 kern_base[f] = lig_kern_base[f] + nl - kern_base_offset;
\r
1975 exten_base[f] = kern_base[f] + kern_base_offset + nk;
\r
1976 param_base[f] = exten_base[f] + ne;
\r
1982 store_four_quarters(font_check[f]);
\r
1986 z = z * 256 + fbyte;
\r
1988 z = (z * 16) + (fbyte / 16);
\r
2002 font_dsize[f] = z;
\r
2008 z = xn_over_d(z, - (integer) s, 1000);
\r
2013 for (k = fmem_ptr; k <= width_base[f] - 1; k++)
\r
2015 store_four_quarters(font_info[k].qqqq);
\r
2017 if ((a >= nw) || (b / 16 >= nh) || (b % 16 >= nd) || (c / 4 >= ni))
\r
2034 check_byte_range(d);
\r
2036 while (d < k + bc - fmem_ptr)
\r
2038 qw = char_info(f, d);
\r
2040 if (char_tag(qw) != list_tag)
\r
2046 if (d == k + bc - fmem_ptr)
\r
2061 while (z >= 8388608L) /* 2^23 */
\r
2064 alpha = alpha + alpha;
\r
2067 beta = (char) (256 / alpha);
\r
2068 alpha = alpha * z;
\r
2071 for (k = width_base[f]; k <= lig_kern_base[f] - 1; k++)
\r
2072 store_scaled(font_info[k].cint);
\r
2074 if (font_info[width_base[f]].cint != 0)
\r
2077 if (font_info[height_base[f]].cint != 0)
\r
2080 if (font_info[depth_base[f]].cint != 0)
\r
2083 if (font_info[italic_base[f]].cint != 0)
\r
2087 bch_label = 32767; /* '77777 */
\r
2092 for (k = lig_kern_base[f]; k <= kern_base[f] + kern_base_offset - 1; k++)
\r
2094 store_four_quarters(font_info[k].qqqq);
\r
2098 if (256 * c + d >= nl)
\r
2102 if (k == lig_kern_base[f])
\r
2108 check_existence(b);
\r
2111 check_existence(d);
\r
2112 else if (256 * (c - 128) + d >= nk)
\r
2116 if (k - lig_kern_base[f] + a + 1 >= nl)
\r
2122 bch_label = 256 * c + d;
\r
2125 for (k = kern_base[f] + kern_base_offset; k <= exten_base[f] - 1; k++)
\r
2126 store_scaled(font_info[k].cint);
\r
2128 for (k = exten_base[f]; k <= param_base[f] - 1; k++)
\r
2130 store_four_quarters(font_info[k].qqqq);
\r
2133 check_existence(a);
\r
2136 check_existence(b);
\r
2139 check_existence(c);
\r
2141 check_existence(d);
\r
2145 for (k = 1; k <= np; k++)
\r
2155 sw = sw * 256 + fbyte;
\r
2157 sw = sw * 256 + fbyte;
\r
2159 font_info[param_base[f]].cint = (sw * 16) + (fbyte / 16);
\r
2162 store_scaled(font_info[param_base[f] + k - 1].cint);
\r
2164 if (feof(tfm_file))
\r
2167 for (k = np + 1; k <= 7; k++)
\r
2168 font_info[param_base[f] + k - 1].cint = 0;
\r
2172 font_params[f] = np;
\r
2174 font_params[f] = 7;
\r
2176 hyphen_char[f] = default_hyphen_char;
\r
2177 skew_char[f] = default_skew_char;
\r
2179 if (bch_label < nl)
\r
2180 bchar_label[f] = bch_label + lig_kern_base[f];
\r
2182 bchar_label[f] = non_address;
\r
2184 font_bchar[f] = bchar;
\r
2185 font_false_bchar[f] = bchar;
\r
2190 qw = char_info(f, bchar);
\r
2192 if (char_exists(qw))
\r
2193 font_false_bchar[f] = 256;
\r
2196 font_name[f] = nom;
\r
2197 font_area[f] = aire;
\r
2201 adjust(char_base);
\r
2202 adjust(width_base);
\r
2203 adjust(lig_kern_base);
\r
2204 adjust(kern_base);
\r
2205 adjust(exten_base);
\r
2206 decr(param_base[f]);
\r
2207 fmem_ptr = fmem_ptr + lf;
\r
2213 start_font_error_message();
\r
2216 prints(" not loadable: Bad metric (TFM) file");
\r
2218 prints(" not loadable: Metric (TFM) file not found");
\r
2220 help5("I wasn't able to read the size data for this font,",
\r
2221 "so I will ignore the font specification.",
\r
2222 "[Wizards can fix TFM files using TFtoPL/PLtoTF.]",
\r
2223 "You might try inserting a different font spec;",
\r
2224 "e.g., type `I\\font<same font id>=<substitute font name>'.");
\r
2229 b_close(tfm_file);
\r