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
41 while (!(cur_cmd != spacer));
43 if (cur_tok == other_token + '-')
46 cur_tok = other_token + '+';
49 while (!(cur_tok != other_token + '+'));
51 if (cur_tok == alpha_token)
55 if (cur_tok < cs_token_flag)
59 if (cur_cmd <= right_brace)
60 if (cur_cmd == right_brace)
65 else if (cur_tok < cs_token_flag + single_base)
66 cur_val = cur_tok - cs_token_flag - active_base;
68 cur_val = cur_tok - cs_token_flag - single_base;
72 print_err("Improper alphabetic constant");
73 help2("A one-character control sequence belongs after a ` mark.",
74 "So I'm essentially inserting \\0 here.");
82 if (cur_cmd != spacer)
86 else if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))
88 scan_something_internal(int_val, false);
93 m = 214748364L; /* 7FFFFFFF hex */
95 if (cur_tok == octal_token)
98 m = 268435456L; /* 2^28 */
101 else if (cur_tok == hex_token)
104 m = 134217728L; /* 2^27 8000000 hex */
113 if ((cur_tok < zero_token + radix) && (cur_tok >= zero_token) && (cur_tok <= zero_token + 9))
114 d = cur_tok - zero_token;
115 else if (radix == 16)
116 if ((cur_tok <= A_token + 5) && (cur_tok >= A_token))
117 d = cur_tok - A_token + 10;
118 else if ((cur_tok <= other_A_token + 5) && (cur_tok >= other_A_token))
119 d = cur_tok - other_A_token;
127 if ((cur_val >= m) && ((cur_val > m) || (d > 7) || (radix != 10)))
131 print_err("Number too big");
132 help2("I can only go up to 2147483647='17777777777=\"7FFFFFFF,",
133 "so I'm using that number instead of yours.");
135 cur_val = 2147483647L; /* 7FFFFFFF hex */
140 cur_val = cur_val * radix + d;
147 print_err("Missing number, treated as zero");
148 help3("A number should have been here; I inserted `0'.",
149 "(If you can't figure out why I needed to see a number,",
150 "look up `weird error' in the index to The TeXbook.)");
153 else if (cur_cmd != spacer)
158 cur_val = - (integer) cur_val;
161 void scan_dimen_(boolean mu, boolean inf, boolean shortcut)
169 integer save_cur_val;
186 while (!(cur_cmd != spacer));
188 if (cur_tok == other_token + '-')
190 negative = ! negative;
191 cur_tok = other_token + '+';
194 while (!(cur_tok != other_token + '+'));
196 if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))
200 scan_something_internal(mu_val, false);
202 if (cur_val_level >= glue_val)
205 delete_glue_ref(cur_val);
209 if (cur_val_level == mu_val)
212 if (cur_val_level != int_val)
217 scan_something_internal(dimen_val, false);
219 if (cur_val_level == dimen_val)
227 if (cur_tok == continental_point_token)
228 cur_tok = point_token;
230 if (cur_tok != point_token)
240 if (cur_tok == continental_point_token)
241 cur_tok = point_token;
243 if ((radix == 10) && (cur_tok == point_token))
253 if ((cur_tok > zero_token + 9) || (cur_tok < zero_token))
260 info(q) = cur_tok - zero_token;
266 for (kk = k; kk >= 1; kk--)
268 dig[kk - 1] = info(p);
274 f = round_decimals(k);
276 if (cur_cmd != spacer)
284 negative = !negative;
285 cur_val = - (integer) cur_val;
290 if (scan_keyword("fil"))
294 while (scan_keyword("l"))
296 if (cur_order == filll)
298 print_err("Illegal unit of measure (");
299 prints("replaced by filll)");
300 help1("I dddon't go any higher than filll.");
306 goto attach_fraction;
310 save_cur_val = cur_val;
316 while (!(cur_cmd != spacer));
318 if ((cur_cmd < min_internal) || (cur_cmd > max_internal))
324 scan_something_internal(mu_val, false);
326 if (cur_val_level >= glue_val)
329 delete_glue_ref(cur_val);
333 if (cur_val_level != mu_val)
340 scan_something_internal(dimen_val, false);
350 if (scan_keyword("em"))
352 else if (scan_keyword("ex"))
353 v = x_height(cur_font);
360 if (cur_cmd != spacer)
365 cur_val = mult_and_add(save_cur_val, v, xn_over_d(v, f, 65536L), 1073741823L); /* 2^30 - 1 */
371 if (scan_keyword("mu"))
372 goto attach_fraction;
375 print_err("Illegal unit of measure (");
376 prints("mu inserted)");
377 help4("The unit of measurement in math glue must be mu.",
378 "To recover gracefully from this error, it's best to",
379 "delete the erroneous units; e.g., type `2' to delete",
380 "two letters. (See Chapter 27 of The TeXbook.)");
382 goto attach_fraction;
386 if (scan_keyword("true"))
392 cur_val = xn_over_d(cur_val, 1000, mag);
393 f = (1000 * f + 65536L * tex_remainder) / mag;
394 cur_val = cur_val + (f / 65536L);
399 if (scan_keyword("pt"))
400 goto attach_fraction;
402 if (scan_keyword("in"))
403 set_conversion(7227, 100);
404 else if (scan_keyword("pc"))
405 set_conversion(12, 1);
406 else if (scan_keyword("cm"))
407 set_conversion(7227, 254);
408 else if (scan_keyword("mm"))
409 set_conversion(7227, 2540);
410 else if (scan_keyword("bp"))
411 set_conversion(7227, 7200);
412 else if (scan_keyword("dd"))
413 set_conversion(1238, 1157);
414 else if (scan_keyword("cc"))
415 set_conversion(14856, 1157);
416 else if (scan_keyword("Q"))
417 set_conversion(7227, 10160);
418 else if (scan_keyword("H"))
419 set_conversion(7227, 10160);
420 else if (scan_keyword("sp"))
424 print_err("Illegal unit of measure (");
425 prints("pt inserted)");
426 help6("Dimensions can be in units of em, ex, in, pt, pc,",
427 "cm, mm, dd, cc, bp, or sp; but yours is a new one!",
428 "I'll assume that you meant to say pt, for printer's points.",
429 "To recover gracefully from this error, it's best to",
430 "delete the erroneous units; e.g., type `2' to delete",
431 "two letters. (See Chapter 27 of The TeXbook.)");
436 cur_val = xn_over_d(cur_val, num, denom);
437 f = (num * f + 65536L * tex_remainder) / denom;
438 cur_val = cur_val +(f / 65536L);
443 if (cur_val >= 16384) /* 2^14 */
446 cur_val = cur_val * unity + f;
452 if (cur_cmd != spacer)
457 if (arith_error || (abs(cur_val) >= 1073741824L)) /* 2^30 */
459 print_err("Dimension too large");
460 help2("I can't work with sizes bigger than about 19 feet.",
461 "Continue and I'll use the largest value I can.");
468 cur_val = - (integer) cur_val;
471 void scan_glue_(small_number level)
477 mu = (level == mu_val);
486 while (!(cur_cmd != spacer));
488 if (cur_tok == other_token + '-')
490 negative = !negative;
491 cur_tok = other_token + '+';
494 while (!(cur_tok != other_token + '+'));
496 if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))
498 scan_something_internal(level, negative);
500 if (cur_val_level >= glue_val)
502 if (cur_val_level != level)
509 if (cur_val_level == int_val)
511 scan_dimen(mu, false, true);
513 else if (level == mu_val)
521 scan_dimen(mu, false, false);
524 cur_val = - (integer) cur_val;
526 q = new_spec(zero_glue);
529 if (scan_keyword("plus"))
531 scan_dimen(mu, true, false);
532 stretch(q) = cur_val;
533 stretch_order(q) = cur_order;
536 if (scan_keyword("minus"))
538 scan_dimen(mu, true, false);
540 shrink_order(q) = cur_order;
546 halfword scan_rule_spec (void)
552 if (cur_cmd == vrule)
553 width(q) = default_rule;
556 height(q) = default_rule;
562 if (scan_keyword("width"))
564 scan_dimen(false, false, false);
569 if (scan_keyword("height"))
571 scan_dimen(false, false, false);
576 if (scan_keyword("depth"))
578 scan_dimen(false, false, false);
586 halfword str_toks_(pool_pointer b)
607 fast_store_new_token(t);
616 halfword the_toks (void)
623 scan_something_internal(tok_val, false);
625 if (cur_val_level >= ident_val)
630 if (cur_val_level == ident_val)
631 store_new_token(cs_token_flag + cur_val);
632 else if (cur_val != 0)
638 fast_store_new_token(info(r));
647 old_setting = selector;
648 selector = new_string;
651 switch (cur_val_level)
659 print_scaled(cur_val);
666 print_spec(cur_val, "pt");
667 delete_glue_ref(cur_val);
673 print_spec(cur_val, "mu");
674 delete_glue_ref(cur_val);
679 selector = old_setting;
684 void ins_the_toks (void)
686 link(garbage) = the_toks();
687 ins_list(link(temp_head));
690 void conv_toks (void)
694 small_number save_scanner_status;
702 case roman_numeral_code:
708 save_scanner_status = scanner_status;
711 scanner_status = save_scanner_status;
724 old_setting = selector;
725 selector = new_string;
734 case roman_numeral_code:
735 print_roman_int(cur_val);
750 print(font_name[cur_val]);
752 if (font_size[cur_val] != font_dsize[cur_val])
755 print_scaled(font_size[cur_val]);
765 selector = old_setting;
766 link(garbage) = str_toks(b);
767 begin_token_list(link(temp_head), 4);
770 pointer scan_toks_(boolean macro_def, boolean xpand)
780 scanner_status = defining;
782 scanner_status = absorbing;
784 warning_index = cur_cs;
785 def_ref = get_avail();
786 token_ref_count(def_ref) = 0;
797 if (cur_tok < right_brace_limit)
800 if (cur_cmd == mac_param)
802 s = match_token + cur_chr;
805 if (cur_cmd == left_brace)
807 hash_brace = cur_tok;
808 store_new_token(cur_tok);
809 store_new_token(end_match_token);
813 if (t == zero_token + 9)
815 print_err("You already have nine parameters");
816 help1("I'm going to ignore the # sign you just used.");
825 print_err("Parameters must be numbered consecutively");
826 help2("I've inserted the digit you should have used after the #.",
827 "Type `1' to delete what you did use.");
835 store_new_token(cur_tok);
839 store_new_token(end_match_token);
841 if (cur_cmd == right_brace)
843 print_err("Missing { inserted");
845 help2("Where was the left brace? You said something like `\\def\\a}',",
846 "which I'm going to interpret as `\\def\\a{}'.");
867 if (cur_cmd <= max_command)
878 if (link(temp_head) != 0)
880 link(p) = link(temp_head);
891 if (cur_tok < right_brace_limit)
892 if (cur_cmd < right_brace)
901 else if (cur_cmd == mac_param)
911 if (cur_cmd != mac_param)
912 if ((cur_tok <= zero_token) || (cur_tok > t))
914 print_err("Illegal parameter number in definition of ");
915 sprint_cs(warning_index);
916 help3("You meant to type ## instead of #, right?",
917 "Or maybe a } was forgotten somewhere earlier, and things",
918 "are all screwed up? I'm going to assume that you meant ##.");
923 cur_tok = out_param_token - '0' + cur_chr;
926 store_new_token(cur_tok);
932 store_new_token(hash_brace);
936 /* used only in ITEX.C */
938 void read_toks_(integer n, halfword r)
943 /* small_number m; */
944 int m; /* 95/Jan/7 */
946 scanner_status = defining;
948 def_ref = get_avail();
949 token_ref_count(def_ref) = 0;
951 store_new_token(end_match_token);
953 if ((n < 0) || (n > 15))
959 align_state = 1000000L;
963 begin_file_reading();
966 if (read_open[m] == closed)
967 if (interaction > nonstop_mode)
979 fatal_error("*** (cannot \\read from terminal in nonstop modes)");
982 else if (read_open[m] == 1)
983 if (input_ln(read_file[m], false))
987 (void) a_close(read_file[m]);
992 if (!input_ln(read_file[m], true))
994 (void) a_close(read_file[m]);
997 if (align_state != 1000000L)
1000 print_err("File ended within ");
1002 help1("This \\read has unbalanced braces.");
1003 align_state = 1000000L;
1011 if (end_line_char_inactive())
1014 buffer[limit] = end_line_char;
1027 if (align_state < 1000000L)
1033 while (!(cur_tok == 0));
1035 align_state = 1000000L;
1039 store_new_token(cur_tok);
1044 while (!(align_state == 1000000L));
1047 scanner_status = normal;
1051 void pass_text (void)
1054 small_number save_scanner_status;
1056 save_scanner_status = scanner_status;
1057 scanner_status = skipping;
1065 if (cur_cmd == fi_or_else)
1073 else if (cur_cmd == if_test)
1077 scanner_status = save_scanner_status;
1080 void change_if_limit_(small_number l, halfword p)
1108 /* called from tex2.c */
1110 void conditional (void)
1116 small_number save_scanner_status;
1117 halfword save_cond_ptr;
1118 small_number this_if;
1121 p = get_node(if_node_size);
1124 subtype(p) = cur_if;
1125 if_line_field(p) = if_line;
1132 save_cond_ptr = cond_ptr;
1143 if (cur_cmd == relax)
1144 if (cur_chr == no_expand_flag)
1146 cur_cmd = active_char;
1147 cur_chr = cur_tok - cs_token_flag - active_base;
1151 if ((cur_cmd > active_char) || (cur_chr > 255))
1164 if (cur_cmd == relax)
1165 if (cur_chr == no_expand_flag)
1167 cur_cmd = active_char;
1168 cur_chr = cur_tok - cs_token_flag - active_base;
1172 if ((cur_cmd > active_char) || (cur_chr > 255))
1178 if (this_if == if_char_code)
1188 if (this_if == if_int_code)
1191 scan_dimen(false, false, false);
1199 while (!(cur_cmd != spacer));
1201 if ((cur_tok >= other_token + '<') && (cur_tok <= other_token + '>'))
1202 r = cur_tok - other_token;
1205 print_err("Missing = inserted for ");
1206 print_cmd_chr(if_test, this_if);
1207 help1("I was expecting to see `<', `=', or `>'. Didn't.");
1212 if (this_if == if_int_code)
1215 scan_dimen(false, false, false);
1240 b = (abs(mode) == vmode);
1244 b = (abs(mode) == hmode);
1248 b = (abs(mode) == mmode);
1259 scan_eight_bit_int();
1262 if (this_if == if_void_code)
1266 else if (this_if == if_hbox_code)
1267 b = (type(p) == hlist_node);
1269 b = (type(p) == vlist_node);
1275 save_scanner_status = scanner_status;
1285 else if (cur_cmd < call)
1296 while ((p != 0) && (q != 0))
1297 if (info(p) != info(q))
1305 b = ((p == 0) && (q == 0));
1309 scanner_status = save_scanner_status;
1315 scan_four_bit_int();
1316 b = (read_open[cur_val] == closed);
1333 if (tracing_commands > 1)
1339 end_diagnostic(false);
1346 if (cond_ptr == save_cond_ptr)
1347 if (cur_chr == or_code)
1351 else if (cur_chr == fi_code)
1354 if_line = if_line_field(p);
1355 cur_if = subtype(p);
1358 free_node(p, if_node_size);
1362 change_if_limit(or_code, save_cond_ptr);
1368 if (tracing_commands > 1)
1377 end_diagnostic(false);
1382 change_if_limit(else_code, save_cond_ptr);
1390 if (cond_ptr == save_cond_ptr)
1392 if (cur_chr != or_code)
1395 print_err("Extra ");
1397 help1("I'm ignoring this; it doesn't match any \\if.");
1400 else if (cur_chr == fi_code)
1403 if_line = if_line_field(p);
1404 cur_if = subtype(p);
1407 free_node(p, if_node_size);
1412 if (cur_chr == fi_code)
1415 if_line = if_line_field(p);
1416 cur_if = subtype(p);
1419 free_node(p, if_node_size);
1425 void begin_name (void)
1430 /* This gathers up a file name and makes a string of it */
1431 /* Also tries to break it into `file area' `file name' and `file extension' */
1432 /* Used by scan_file_name and prompt_file_name */
1433 /* We assume tilde has been converted to pseudo_tilde and space to pseudo_space */
1434 /* returns false if it is given a space character - end of file name */
1436 boolean more_name_(ASCII_code c)
1438 if (quoted_file_name == false && c == ' ')
1440 else if (quoted_file_name != false && c == '"')
1442 quoted_file_name = false; /* catch next space character */
1443 return true; /* accept ending quote, but throw away */
1451 if ((c == '/' || c == '\\' || c == ':'))
1453 area_delimiter = cur_length;
1457 ext_delimiter = cur_length;
1464 void end_name (void)
1466 #ifdef ALLOCATESTRING
1467 if (str_ptr + 3 > current_max_strings)
1468 str_start = realloc_str_start(increment_max_strings + 3);
1470 if (str_ptr + 3 > current_max_strings)
1472 overflow("number of strings", current_max_strings - init_str_ptr);
1476 if (str_ptr + 3 > max_strings)
1478 overflow("number of strings", max_strings - init_str_ptr);
1483 if (area_delimiter == 0) // no area delimiter ':' '/' or '\' found
1484 cur_area = 335; // "" default area
1488 str_start[str_ptr + 1] = str_start[str_ptr] + area_delimiter;
1492 if (ext_delimiter == 0) // no extension delimiter '.' found
1494 cur_ext = 335; // "" default extension
1495 cur_name = make_string();
1500 str_start[str_ptr + 1] = str_start[str_ptr] + ext_delimiter - area_delimiter - 1;
1502 cur_ext = make_string();
1506 /* n current name, a current area, e current extension */
1507 /* result in name_of_file[] */
1509 void pack_file_name_(str_number n, str_number a, str_number e)
1517 for (j = str_start[a]; j <= str_start[a + 1] - 1; j++)
1522 if (k <= file_name_size)
1523 name_of_file[k] = xchr[c];
1526 for (j = str_start[n]; j <= str_start[n + 1] - 1; j++)
1531 if (k <= file_name_size)
1532 name_of_file[k] = xchr[c];
1535 for (j = str_start[e]; j <= str_start[e + 1] - 1; j++)
1540 if (k <= file_name_size)
1541 name_of_file[k] = xchr[c];
1544 if (k < file_name_size)
1547 name_length = file_name_size - 1;
1549 /* pad it out with spaces ... what for ? in case we modify and forget ? */
1550 for (k = name_length + 1; k <= file_name_size; k++)
1551 name_of_file[k] = ' ';
1553 name_of_file[file_name_size] = '\0'; /* paranoia 94/Mar/24 */
1556 name_of_file [name_length+1] = '\0';
1559 printf(" pack_file_name `%s' (%lld) ", name_of_file + 1, name_length);
1561 name_of_file [name_length + 1] = ' ';
1564 /* Called only from two places tex9.c for format name - specified and default */
1565 /* for specified format name args are 0, a, b name in buffer[a] --- buffer[b] */
1566 /* for default args are format_default_length-4, 1, 0 */
1568 void pack_buffered_name_(small_number n, integer a, integer b)
1574 if (n + b - a + 5 > file_name_size)
1575 b = a + file_name_size - n - 5;
1579 /* This loop kicks in when we want the default format name */
1580 for (j = 1; j <= n; j++)
1582 c = xord[TEX_format_default[j]];
1585 if (k <= file_name_size)
1586 name_of_file[k] = xchr[c];
1588 /* This loop kicks in when we want a specififed format name */
1589 for (j = a; j <= b; j++)
1594 if (k <= file_name_size)
1595 name_of_file[k] = xchr[c];
1598 /* This adds the extension from the default format name */
1599 for (j = format_default_length - 3; j <= format_default_length; j++)
1601 c = xord[TEX_format_default[j]];
1604 if (k <= file_name_size)
1605 name_of_file[k] = xchr[c];
1608 if (k < file_name_size)
1611 name_length = file_name_size - 1;
1613 for (k = name_length + 1; k <= file_name_size; k++)
1614 name_of_file[k]= ' ';
1616 name_of_file[file_name_size] = '\0';
1619 str_number make_name_string (void)
1623 #ifdef ALLOCATESTRING
1624 if (pool_ptr + name_length > current_pool_size)
1625 str_pool = realloc_str_pool(increment_pool_size + name_length);
1627 if (str_ptr == current_max_strings)
1628 str_start = realloc_str_start(increment_max_strings);
1630 if ((pool_ptr + name_length > current_pool_size) || (str_ptr == current_max_strings) || (cur_length > 0))
1632 if ((pool_ptr + name_length > pool_size) || (str_ptr == max_strings) || (cur_length > 0))
1639 for (k = 1; k <= name_length; k++)
1640 append_char(xord[name_of_file[k]]);
1642 return make_string();
1646 //str_number a_make_name_string_(alpha_file * f)
1647 str_number a_make_name_string_(void)
1649 return make_name_string();
1652 //str_number b_make_name_string_(byte_file * f)
1653 str_number b_make_name_string_(void)
1655 return make_name_string();
1658 //str_number w_make_name_string_(word_file * f)
1659 str_number w_make_name_string_(void)
1661 return make_name_string();
1664 /* Used by start_input to scan file name on command line */
1665 /* Also in tex8.c new_font_, open_or_close_in, and do_extension */
1667 void scan_file_name (void)
1669 name_in_progress = true;
1676 while (!(cur_cmd != spacer));
1678 quoted_file_name = false;
1680 if (allow_quoted_names)
1684 quoted_file_name = true;
1691 if ((cur_cmd > other_char) || (cur_chr > 255))
1697 if (!more_name(cur_chr)) /* up to next white space */
1705 name_in_progress = false;
1707 /* argument is string .fmt, .log, or .dvi */
1709 void pack_job_name_(str_number s)
1711 cur_area = 335; /* "" */
1713 cur_name = job_name;
1714 pack_file_name(cur_name, cur_area, cur_ext);
1717 /* s - what can't be found, e - default */
1718 void prompt_file_name_(char * s, str_number e)
1722 if (interaction == scroll_mode)
1725 if (!strcmp("input file name", s))
1726 print_err("I can't find file `");
1728 print_err("I can't write on file `");
1730 print_file_name(cur_name, cur_area, cur_ext);
1733 if (e == 785) /* .tex */
1736 print_nl("Please type another ");
1739 if (interaction < 2)
1741 fatal_error("*** (job aborted, file error in nonstop mode)");
1747 show_line(" (or ^z to exit)", 0);
1749 show_line(" (or Ctrl-Z to exit)", 0);
1754 /* should we deal with tilde and space in file name here ??? */
1759 while ((buffer[k] == ' ') && (k < last))
1762 quoted_file_name = false;
1764 if (allow_quoted_names && k < last) /* check whether quoted name */
1766 if (buffer[k]== '"')
1768 quoted_file_name = true;
1777 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1778 /* convert tilde '~' to pseudo tilde */
1779 if (pseudo_tilde != 0 && buffer[k]== '~')
1780 buffer[k] = pseudo_tilde;
1781 /* convert space ' ' to pseudo space */
1782 if (pseudo_space != 0 && buffer[k]== ' ')
1783 buffer[k] = pseudo_space;
1784 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1785 if (!more_name(buffer[k]))
1795 if (cur_ext == 335) /* "" */
1796 cur_ext = e; /* use default extension */
1798 pack_file_name(cur_name, cur_area, cur_ext);
1801 void open_log_file (void)
1808 old_setting = selector;
1813 pack_job_name(".log");
1815 while (!a_open_out(log_file))
1817 selector = term_only;
1818 prompt_file_name("transcript file name", ".log");
1821 texmf_log_name = a_make_name_string(log_file);
1822 selector = log_only;
1826 fprintf(log_file, "%s (%s %s)", tex_version, application, yandyversion);
1828 if (format_ident > 0)
1829 slow_print(format_ident);
1839 months = " JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
1841 for (k = 3 * month - 2; k <= 3 * month; k++)
1842 putc(months[k], log_file);
1852 print_two(tex_time / 60);
1854 print_two(tex_time % 60);
1857 input_stack[input_ptr] = cur_input;
1859 l = input_stack[0].limit_field;
1861 if (buffer[l] == end_line_char)
1864 for (k = 1; k <= l; k++)
1871 if (format_file != NULL)
1873 fprintf(log_file, "(%s)\n", format_file);
1879 selector = old_setting + 2;
1882 void start_input(void)
1885 pack_file_name(cur_name, cur_area, cur_ext);
1889 begin_file_reading();
1891 if (a_open_in(cur_file, TEXINPUTPATH))
1895 prompt_file_name("input file name", ".tex");
1899 name = a_make_name_string(cur_file);
1903 job_name = cur_name;
1907 if (term_offset + length(name) > max_print_line - 2)
1909 else if ((term_offset > 0) || (file_offset > 0))
1915 if (open_parens > max_open_parens)
1916 max_open_parens = open_parens;
1925 if (input_ln(cur_file, false))
1930 if (end_line_char_inactive())
1933 buffer[limit] = end_line_char;
1940 internal_font_number read_font_info_(halfword u, str_number nom, str_number aire, scaled s)
1943 boolean file_opened;
1944 halfword lf, lh, nw, nh, nd, ni, nl, nk, ne, np;
1946 internal_font_number f;
1947 internal_font_number g;
1948 eight_bits a, b, c, d;
1958 file_opened = false;
1959 pack_file_name(nom, aire, 805); /* .tfm */
1961 if (!b_open_in(tfm_file))
1968 tfm_temp = getc(tfm_file);
1970 tfm_temp = getc(tfm_file);
1972 tfm_temp = getc(tfm_file);
1975 if ((bc > ec + 1) || (ec > 255))
1984 tfm_temp = getc(tfm_file);
1986 tfm_temp = getc(tfm_file);
1988 tfm_temp = getc(tfm_file);
1990 tfm_temp = getc(tfm_file);
1992 tfm_temp = getc(tfm_file);
1994 tfm_temp = getc(tfm_file);
1996 tfm_temp = getc(tfm_file);
1998 tfm_temp = getc(tfm_file);
2001 if (lf != 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np)
2004 if ((nw == 0) || (nh == 0) || (nd == 0) || (ni == 0))
2014 if ((fmem_ptr + lf > current_font_mem_size))
2015 font_info = realloc_font_info (increment_font_mem_size + lf);
2017 if ((font_ptr == font_max) || (fmem_ptr + lf > current_font_mem_size))
2019 if ((font_ptr == font_max) || (fmem_ptr + lf > font_mem_size))
2023 printf("font_ptr %lld font_max %d fmem_ptr %lld lf %d font_mem_size %ld\n",
2024 font_ptr, font_max, fmem_ptr, lf, font_mem_size);
2029 print_file_name(nom, aire, 335); /* "" */
2037 else if (s != -1000)
2040 print_int(- (integer) s);
2043 prints(" not loaded: Not enough room left");
2044 help4("I'm afraid I won't be able to make use of this font,",
2045 "because my memory for character-size data is too small.",
2046 "If you're really stuck, ask a wizard to enlarge me.",
2047 "Or maybe try `I\\font<same font id>=<name of loaded font>'.");
2053 char_base[f] = fmem_ptr - bc;
2054 width_base[f] = char_base[f] + ec + 1;
2055 height_base[f] = width_base[f] + nw;
2056 depth_base[f] = height_base[f] + nh;
2057 italic_base[f] = depth_base[f] + nd;
2058 lig_kern_base[f] = italic_base[f] + ni;
2059 kern_base[f] = lig_kern_base[f] + nl - 256 * (128);
2060 exten_base[f] = kern_base[f] + 256 * (128) + nk;
2061 param_base[f] = exten_base[f] + ne;
2067 store_four_quarters(font_check[f]);
2068 tfm_temp = getc(tfm_file);
2070 tfm_temp = getc(tfm_file);
2071 z = z * 256 + tfm_temp;
2072 tfm_temp = getc(tfm_file);
2073 z =(z * 16) + (tfm_temp / 16);
2080 tfm_temp = getc(tfm_file);
2081 tfm_temp = getc(tfm_file);
2082 tfm_temp = getc(tfm_file);
2083 tfm_temp = getc(tfm_file);
2093 z = xn_over_d(z, - (integer) s, 1000);
2098 for (k = fmem_ptr; k <= width_base[f] - 1; k++)
2100 store_four_quarters(font_info[k].qqqq);
2102 if ((a >= nw) || (b / 16 >= nh) || (b % 16 >= nd) || (c / 4 >= ni))
2120 if ((d < bc) || (d > ec))
2124 while (d < k + bc - fmem_ptr)
2126 qw = char_info(f, d);
2128 if (char_tag(qw) != list_tag)
2134 if (d == k + bc - fmem_ptr)
2149 while (z >= 8388608L) /* 2^23 */
2152 alpha = alpha + alpha;
2155 beta = (char) (256 / alpha);
2159 for (k = width_base[f]; k <= lig_kern_base[f] - 1; k++)
2161 tfm_temp = getc(tfm_file);
2163 tfm_temp = getc(tfm_file);
2165 tfm_temp = getc(tfm_file);
2167 tfm_temp = getc(tfm_file);
2169 sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2172 font_info[k].cint = sw;
2174 font_info[k].cint = sw - alpha;
2179 if (font_info[width_base[f]].cint != 0)
2182 if (font_info[height_base[f]].cint != 0)
2185 if (font_info[depth_base[f]].cint != 0)
2188 if (font_info[italic_base[f]].cint != 0)
2192 bch_label = 32767; /* '77777 */
2197 for (k = lig_kern_base[f]; k <= kern_base[f] + 256 * (128) - 1; k++)
2199 store_four_quarters(font_info[k].qqqq);
2203 if (256 * c + d >= nl)
2207 if (k == lig_kern_base[f])
2217 else if (256 * (c - 128) + d >= nk)
2221 if (k - lig_kern_base[f] + a + 1 >= nl)
2227 bch_label = 256 * c + d;
2230 for (k = kern_base[f] + 256 * (128); k <= exten_base[f] - 1; k++)
2232 tfm_temp = getc(tfm_file);
2234 tfm_temp = getc(tfm_file);
2236 tfm_temp = getc(tfm_file);
2238 tfm_temp = getc(tfm_file);
2240 sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2243 font_info[k].cint = sw;
2245 font_info[k].cint = sw - alpha;
2250 for (k = exten_base[f]; k <= param_base[f] - 1; k++)
2252 store_four_quarters(font_info[k].qqqq);
2267 for (k = 1; k <= np; k++)
2270 tfm_temp = getc(tfm_file);
2276 tfm_temp = getc(tfm_file);
2277 sw = sw * 256 + tfm_temp;
2278 tfm_temp = getc(tfm_file);
2279 sw = sw * 256 + tfm_temp;
2280 tfm_temp = getc(tfm_file);
2281 font_info[param_base[f]].cint = (sw * 16) + (tfm_temp / 16);
2285 tfm_temp = getc(tfm_file);
2287 tfm_temp = getc(tfm_file);
2289 tfm_temp = getc(tfm_file);
2291 tfm_temp = getc(tfm_file);
2293 sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2296 font_info[param_base[f] + k - 1].cint = sw;
2298 font_info[param_base[f] + k - 1].cint = sw - alpha;
2305 for (k = np + 1; k <= 7; k++)
2306 font_info[param_base[f] + k - 1].cint = 0;
2310 font_params[f] = np;
2314 hyphen_char[f] = default_hyphen_char;
2315 skew_char[f] = default_skew_char;
2318 bchar_label[f] = bch_label + lig_kern_base[f];
2320 bchar_label[f] = non_address;
2322 font_bchar[f] = bchar;
2323 font_false_bchar[f] = bchar;
2328 qw = char_info(f, bchar);
2330 if (char_exists(qw))
2331 font_false_bchar[f] = 256;
2335 font_area[f] = aire;
2339 char_base[f] = char_base[f];
2340 width_base[f] = width_base[f];
2341 lig_kern_base[f] = lig_kern_base[f];
2342 kern_base[f] = kern_base[f];
2343 exten_base[f] = exten_base[f];
2344 decr(param_base[f]);
2345 fmem_ptr = fmem_ptr + lf;
2354 print_file_name(nom, aire, 335);
2362 else if (s != -1000)
2365 print_int(-(integer)s);
2369 prints(" not loadable: Bad metric (TFM) file");
2371 prints(" not loadable: Metric (TFM) file not found");
2373 help5("I wasn't able to read the size data for this font,",
2374 "so I will ignore the font specification.",
2375 "[Wizards can fix TFM files using TFtoPL/PLtoTF.]",
2376 "You might try inserting a different font spec;",
2377 "e.g., type `I\\font<same font id>=<substitute font name>'.");