1 /* Copyright 2014 Clerk Ma
\r
3 This program is free software; you can redistribute it and/or modify
\r
4 it under the terms of the GNU General Public License as published by
\r
5 the Free Software Foundation; either version 2 of the License, or
\r
6 (at your option) any later version.
\r
8 This program is distributed in the hope that it will be useful, but
\r
9 WITHOUT ANY WARRANTY; without even the implied warranty of
\r
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
11 General Public License for more details.
\r
13 You should have received a copy of the GNU General Public License
\r
14 along with this program; if not, write to the Free Software
\r
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
\r
18 #define EXTERN extern
\r
20 #include "yandytex.h"
\r
23 void scan_int (void)
\r
41 while (!(cur_cmd != spacer));
\r
43 if (cur_tok == other_token + '-')
\r
45 negative = !negative;
\r
46 cur_tok = other_token + '+';
\r
49 while (!(cur_tok != other_token + '+'));
\r
51 if (cur_tok == alpha_token)
\r
55 if (cur_tok < cs_token_flag)
\r
59 if (cur_cmd <= right_brace)
\r
60 if (cur_cmd == right_brace)
\r
65 else if (cur_tok < cs_token_flag + single_base)
\r
66 cur_val = cur_tok - cs_token_flag - active_base;
\r
68 cur_val = cur_tok - cs_token_flag - single_base;
\r
72 print_err("Improper alphabetic constant");
\r
73 help2("A one-character control sequence belongs after a ` mark.",
\r
74 "So I'm essentially inserting \\0 here.");
\r
82 if (cur_cmd != spacer)
\r
86 else if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))
\r
88 scan_something_internal(int_val, false);
\r
93 m = 214748364L; /* 7FFFFFFF hex */
\r
95 if (cur_tok == octal_token)
\r
98 m = 268435456L; /* 2^28 */
\r
101 else if (cur_tok == hex_token)
\r
104 m = 134217728L; /* 2^27 8000000 hex */
\r
113 if ((cur_tok < zero_token + radix) && (cur_tok >= zero_token) && (cur_tok <= zero_token + 9))
\r
114 d = cur_tok - zero_token;
\r
115 else if (radix == 16)
\r
116 if ((cur_tok <= A_token + 5) && (cur_tok >= A_token))
\r
117 d = cur_tok - A_token + 10;
\r
118 else if ((cur_tok <= other_A_token + 5) && (cur_tok >= other_A_token))
\r
119 d = cur_tok - other_A_token;
\r
127 if ((cur_val >= m) && ((cur_val > m) || (d > 7) || (radix != 10)))
\r
131 print_err("Number too big");
\r
132 help2("I can only go up to 2147483647='17777777777=\"7FFFFFFF,",
\r
133 "so I'm using that number instead of yours.");
\r
135 cur_val = 2147483647L; /* 7FFFFFFF hex */
\r
140 cur_val = cur_val * radix + d;
\r
148 print_err("Missing number, treated as zero");
\r
149 help3("A number should have been here; I inserted `0'.",
\r
150 "(If you can't figure out why I needed to see a number,",
\r
151 "look up `weird error' in the index to The TeXbook.)");
\r
154 else if (cur_cmd != spacer)
\r
159 cur_val = - (integer) cur_val;
\r
162 void scan_dimen (boolean mu, boolean inf, boolean shortcut)
\r
166 integer num, denom;
\r
167 small_number k, kk;
\r
170 integer save_cur_val;
\r
173 arith_error = false;
\r
174 cur_order = normal;
\r
187 while (!(cur_cmd != spacer));
\r
189 if (cur_tok == other_token + '-')
\r
191 negative = ! negative;
\r
192 cur_tok = other_token + '+';
\r
195 while (!(cur_tok != other_token + '+'));
\r
197 if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))
\r
201 scan_something_internal(mu_val, false);
\r
203 if (cur_val_level >= glue_val)
\r
205 v = width(cur_val);
\r
206 delete_glue_ref(cur_val);
\r
210 if (cur_val_level == mu_val)
\r
213 if (cur_val_level != int_val)
\r
218 scan_something_internal(dimen_val, false);
\r
220 if (cur_val_level == dimen_val)
\r
228 if (cur_tok == continental_point_token)
\r
229 cur_tok = point_token;
\r
231 if (cur_tok != point_token)
\r
241 if (cur_tok == continental_point_token)
\r
242 cur_tok = point_token;
\r
244 if ((radix == 10) && (cur_tok == point_token))
\r
254 if ((cur_tok > zero_token + 9) || (cur_tok < zero_token))
\r
261 info(q) = cur_tok - zero_token;
\r
268 for (kk = k; kk >= 1; kk--)
\r
270 dig[kk - 1] = info(p);
\r
276 f = round_decimals(k);
\r
278 if (cur_cmd != spacer)
\r
286 negative = !negative;
\r
287 cur_val = - (integer) cur_val;
\r
292 if (scan_keyword("fil"))
\r
296 while (scan_keyword("l"))
\r
298 if (cur_order == filll)
\r
300 print_err("Illegal unit of measure (");
\r
301 prints("replaced by filll)");
\r
302 help1("I dddon't go any higher than filll.");
\r
309 goto attach_fraction;
\r
313 save_cur_val = cur_val;
\r
319 while (!(cur_cmd != spacer));
\r
321 if ((cur_cmd < min_internal) || (cur_cmd > max_internal))
\r
327 scan_something_internal(mu_val, false);
\r
329 if (cur_val_level >= glue_val)
\r
331 v = width(cur_val);
\r
332 delete_glue_ref(cur_val);
\r
336 if (cur_val_level != mu_val)
\r
343 scan_something_internal(dimen_val, false);
\r
353 if (scan_keyword("em"))
\r
354 v = quad(cur_font);
\r
355 else if (scan_keyword("ex"))
\r
356 v = x_height(cur_font);
\r
363 if (cur_cmd != spacer)
\r
368 cur_val = nx_plus_y(save_cur_val, v, xn_over_d(v, f, 65536L));
\r
374 if (scan_keyword("mu"))
\r
375 goto attach_fraction;
\r
378 print_err("Illegal unit of measure (");
\r
379 prints("mu inserted)");
\r
380 help4("The unit of measurement in math glue must be mu.",
\r
381 "To recover gracefully from this error, it's best to",
\r
382 "delete the erroneous units; e.g., type `2' to delete",
\r
383 "two letters. (See Chapter 27 of The TeXbook.)");
\r
385 goto attach_fraction;
\r
389 if (scan_keyword("true"))
\r
395 cur_val = xn_over_d(cur_val, 1000, mag);
\r
396 f = (1000 * f + 65536L * tex_remainder) / mag;
\r
397 cur_val = cur_val + (f / 65536L);
\r
402 if (scan_keyword("pt"))
\r
403 goto attach_fraction;
\r
405 if (scan_keyword("in"))
\r
406 set_conversion(7227, 100);
\r
407 else if (scan_keyword("pc"))
\r
408 set_conversion(12, 1);
\r
409 else if (scan_keyword("cm"))
\r
410 set_conversion(7227, 254);
\r
411 else if (scan_keyword("mm"))
\r
412 set_conversion(7227, 2540);
\r
413 else if (scan_keyword("bp"))
\r
414 set_conversion(7227, 7200);
\r
415 else if (scan_keyword("dd"))
\r
416 set_conversion(1238, 1157);
\r
417 else if (scan_keyword("cc"))
\r
418 set_conversion(14856, 1157);
\r
419 else if (scan_keyword("Q"))
\r
420 set_conversion(7227, 10160);
\r
421 else if (scan_keyword("H"))
\r
422 set_conversion(7227, 10160);
\r
423 else if (scan_keyword("twip"))
\r
424 set_conversion(1, 20);
\r
425 else if (scan_keyword("sp"))
\r
429 print_err("Illegal unit of measure (");
\r
430 prints("pt inserted)");
\r
431 help6("Dimensions can be in units of em, ex, in, pt, pc,",
\r
432 "cm, mm, dd, cc, bp, or sp; but yours is a new one!",
\r
433 "I'll assume that you meant to say pt, for printer's points.",
\r
434 "To recover gracefully from this error, it's best to",
\r
435 "delete the erroneous units; e.g., type `2' to delete",
\r
436 "two letters. (See Chapter 27 of The TeXbook.)");
\r
441 cur_val = xn_over_d(cur_val, num, denom);
\r
442 f = (num * f + 65536L * tex_remainder) / denom;
\r
443 cur_val = cur_val +(f / 65536L);
\r
448 if (cur_val >= 16384) /* 2^14 */
\r
449 arith_error = true;
\r
451 cur_val = cur_val * unity + f;
\r
457 if (cur_cmd != spacer)
\r
462 if (arith_error || (abs(cur_val) >= 1073741824L)) /* 2^30 */
\r
464 print_err("Dimension too large");
\r
465 help2("I can't work with sizes bigger than about 19 feet.",
\r
466 "Continue and I'll use the largest value I can.");
\r
468 cur_val = max_dimen;
\r
469 arith_error = false;
\r
473 cur_val = - (integer) cur_val;
\r
476 void scan_glue (small_number level)
\r
482 mu = (level == mu_val);
\r
491 while (!(cur_cmd != spacer));
\r
493 if (cur_tok == other_token + '-')
\r
495 negative = !negative;
\r
496 cur_tok = other_token + '+';
\r
499 while (!(cur_tok != other_token + '+'));
\r
501 if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))
\r
503 scan_something_internal(level, negative);
\r
505 if (cur_val_level >= glue_val)
\r
507 if (cur_val_level != level)
\r
513 if (cur_val_level == int_val)
\r
514 scan_dimen(mu, false, true);
\r
515 else if (level == mu_val)
\r
521 scan_dimen(mu, false, false);
\r
524 cur_val = - (integer) cur_val;
\r
527 q = new_spec(zero_glue);
\r
528 width(q) = cur_val;
\r
530 if (scan_keyword("plus"))
\r
532 scan_dimen(mu, true, false);
\r
533 stretch(q) = cur_val;
\r
534 stretch_order(q) = cur_order;
\r
537 if (scan_keyword("minus"))
\r
539 scan_dimen(mu, true, false);
\r
540 shrink(q) = cur_val;
\r
541 shrink_order(q) = cur_order;
\r
547 pointer scan_rule_spec (void)
\r
553 if (cur_cmd == vrule)
\r
554 width(q) = default_rule;
\r
557 height(q) = default_rule;
\r
563 if (scan_keyword("width"))
\r
565 scan_dimen(false, false, false);
\r
566 width(q) = cur_val;
\r
570 if (scan_keyword("height"))
\r
572 scan_dimen(false, false, false);
\r
573 height(q) = cur_val;
\r
577 if (scan_keyword("depth"))
\r
579 scan_dimen(false, false, false);
\r
580 depth(q) = cur_val;
\r
587 pointer str_toks (pool_pointer b)
\r
599 while (k < pool_ptr)
\r
606 t = other_token + t;
\r
608 fast_store_new_token(t);
\r
617 pointer the_toks (void)
\r
624 scan_something_internal(tok_val, false);
\r
626 if (cur_val_level >= ident_val)
\r
631 if (cur_val_level == ident_val)
\r
632 store_new_token(cs_token_flag + cur_val);
\r
633 else if (cur_val != 0)
\r
639 fast_store_new_token(info(r));
\r
648 old_setting = selector;
\r
649 selector = new_string;
\r
652 switch (cur_val_level)
\r
655 print_int(cur_val);
\r
660 print_scaled(cur_val);
\r
667 print_spec(cur_val, "pt");
\r
668 delete_glue_ref(cur_val);
\r
674 print_spec(cur_val, "mu");
\r
675 delete_glue_ref(cur_val);
\r
680 selector = old_setting;
\r
681 return str_toks(b);
\r
685 void ins_the_toks (void)
\r
687 link(garbage) = the_toks();
\r
688 ins_list(link(temp_head));
\r
691 void conv_toks (void)
\r
695 small_number save_scanner_status;
\r
703 case roman_numeral_code:
\r
709 save_scanner_status = scanner_status;
\r
710 scanner_status = 0;
\r
712 scanner_status = save_scanner_status;
\r
715 case font_name_code:
\r
719 case job_name_code:
\r
725 old_setting = selector;
\r
726 selector = new_string;
\r
732 print_int(cur_val);
\r
735 case roman_numeral_code:
\r
736 print_roman_int(cur_val);
\r
743 print_char(cur_chr);
\r
750 case font_name_code:
\r
751 print(font_name[cur_val]);
\r
753 if (font_size[cur_val] != font_dsize[cur_val])
\r
756 print_scaled(font_size[cur_val]);
\r
761 case job_name_code:
\r
766 selector = old_setting;
\r
767 link(garbage) = str_toks(b);
\r
768 begin_token_list(link(temp_head), 4);
\r
771 pointer scan_toks (boolean macro_def, boolean xpand)
\r
777 halfword unbalance;
\r
778 halfword hash_brace;
\r
781 scanner_status = defining;
\r
783 scanner_status = absorbing;
\r
785 warning_index = cur_cs;
\r
786 def_ref = get_avail();
\r
787 token_ref_count(def_ref) = 0;
\r
798 if (cur_tok < right_brace_limit)
\r
801 if (cur_cmd == mac_param)
\r
803 s = match_token + cur_chr;
\r
806 if (cur_cmd == left_brace)
\r
808 hash_brace = cur_tok;
\r
809 store_new_token(cur_tok);
\r
810 store_new_token(end_match_token);
\r
814 if (t == zero_token + 9)
\r
816 print_err("You already have nine parameters");
\r
817 help1("I'm going to ignore the # sign you just used.");
\r
826 print_err("Parameters must be numbered consecutively");
\r
827 help2("I've inserted the digit you should have used after the #.",
\r
828 "Type `1' to delete what you did use.");
\r
836 store_new_token(cur_tok);
\r
840 store_new_token(end_match_token);
\r
842 if (cur_cmd == right_brace)
\r
844 print_err("Missing { inserted");
\r
846 help2("Where was the left brace? You said something like `\\def\\a}',",
\r
847 "which I'm going to interpret as `\\def\\a{}'.");
\r
868 if (cur_cmd <= max_command)
\r
871 if (cur_cmd != the)
\r
879 if (link(temp_head) != 0)
\r
881 link(p) = link(temp_head);
\r
892 if (cur_tok < right_brace_limit)
\r
893 if (cur_cmd < right_brace)
\r
899 if (unbalance == 0)
\r
902 else if (cur_cmd == mac_param)
\r
912 if (cur_cmd != mac_param)
\r
913 if ((cur_tok <= zero_token) || (cur_tok > t))
\r
915 print_err("Illegal parameter number in definition of ");
\r
916 sprint_cs(warning_index);
\r
917 help3("You meant to type ## instead of #, right?",
\r
918 "Or maybe a } was forgotten somewhere earlier, and things",
\r
919 "are all screwed up? I'm going to assume that you meant ##.");
\r
924 cur_tok = out_param_token - '0' + cur_chr;
\r
927 store_new_token(cur_tok);
\r
931 scanner_status = 0;
\r
933 if (hash_brace != 0)
\r
934 store_new_token(hash_brace);
\r
939 void read_toks (integer n, pointer r)
\r
944 /* small_number m; */
\r
947 scanner_status = defining;
\r
949 def_ref = get_avail();
\r
950 token_ref_count(def_ref) = 0;
\r
952 store_new_token(end_match_token);
\r
954 if ((n < 0) || (n > 15))
\r
960 align_state = 1000000L;
\r
964 begin_file_reading();
\r
967 if (read_open[m] == closed)
\r
968 if (interaction > nonstop_mode)
\r
980 fatal_error("*** (cannot \\read from terminal in nonstop modes)");
\r
983 else if (read_open[m] == just_open)
\r
984 if (input_ln(read_file[m], false))
\r
985 read_open[m] = normal;
\r
988 a_close(read_file[m]);
\r
989 read_open[m] = closed;
\r
993 if (!input_ln(read_file[m], true))
\r
995 a_close(read_file[m]);
\r
996 read_open[m] = closed;
\r
998 if (align_state != 1000000L)
\r
1001 print_err("File ended within ");
\r
1002 print_esc("read");
\r
1003 help1("This \\read has unbalanced braces.");
\r
1004 align_state = 1000000L;
\r
1012 if (end_line_char_inactive())
\r
1015 buffer[limit] = end_line_char;
\r
1017 first = limit + 1;
\r
1028 if (align_state < 1000000L)
\r
1034 while (!(cur_tok == 0));
\r
1036 align_state = 1000000L;
\r
1040 store_new_token(cur_tok);
\r
1044 end_file_reading();
\r
1046 while (!(align_state == 1000000L));
\r
1048 cur_val = def_ref;
\r
1049 scanner_status = normal;
\r
1053 void pass_text (void)
\r
1056 small_number save_scanner_status;
\r
1058 save_scanner_status = scanner_status;
\r
1059 scanner_status = skipping;
\r
1067 if (cur_cmd == fi_or_else)
\r
1072 if (cur_chr == fi_code)
\r
1075 else if (cur_cmd == if_test)
\r
1080 scanner_status = save_scanner_status;
\r
1083 void change_if_limit (small_number l, pointer p)
\r
1087 if (p == cond_ptr)
\r
1112 void conditional (void)
\r
1118 small_number save_scanner_status;
\r
1119 pointer save_cond_ptr;
\r
1120 small_number this_if;
\r
1123 p = get_node(if_node_size);
\r
1124 link(p) = cond_ptr;
\r
1125 type(p) = if_limit;
\r
1126 subtype(p) = cur_if;
\r
1127 if_line_field(p) = if_line;
\r
1130 if_limit = if_code;
\r
1134 save_cond_ptr = cond_ptr;
\r
1135 this_if = cur_chr;
\r
1139 case if_char_code:
\r
1142 get_x_token_or_active_char();
\r
1144 if ((cur_cmd > active_char) || (cur_chr > 255))
\r
1155 get_x_token_or_active_char();
\r
1157 if ((cur_cmd > active_char) || (cur_chr > 255))
\r
1163 if (this_if == if_char_code)
\r
1164 b = (n == cur_chr);
\r
1166 b = (m == cur_cmd);
\r
1173 if (this_if == if_int_code)
\r
1176 scan_dimen(false, false, false);
\r
1184 while (!(cur_cmd != spacer));
\r
1186 if ((cur_tok >= other_token + '<') && (cur_tok <= other_token + '>'))
\r
1187 r = cur_tok - other_token;
\r
1190 print_err("Missing = inserted for ");
\r
1191 print_cmd_chr(if_test, this_if);
\r
1192 help1("I was expecting to see `<', `=', or `>'. Didn't.");
\r
1197 if (this_if == if_int_code)
\r
1200 scan_dimen(false, false, false);
\r
1205 b = (n < cur_val);
\r
1209 b = (n == cur_val);
\r
1213 b = (n > cur_val);
\r
1224 case if_vmode_code:
\r
1225 b = (abs(mode) == vmode);
\r
1228 case if_hmode_code:
\r
1229 b = (abs(mode) == hmode);
\r
1232 case if_mmode_code:
\r
1233 b = (abs(mode) == mmode);
\r
1236 case if_inner_code:
\r
1240 case if_void_code:
\r
1241 case if_hbox_code:
\r
1242 case if_vbox_code:
\r
1244 scan_eight_bit_int();
\r
1247 if (this_if == if_void_code)
\r
1251 else if (this_if == if_hbox_code)
\r
1252 b = (type(p) == hlist_node);
\r
1254 b = (type(p) == vlist_node);
\r
1260 save_scanner_status = scanner_status;
\r
1261 scanner_status = 0;
\r
1270 else if (cur_cmd < call)
\r
1271 b = (cur_chr == q);
\r
1274 p = link(cur_chr);
\r
1275 q = link(equiv(n));
\r
1281 while ((p != 0) && (q != 0))
\r
1282 if (info(p) != info(q))
\r
1290 b = ((p == 0) && (q == 0));
\r
1294 scanner_status = save_scanner_status;
\r
1300 scan_four_bit_int();
\r
1301 b = (read_open[cur_val] == closed);
\r
1305 case if_true_code:
\r
1309 case if_false_code:
\r
1313 case if_case_code:
\r
1318 if (tracing_commands > 1)
\r
1320 begin_diagnostic();
\r
1324 end_diagnostic(false);
\r
1331 if (cond_ptr == save_cond_ptr)
\r
1332 if (cur_chr == or_code)
\r
1335 goto common_ending;
\r
1336 else if (cur_chr == fi_code)
\r
1339 if_line = if_line_field(p);
\r
1340 cur_if = subtype(p);
\r
1341 if_limit = type(p);
\r
1342 cond_ptr = link(p);
\r
1343 free_node(p, if_node_size);
\r
1347 change_if_limit(or_code, save_cond_ptr);
\r
1353 if (tracing_commands > 1)
\r
1355 begin_diagnostic();
\r
1360 prints("{false}");
\r
1362 end_diagnostic(false);
\r
1367 change_if_limit(else_code, save_cond_ptr);
\r
1375 if (cond_ptr == save_cond_ptr)
\r
1377 if (cur_chr != or_code)
\r
1378 goto common_ending;
\r
1380 print_err("Extra ");
\r
1382 help1("I'm ignoring this; it doesn't match any \\if.");
\r
1385 else if (cur_chr == fi_code)
\r
1388 if_line = if_line_field(p);
\r
1389 cur_if = subtype(p);
\r
1390 if_limit = type(p);
\r
1391 cond_ptr = link(p);
\r
1392 free_node(p, if_node_size);
\r
1397 if (cur_chr == fi_code)
\r
1400 if_line = if_line_field(p);
\r
1401 cur_if = subtype(p);
\r
1402 if_limit = type(p);
\r
1403 cond_ptr = link(p);
\r
1404 free_node(p, if_node_size);
\r
1407 if_limit = fi_code;
\r
1410 void begin_name (void)
\r
1412 area_delimiter = 0;
\r
1413 ext_delimiter = 0;
\r
1416 boolean more_name (ASCII_code c)
\r
1418 if (quoted_file_name == false && c == ' ')
\r
1420 else if (quoted_file_name != false && c == '"')
\r
1422 quoted_file_name = false; /* catch next space character */
\r
1423 return true; /* accept ending quote, but throw away */
\r
1430 // for DOS/Windows
\r
1431 if ((c == '/' || c == '\\' || c == ':'))
\r
1433 area_delimiter = cur_length;
\r
1434 ext_delimiter = 0;
\r
1436 else if (c == '.')
\r
1437 ext_delimiter = cur_length;
\r
1444 void end_name (void)
\r
1446 #ifdef ALLOCATESTRING
\r
1447 if (str_ptr + 3 > current_max_strings)
\r
1448 str_start = realloc_str_start(increment_max_strings + 3);
\r
1450 if (str_ptr + 3 > current_max_strings)
\r
1452 overflow("number of strings", current_max_strings - init_str_ptr);
\r
1456 if (str_ptr + 3 > max_strings)
\r
1458 overflow("number of strings", max_strings - init_str_ptr);
\r
1463 if (area_delimiter == 0) // no area delimiter ':' '/' or '\' found
\r
1464 cur_area = 335; // "" default area
\r
1467 cur_area = str_ptr;
\r
1468 str_start[str_ptr + 1] = str_start[str_ptr] + area_delimiter;
\r
1472 if (ext_delimiter == 0) // no extension delimiter '.' found
\r
1474 cur_ext = 335; // "" default extension
\r
1475 cur_name = make_string();
\r
1479 cur_name = str_ptr;
\r
1480 str_start[str_ptr + 1] = str_start[str_ptr] + ext_delimiter - area_delimiter - 1;
\r
1482 cur_ext = make_string();
\r
1486 void pack_file_name (str_number n, str_number a, str_number e)
\r
1494 for (j = str_start[a]; j <= str_start[a + 1] - 1; j++)
\r
1495 append_to_name(str_pool[j]);
\r
1497 for (j = str_start[n]; j <= str_start[n + 1] - 1; j++)
\r
1498 append_to_name(str_pool[j]);
\r
1500 for (j = str_start[e]; j <= str_start[e + 1] - 1; j++)
\r
1501 append_to_name(str_pool[j]);
\r
1503 if (k < file_name_size)
\r
1506 name_length = file_name_size - 1;
\r
1508 for (k = name_length + 1; k <= file_name_size; k++)
\r
1509 name_of_file[k] = ' ';
\r
1511 name_of_file[file_name_size] = '\0'; /* paranoia */
\r
1514 name_of_file [name_length + 1] = '\0';
\r
1517 printf(" pack_file_name `%s' (%lld) ", name_of_file + 1, name_length);
\r
1519 name_of_file [name_length + 1] = ' ';
\r
1522 /* Called only from two places tex9.c for format name - specified and default */
\r
1523 /* for specified format name args are 0, a, b name in buffer[a] --- buffer[b] */
\r
1524 /* for default args are format_default_length-4, 1, 0 */
\r
1526 void pack_buffered_name_(small_number n, integer a, integer b)
\r
1532 if (n + b - a + 5 > file_name_size)
\r
1533 b = a + file_name_size - n - 5;
\r
1537 for (j = 1; j <= n; j++)
\r
1538 append_to_name(xord[TEX_format_default[j]]);
\r
1540 for (j = a; j <= b; j++)
\r
1541 append_to_name(buffer[j]);
\r
1543 for (j = format_default_length - 3; j <= format_default_length; j++)
\r
1544 append_to_name(xord[TEX_format_default[j]]);
\r
1546 if (k < file_name_size)
\r
1549 name_length = file_name_size - 1;
\r
1551 for (k = name_length + 1; k <= file_name_size; k++)
\r
1552 name_of_file[k]= ' ';
\r
1554 name_of_file[file_name_size] = '\0';
\r
1557 str_number make_name_string (void)
\r
1561 #ifdef ALLOCATESTRING
\r
1562 if (pool_ptr + name_length > current_pool_size)
\r
1563 str_pool = realloc_str_pool(increment_pool_size + name_length);
\r
1565 if (str_ptr == current_max_strings)
\r
1566 str_start = realloc_str_start(increment_max_strings);
\r
1568 if ((pool_ptr + name_length > current_pool_size) || (str_ptr == current_max_strings) || (cur_length > 0))
\r
1570 if ((pool_ptr + name_length > pool_size) || (str_ptr == max_strings) || (cur_length > 0))
\r
1577 for (k = 1; k <= name_length; k++)
\r
1578 append_char(xord[name_of_file[k]]);
\r
1580 return make_string();
\r
1584 //str_number a_make_name_string (alpha_file * f)
\r
1585 str_number a_make_name_string_(void)
\r
1587 return make_name_string();
\r
1590 //str_number b_make_name_string_(byte_file * f)
\r
1591 str_number b_make_name_string_(void)
\r
1593 return make_name_string();
\r
1596 //str_number w_make_name_string_(word_file * f)
\r
1597 str_number w_make_name_string_(void)
\r
1599 return make_name_string();
\r
1602 void scan_file_name (void)
\r
1604 name_in_progress = true;
\r
1611 while (!(cur_cmd != spacer));
\r
1613 quoted_file_name = false;
\r
1615 if (allow_quoted_names)
\r
1617 if (cur_chr == '"')
\r
1619 quoted_file_name = true;
\r
1626 if ((cur_cmd > other_char) || (cur_chr > 255))
\r
1632 if (!more_name(cur_chr))
\r
1640 name_in_progress = false;
\r
1642 /* argument is string .fmt, .log, .pdf, or .dvi */
\r
1644 void pack_job_name_(str_number s)
\r
1646 cur_area = 335; /* "" */
\r
1648 cur_name = job_name;
\r
1649 pack_file_name(cur_name, cur_area, cur_ext);
\r
1652 void prompt_file_name_(const char * s, str_number e)
\r
1656 if (interaction == scroll_mode)
\r
1659 if (!strcmp("input file name", s))
\r
1660 print_err("I can't find file `");
\r
1662 print_err("I can't write on file `");
\r
1664 print_file_name(cur_name, cur_area, cur_ext);
\r
1667 if (e == 785) /* .tex */
\r
1670 print_nl("Please type another ");
\r
1673 if (interaction < scroll_mode)
\r
1675 fatal_error("*** (job aborted, file error in nonstop mode)");
\r
1680 show_line(" (or Ctrl-Z to exit)", 0);
\r
1682 prompt_input(": ");
\r
1688 while ((buffer[k] == ' ') && (k < last))
\r
1691 quoted_file_name = false;
\r
1693 if (allow_quoted_names && k < last) /* check whether quoted name */
\r
1695 if (buffer[k]== '"')
\r
1697 quoted_file_name = true;
\r
1707 /* convert tilde '~' to pseudo tilde */
\r
1708 if (pseudo_tilde != 0 && buffer[k]== '~')
\r
1709 buffer[k] = pseudo_tilde;
\r
1711 /* convert space ' ' to pseudo space */
\r
1712 if (pseudo_space != 0 && buffer[k]== ' ')
\r
1713 buffer[k] = pseudo_space;
\r
1715 if (!more_name(buffer[k]))
\r
1725 if (cur_ext == 335) /* "" */
\r
1726 cur_ext = e; /* use default extension */
\r
1728 pack_file_name(cur_name, cur_area, cur_ext);
\r
1731 void open_log_file (void)
\r
1738 old_setting = selector;
\r
1740 if (job_name == 0)
\r
1741 job_name = get_job_name(790);
\r
1744 pack_job_name(".log");
\r
1746 while (!a_open_out(log_file))
\r
1748 selector = term_only;
\r
1749 prompt_file_name("transcript file name", ".log");
\r
1752 log_name = a_make_name_string(log_file);
\r
1753 selector = log_only;
\r
1754 log_opened = true;
\r
1757 fprintf(log_file, "%s (%s %s)", banner, application, yandyversion);
\r
1759 if (format_ident > 0)
\r
1760 slow_print(format_ident);
\r
1764 if (civilize_flag)
\r
1770 months = " JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
\r
1772 for (k = 3 * month - 2; k <= 3 * month; k++)
\r
1773 putc(months[k], log_file);
\r
1777 if (civilize_flag)
\r
1783 print_two(tex_time / 60);
\r
1785 print_two(tex_time % 60);
\r
1788 input_stack[input_ptr] = cur_input;
\r
1790 l = input_stack[0].limit_field;
\r
1792 if (buffer[l] == end_line_char)
\r
1795 for (k = 1; k <= l; k++)
\r
1800 if (show_fmt_flag)
\r
1802 if (format_file != NULL)
\r
1804 fprintf(log_file, "(%s)\n", format_file);
\r
1805 free(format_file);
\r
1806 format_file = NULL;
\r
1810 selector = old_setting + 2;
\r
1813 void start_input (void)
\r
1816 pack_file_name(cur_name, cur_area, cur_ext);
\r
1820 begin_file_reading();
\r
1822 if (a_open_in(cur_file, kpse_tex_format))
\r
1825 end_file_reading();
\r
1826 prompt_file_name("input file name", ".tex");
\r
1830 name = a_make_name_string(cur_file);
\r
1832 if (job_name == 0)
\r
1834 job_name = get_job_name(cur_name);
\r
1835 //job_name = cur_name;
\r
1839 if (term_offset + length(name) > max_print_line - 2)
\r
1841 else if ((term_offset > 0) || (file_offset > 0))
\r
1845 incr(open_parens);
\r
1847 if (open_parens > max_open_parens)
\r
1848 max_open_parens = open_parens;
\r
1851 update_terminal();
\r
1857 if (input_ln(cur_file, false))
\r
1860 firm_up_the_line();
\r
1862 if (end_line_char_inactive())
\r
1865 buffer[limit] = end_line_char;
\r
1867 first = limit + 1;
\r
1872 internal_font_number read_font_info (pointer u, str_number nom, str_number aire, scaled s)
\r
1875 boolean file_opened;
\r
1876 halfword lf, lh, nw, nh, nd, ni, nl, nk, ne, np;
\r
1878 internal_font_number f;
\r
1879 internal_font_number g;
\r
1880 eight_bits a, b, c, d;
\r
1883 integer bch_label;
\r
1890 file_opened = false;
\r
1891 pack_file_name(nom, aire, 805); /* .tfm */
\r
1893 if (!b_open_in(tfm_file))
\r
1896 file_opened = true;
\r
1907 if ((bc > ec + 1) || (ec > 255))
\r
1933 if (lf != 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np)
\r
1936 if ((nw == 0) || (nh == 0) || (nd == 0) || (ni == 0))
\r
1945 #ifdef ALLOCATEFONT
\r
1946 if ((fmem_ptr + lf > current_font_mem_size))
\r
1947 font_info = realloc_font_info (increment_font_mem_size + lf);
\r
1949 if ((font_ptr == font_max) || (fmem_ptr + lf > current_font_mem_size))
\r
1951 if ((font_ptr == font_max) || (fmem_ptr + lf > font_mem_size))
\r
1955 printf("font_ptr %lld font_max %d fmem_ptr %lld lf %d font_mem_size %ld\n",
\r
1956 font_ptr, font_max, fmem_ptr, lf, font_mem_size);
\r
1958 start_font_error_message();
\r
1959 prints(" not loaded: Not enough room left");
\r
1960 help4("I'm afraid I won't be able to make use of this font,",
\r
1961 "because my memory for character-size data is too small.",
\r
1962 "If you're really stuck, ask a wizard to enlarge me.",
\r
1963 "Or maybe try `I\\font<same font id>=<name of loaded font>'.");
\r
1969 char_base[f] = fmem_ptr - bc;
\r
1970 width_base[f] = char_base[f] + ec + 1;
\r
1971 height_base[f] = width_base[f] + nw;
\r
1972 depth_base[f] = height_base[f] + nh;
\r
1973 italic_base[f] = depth_base[f] + nd;
\r
1974 lig_kern_base[f] = italic_base[f] + ni;
\r
1975 kern_base[f] = lig_kern_base[f] + nl - kern_base_offset;
\r
1976 exten_base[f] = kern_base[f] + kern_base_offset + nk;
\r
1977 param_base[f] = exten_base[f] + ne;
\r
1983 store_four_quarters(font_check[f]);
\r
1987 z = z * 256 + fbyte;
\r
1989 z = (z * 16) + (fbyte / 16);
\r
2003 font_dsize[f] = z;
\r
2009 z = xn_over_d(z, - (integer) s, 1000);
\r
2014 for (k = fmem_ptr; k <= width_base[f] - 1; k++)
\r
2016 store_four_quarters(font_info[k].qqqq);
\r
2018 if ((a >= nw) || (b / 16 >= nh) || (b % 16 >= nd) || (c / 4 >= ni))
\r
2035 check_byte_range(d);
\r
2037 while (d < k + bc - fmem_ptr)
\r
2039 qw = char_info(f, d);
\r
2041 if (char_tag(qw) != list_tag)
\r
2047 if (d == k + bc - fmem_ptr)
\r
2062 while (z >= 8388608L) /* 2^23 */
\r
2065 alpha = alpha + alpha;
\r
2068 beta = (char) (256 / alpha);
\r
2069 alpha = alpha * z;
\r
2072 for (k = width_base[f]; k <= lig_kern_base[f] - 1; k++)
\r
2073 store_scaled(font_info[k].cint);
\r
2075 if (font_info[width_base[f]].cint != 0)
\r
2078 if (font_info[height_base[f]].cint != 0)
\r
2081 if (font_info[depth_base[f]].cint != 0)
\r
2084 if (font_info[italic_base[f]].cint != 0)
\r
2088 bch_label = 32767; /* '77777 */
\r
2093 for (k = lig_kern_base[f]; k <= kern_base[f] + kern_base_offset - 1; k++)
\r
2095 store_four_quarters(font_info[k].qqqq);
\r
2099 if (256 * c + d >= nl)
\r
2103 if (k == lig_kern_base[f])
\r
2109 check_existence(b);
\r
2112 check_existence(d);
\r
2113 else if (256 * (c - 128) + d >= nk)
\r
2117 if (k - lig_kern_base[f] + a + 1 >= nl)
\r
2123 bch_label = 256 * c + d;
\r
2126 for (k = kern_base[f] + kern_base_offset; k <= exten_base[f] - 1; k++)
\r
2127 store_scaled(font_info[k].cint);
\r
2129 for (k = exten_base[f]; k <= param_base[f] - 1; k++)
\r
2131 store_four_quarters(font_info[k].qqqq);
\r
2134 check_existence(a);
\r
2137 check_existence(b);
\r
2140 check_existence(c);
\r
2142 check_existence(d);
\r
2146 for (k = 1; k <= np; k++)
\r
2156 sw = sw * 256 + fbyte;
\r
2158 sw = sw * 256 + fbyte;
\r
2160 font_info[param_base[f]].cint = (sw * 16) + (fbyte / 16);
\r
2163 store_scaled(font_info[param_base[f] + k - 1].cint);
\r
2165 if (feof(tfm_file))
\r
2168 for (k = np + 1; k <= 7; k++)
\r
2169 font_info[param_base[f] + k - 1].cint = 0;
\r
2173 font_params[f] = np;
\r
2175 font_params[f] = 7;
\r
2177 hyphen_char[f] = default_hyphen_char;
\r
2178 skew_char[f] = default_skew_char;
\r
2180 if (bch_label < nl)
\r
2181 bchar_label[f] = bch_label + lig_kern_base[f];
\r
2183 bchar_label[f] = non_address;
\r
2185 font_bchar[f] = bchar;
\r
2186 font_false_bchar[f] = bchar;
\r
2191 qw = char_info(f, bchar);
\r
2193 if (char_exists(qw))
\r
2194 font_false_bchar[f] = 256;
\r
2197 font_name[f] = nom;
\r
2198 font_area[f] = aire;
\r
2202 adjust(char_base);
\r
2203 adjust(width_base);
\r
2204 adjust(lig_kern_base);
\r
2205 adjust(kern_base);
\r
2206 adjust(exten_base);
\r
2207 decr(param_base[f]);
\r
2208 fmem_ptr = fmem_ptr + lf;
\r
2214 start_font_error_message();
\r
2217 prints(" not loadable: Bad metric (TFM) file");
\r
2219 prints(" not loadable: Metric (TFM) file not found");
\r
2221 help5("I wasn't able to read the size data for this font,",
\r
2222 "so I will ignore the font specification.",
\r
2223 "[Wizards can fix TFM files using TFtoPL/PLtoTF.]",
\r
2224 "You might try inserting a different font spec;",
\r
2225 "e.g., type `I\\font<same font id>=<substitute font name>'.");
\r
2230 b_close(tfm_file);
\r