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_(bool mu, bool inf, bool shortcut)
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))
246 p = 0; /* p:=null l.8883 */
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 print_string("replaced by filll)");
300 help1("I dddon't go any higher than filll.");
310 savecurval = 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)
364 cur_val = mult_and_add(savecurval, v, xn_over_d(v, f, 65536L), 1073741823L); /* 2^30 - 1 */
369 if (scan_keyword("mu"))
373 print_err("Illegal unit of measure (");
374 print_string("mu inserted)");
375 help4("The unit of measurement in math glue must be mu.",
376 "To recover gracefully from this error, it's best to",
377 "delete the erroneous units; e.g., type `2' to delete",
378 "two letters. (See Chapter 27 of The TeXbook.)");
384 if (scan_keyword("true"))
390 cur_val = xn_over_d(cur_val, 1000, mag);
391 f = (1000 * f + 65536L * tex_remainder) / mag;
392 cur_val = cur_val + (f / 65536L);
397 if (scan_keyword("pt"))
400 if (scan_keyword("in"))
405 else if (scan_keyword("pc"))
410 else if (scan_keyword("cm"))
415 else if (scan_keyword("mm"))
420 else if (scan_keyword("bp"))
425 else if (scan_keyword("dd"))
430 else if (scan_keyword("cc"))
435 else if (scan_keyword("Q"))
440 else if (scan_keyword("H"))
445 else if (scan_keyword("sp"))
449 print_err("Illegal unit of measure (");
450 print_string("pt inserted)");
451 help6("Dimensions can be in units of em, ex, in, pt, pc,",
452 "cm, mm, dd, cc, bp, or sp; but yours is a new one!",
453 "I'll assume that you meant to say pt, for printer's points.",
454 "To recover gracefully from this error, it's best to",
455 "delete the erroneous units; e.g., type `2' to delete",
456 "two letters. (See Chapter 27 of The TeXbook.)");
461 cur_val = xn_over_d(cur_val, num, denom);
462 f = (num * f + 65536L * tex_remainder) / denom;
463 cur_val = cur_val +(f / 65536L);
467 if (cur_val >= 16384) /* 2^14 */
470 cur_val = cur_val * 65536L + f;
475 if (cur_cmd != spacer)
479 if (arith_error || (abs(cur_val) >= 1073741824L)) /* 2^30 */
481 print_err("Dimension too large");
482 help2("I can't work with sizes bigger than about 19 feet.",
483 "Continue and I'll use the largest value I can.");
485 cur_val = 1073741823L; /* 2^30 - 1 */
490 cur_val = - (integer) cur_val;
493 void scan_glue_(small_number level)
499 mu = (level == mu_val);
508 while (!(cur_cmd != spacer));
510 if (cur_tok == other_token + '-')
512 negative = !negative;
513 cur_tok = other_token + '+';
516 while (!(cur_tok != other_token + '+'));
518 if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))
520 scan_something_internal(level, negative);
522 if (cur_val_level >= glue_val)
524 if (cur_val_level != level)
531 if (cur_val_level == int_val)
533 scan_dimen(mu, false, true);
535 else if (level == mu_val)
543 scan_dimen(mu, false, false);
546 cur_val = - (integer) cur_val;
548 q = new_spec(zero_glue);
551 if (scan_keyword("plus"))
553 scan_dimen(mu, true, false);
554 stretch(q) = cur_val;
555 stretch_order(q) = cur_order;
558 if (scan_keyword("minus"))
560 scan_dimen(mu, true, false);
562 shrink_order(q) = cur_order;
568 halfword scan_rule_spec (void)
574 if (cur_cmd == vrule)
575 width(q) = default_rule;
578 height(q) = default_rule;
584 if (scan_keyword("width"))
586 scan_dimen(false, false, false);
591 if (scan_keyword("height"))
593 scan_dimen(false, false, false);
598 if (scan_keyword("depth"))
600 scan_dimen(false, false, false);
608 halfword str_toks_(pool_pointer b)
636 avail = mem[q].hh.v.RH;
654 halfword the_toks (void)
656 register halfword Result;
662 scan_something_internal(tok_val, false);
664 if (cur_val_level >= ident_val)
669 if (cur_val_level == ident_val)
673 mem[q].hh.v.LH = cs_token_flag + cur_val;
676 else if (cur_val != 0)
680 while (r != 0) { /* while r<>null do l.9178 */
688 avail = mem[q].hh.v.RH;
696 mem[q].hh.v.LH = mem[r].hh.v.LH;
706 old_setting = selector;
707 selector = new_string;
710 switch (cur_val_level)
717 print_scaled(cur_val);
723 print_spec(cur_val, "pt");
724 delete_glue_ref(cur_val);
729 print_spec(cur_val, "mu");
730 delete_glue_ref(cur_val);
734 selector = old_setting;
735 Result = str_toks(b);
741 void ins_the_toks (void)
743 link(garbage) = the_toks();
744 begin_token_list(link(temp_head), 4);
747 void conv_toks (void)
751 small_number savescannerstatus;
759 case roman_numeral_code:
765 savescannerstatus = scanner_status;
768 scanner_status = savescannerstatus;
781 old_setting = selector;
782 selector = new_string;
791 case roman_numeral_code:
792 print_roman_int(cur_val);
807 print(font_name[cur_val]);
809 if (font_size[cur_val] != font_dsize[cur_val])
811 print_string(" at ");
812 print_scaled(font_size[cur_val]);
822 selector = old_setting;
823 link(garbage) = str_toks(b);
824 begin_token_list(link(temp_head), 4);
827 halfword scan_toks_(bool macrodef, bool xpand)
829 register halfword Result;
838 scanner_status = defining;
840 scanner_status = absorbing;
842 warning_index = cur_cs;
843 def_ref = get_avail();
844 token_ref_count(def_ref) = 0;
855 if (cur_tok < right_brace_limit)
858 if (cur_cmd == mac_param)
860 s = match_token + cur_chr;
863 if (cur_cmd == left_brace)
869 mem[q].hh.v.LH = cur_tok;
875 mem[q].hh.v.LH = end_match_token;
881 if (t == zero_token + 9)
883 print_err("You already have nine parameters");
884 help1("I'm going to ignore the # sign you just used.");
893 print_err("Parameters must be numbered consecutively");
894 help2("I've inserted the digit you should have used after the #.",
895 "Type `1' to delete what you did use.");
904 mem[q].hh.v.LH = cur_tok;
912 mem[q].hh.v.LH = end_match_token;
916 if (cur_cmd == right_brace)
918 print_err("Missing { inserted");
920 help2("Where was the left brace? You said something like `\\def\\a}',",
921 "which I'm going to interpret as `\\def\\a{}'.");
942 if (cur_cmd <= max_command)
953 if (link(temp_head) != 0)
955 link(p) = link(temp_head);
966 if (cur_tok < right_brace_limit)
967 if (cur_cmd < right_brace)
976 else if (cur_cmd == mac_param)
986 if (cur_cmd != mac_param)
987 if ((cur_tok <= zero_token) || (cur_tok > t))
989 print_err("Illegal parameter number in definition of ");
990 sprint_cs(warning_index);
991 help3("You meant to type ## instead of #, right?",
992 "Or maybe a } was forgotten somewhere earlier, and things",
993 "are all screwed up? I'm going to assume that you meant ##.");
998 cur_tok = out_param_token - '0' + cur_chr;
1003 mem[q].hh.v.LH = cur_tok;
1014 mem[q].hh.v.LH = hashbrace;
1020 /* used only in ITEX.C */
1022 void read_toks_(integer n, halfword r)
1027 /* small_number m; */
1028 int m; /* 95/Jan/7 */
1030 scanner_status = defining;
1032 def_ref = get_avail();
1033 token_ref_count(def_ref) = 0;
1039 mem[q].hh.v.LH = end_match_token;
1043 if ((n < 0) || (n > 15))
1049 align_state = 1000000L;
1053 begin_file_reading();
1054 cur_input.name_field = m + 1;
1056 if (read_open[m] == closed)
1057 if (interaction > nonstop_mode)
1075 fatal_error("*** (cannot \\read from terminal in nonstop modes)");
1076 return; // abort_flag set
1078 else if (read_open[m] == 1)
1079 if (input_ln(read_file[m], false))
1083 (void) a_close(read_file[m]);
1088 if (!input_ln(read_file[m], true))
1090 (void) a_close(read_file[m]);
1093 if (align_state != 1000000L)
1096 print_err("File ended within ");
1098 help1("This \\read has unbalanced braces.");
1099 align_state = 1000000L;
1105 cur_input.limit_field = last;
1107 if ((end_line_char < 0) || (end_line_char > 255))
1108 decr(cur_input.limit_field);
1110 buffer[cur_input.limit_field] = end_line_char;
1112 first = cur_input.limit_field + 1;
1113 cur_input.loc_field = cur_input.start_field;
1114 cur_input.state_field = new_line;
1123 if (align_state < 1000000L)
1129 while(!(cur_tok == 0));
1131 align_state = 1000000L;
1138 mem[q].hh.v.LH = cur_tok;
1145 while(!(align_state == 1000000L));
1148 scanner_status = normal;
1152 void pass_text (void)
1155 small_number savescannerstatus;
1157 savescannerstatus = scanner_status;
1158 scanner_status = skipping;
1166 if (cur_cmd == fi_or_else)
1174 else if (cur_cmd == if_test)
1178 scanner_status = savescannerstatus;
1181 void change_if_limit_(small_number l, halfword p)
1196 return; // abort_flag set
1209 /* called from tex2.c */
1211 void conditional (void)
1217 small_number savescannerstatus;
1218 halfword savecondptr;
1219 small_number thisif;
1222 p = get_node(if_node_size);
1225 subtype(p) = cur_if;
1226 if_line_field(p) = if_line;
1233 savecondptr = cond_ptr;
1244 if (cur_cmd == relax)
1245 if (cur_chr == no_expand_flag)
1247 cur_cmd = active_char;
1248 cur_chr = cur_tok - cs_token_flag - active_base;
1252 if ((cur_cmd > active_char) || (cur_chr > 255))
1265 if (cur_cmd == relax)
1266 if (cur_chr == no_expand_flag)
1268 cur_cmd = active_char;
1269 cur_chr = cur_tok - cs_token_flag - active_base;
1273 if ((cur_cmd > active_char) || (cur_chr > 255))
1279 if (thisif == if_char_code)
1289 if (thisif == if_int_code)
1292 scan_dimen(false, false, false);
1300 while(!(cur_cmd != spacer));
1302 if ((cur_tok >= other_token + '<') && (cur_tok <= other_token + '>'))
1303 r = cur_tok - other_token;
1306 print_err("Missing = inserted for ");
1307 print_cmd_chr(if_test, thisif);
1308 help1("I was expecting to see `<', `=', or `>'. Didn't.");
1313 if (thisif == if_int_code)
1316 scan_dimen(false, false, false);
1341 b = (abs(mode) == 1);
1345 b = (abs(mode) == 102);
1349 b = (abs(mode) == 203);
1360 scan_eight_bit_int();
1363 if (thisif == if_void_code)
1367 else if (thisif == if_hbox_code)
1368 b = (type(p) == hlist_node);
1370 b = (type(p) == vlist_node);
1376 savescannerstatus = scanner_status;
1386 else if (cur_cmd < call)
1397 while ((p != 0) && (q != 0))
1398 if (info(p) != info(q))
1406 b = ((p == 0) && (q == 0));
1410 scanner_status = savescannerstatus;
1416 scan_four_bit_int();
1417 b = (read_open[cur_val] == closed);
1434 if (tracing_commands > 1)
1437 print_string("{case ");
1440 end_diagnostic(false);
1447 if (cond_ptr == savecondptr)
1448 if (cur_chr == or_code)
1452 else if (cur_chr == fi_code)
1455 if_line = if_line_field(p);
1456 cur_if = subtype(p);
1459 free_node(p, if_node_size);
1463 change_if_limit(or_code, savecondptr);
1469 if (tracing_commands > 1)
1474 print_string("{true}");
1476 print_string("{false}");
1478 end_diagnostic(false);
1481 if (b) /* b may be used without ... */
1483 change_if_limit(else_code, savecondptr);
1491 if (cond_ptr == savecondptr)
1493 if (cur_chr != or_code)
1496 print_err("Extra ");
1498 help1("I'm ignoring this; it doesn't match any \\if.");
1501 else if (cur_chr == fi_code)
1504 if_line = if_line_field(p);
1505 cur_if = subtype(p);
1508 free_node(p, if_node_size);
1513 if (cur_chr == fi_code)
1516 if_line = if_line_field(p);
1517 cur_if = subtype(p);
1520 free_node(p, if_node_size);
1526 void begin_name (void)
1528 area_delimiter = 0; /* index between `file area' and `file name' */
1529 ext_delimiter = 0; /* index between `file name' and `file extension' */
1531 /* This gathers up a file name and makes a string of it */
1532 /* Also tries to break it into `file area' `file name' and `file extension' */
1533 /* Used by scan_file_name and prompt_file_name */
1534 /* We assume tilde has been converted to pseudo_tilde and space to pseudo_space */
1535 /* returns false if it is given a space character - end of file name */
1537 bool more_name_(ASCII_code c)
1539 if (quoted_file_name == 0 && c == ' ')
1541 else if (quoted_file_name != 0 && c == '"')
1543 quoted_file_name = 0; /* catch next space character */
1544 return true; /* accept ending quote, but throw away */
1548 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1549 /* convert pseudo tilde back to '~' 95/Sep/26 */ /* moved here 97/June/5 */
1550 /* if (pseudo_tilde != 0 && c == pseudo_tilde) c = '~'; */
1551 /* convert pseudo space back to ' ' 97/June/5 */ /* moved here 97/June/5 */
1552 /* if (pseudo_space != 0 && c == pseudo_space) c = ' '; */
1553 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1556 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1557 // if ((c == 47)) /* / */
1559 if ((c == '/' || c == '\\' || c == ':')) /* 94/Mar/1 */
1560 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1562 area_delimiter = cur_length;
1566 ext_delimiter = cur_length;
1570 /******************************** 2000 August 15th start ***********************/
1572 // The following code is to save string space used by TeX for filenames
1573 // Not really critical in a system that has dynamic memory allocation
1574 // And may slow it down slightly - although this linear search only
1575 // occurs when opening a file, which is somewhat slow inany case...
1577 // see if string from str_pool[start] to str_pool[end]
1578 // occurs elsewhere in string pool - returns string number
1579 // returns -1 if not found in string pool 2000 Aug 15
1581 int find_string (int start, int end)
1583 int k, nlen = end - start;
1586 // int trace_flag = 1; // debugging only
1590 sprintf(log_line, "\nLOOKING for string (str_ptr %d nlen %d) ", str_ptr, end - start);
1591 s = log_line + strlen(log_line);
1592 strncpy(s, (const char *) str_pool + start, nlen);
1593 strcpy(s + nlen, "");
1594 show_line(log_line, 0);
1597 // avoid problems with(cur_name == flushablestring)by going only up to str_ptr-1
1598 // code in new_font (tex8.c) will take care of reuse of font name already
1599 for (k = 0; k < str_ptr - 1; k++)
1601 if (length(k) != nlen)
1604 if (strncmp((const char *) str_pool + start, (const char *) str_pool + str_start[k], nlen) == 0)
1608 sprintf(log_line, "\nFOUND the string %d (%d) ", k, str_start[k+1]-str_start[k]);
1609 s = log_line + strlen(log_line);
1610 strncpy(s, (const char *)str_pool + start, nlen);
1611 strcpy(s+nlen, "\n");
1612 show_line(log_line, 0);
1614 return k; // return number of matching string
1620 sprintf(log_line, "\nNOT FOUND string ");
1621 s = log_line + strlen(log_line);
1622 strncpy(s, (const char*)str_pool + start, nlen);
1623 strcpy(s + nlen, "\n");
1624 show_line(log_line, 0);
1627 return -1; // no match found
1630 // snip out the string from str_pool[start] to str_pool[end]
1631 // and move everything above it down 2000 Aug 15
1633 void remove_string (int start, int end)
1635 int nlen = pool_ptr - end; // how many bytes to move down
1638 // int trace_flag=1; // debugging only
1639 // if (end < start) show_line("\nEND < START", 1);
1640 // if (pool_ptr < end) show_line("\nPOOLPTR < END", 1);
1644 int n = end - start;
1645 sprintf(log_line, "\nSTRIPPING OUT %d %d ", n, nlen);
1646 s = log_line + strlen(log_line);
1647 strncpy(s, (const char *)str_pool + start, n);
1648 strcpy(s + n, "\n");
1649 show_line(log_line, 0);
1653 memcpy(str_pool + start, str_pool + end, nlen);
1655 pool_ptr = start + nlen; // poolprt - (end-start);
1658 void show_string (int k)
1660 int nlen = length(k);
1663 sprintf(log_line, "\nSTRING %5d (%3d) %5d--%5d ",
1664 k, nlen, str_start[k], str_start[k+1]);
1665 s = log_line + strlen(log_line);
1666 strncpy(s, (const char *)str_pool + str_start[k], nlen);
1667 strcpy(s + nlen, "");
1668 show_line(log_line, 0);
1671 void show_all_strings (void)
1675 for (k = 0; k < str_ptr; k++)
1679 /********************************** 2000 August 15 end ****************************/
1681 void end_name (void)
1683 #ifdef ALLOCATESTRING
1684 if (str_ptr + 3 > current_max_strings)
1685 str_start = realloc_str_start(increment_max_strings + 3);
1687 if (str_ptr + 3 > current_max_strings)
1689 overflow("number of strings", current_max_strings - init_str_ptr); /* 97/Mar/7 */
1690 return; // abort_flag set
1693 if (str_ptr + 3 > max_strings)
1695 overflow("number of strings", max_strings - init_str_ptr); /* number of strings */
1696 return; // abort_flag set
1700 // if (notfirst++ == 0) show_all_strings(); // debugging only
1702 if (area_delimiter == 0) // no area delimiter ':' '/' or '\' found
1703 cur_area = 335; // "" default area
1706 if (save_strings_flag && (cur_area = find_string(str_start[str_ptr], str_start[str_ptr] + area_delimiter)) > 0)
1708 remove_string(str_start[str_ptr], str_start[str_ptr] + area_delimiter);
1709 area_delimiter = 0; // area_delimiter - area_delimiter;
1711 if (ext_delimiter != 0)
1712 ext_delimiter = ext_delimiter - area_delimiter;
1714 // str_start[str_ptr + 1]= str_start[str_ptr]+ area_delimiter; // test only
1715 // incr(str_ptr); // test only
1717 else // carve out string for "cur_area"
1720 str_start[str_ptr + 1] = str_start[str_ptr] + area_delimiter;
1725 if (ext_delimiter == 0) // no extension delimiter '.' found
1727 cur_ext = 335; // "" default extension
1729 if (save_strings_flag && (cur_name = find_string(str_start[str_ptr], pool_ptr)) > 0)
1731 remove_string(str_start[str_ptr], pool_ptr);
1732 // (void) make_string(); // test only
1734 else // Make string from str_start[str_ptr]to pool_ptr
1735 cur_name = make_string();
1737 else // did find an extension
1739 if (save_strings_flag &&
1740 (cur_name = find_string(str_start[str_ptr], str_start[str_ptr] + ext_delimiter - area_delimiter-1)) > 0)
1742 remove_string(str_start[str_ptr], str_start[str_ptr] + ext_delimiter - area_delimiter - 1);
1743 // str_start[str_ptr + 1]= str_start[str_ptr]+ ext_delimiter - area_delimiter - 1; // test only
1744 // incr(str_ptr); // test only
1746 else // carve out string for "cur_name"
1749 str_start[str_ptr + 1]= str_start[str_ptr]+ ext_delimiter - area_delimiter - 1;
1753 if (save_strings_flag && (cur_ext = find_string(str_start[str_ptr], pool_ptr)) > 0)
1755 remove_string(str_start[str_ptr], pool_ptr);
1756 // (void) make_string(); // test only
1758 else // Make string from str_start[str_ptr]to pool_ptr
1759 cur_ext = make_string();
1763 /* n current name, a current area, e current extension */
1764 /* result in name_of_file[] */
1766 void pack_file_name_(str_number n, str_number a, str_number e)
1774 for (j = str_start[a]; j <= str_start[a + 1] - 1; j++)
1780 name_of_file[k] = xchr[c];
1783 for (j = str_start[n]; j <= str_start[n + 1] - 1; j++)
1789 name_of_file[k] = xchr[c];
1792 for (j = str_start[e]; j <= str_start[e + 1] - 1; j++)
1798 name_of_file[k] = xchr[c];
1804 name_length = PATHMAX - 1;
1806 /* pad it out with spaces ... what for ? in case we modify and forget ? */
1807 for (k = name_length + 1; k <= PATHMAX; k++)
1808 name_of_file[k] = ' ';
1810 name_of_file[PATHMAX] = '\0'; /* paranoia 94/Mar/24 */
1813 name_of_file [name_length+1] = '\0';
1817 sprintf(log_line, " pack_file_name `%s' (%d) ", name_of_file + 1, name_length); /* debugging */
1818 show_line(log_line, 0);
1821 name_of_file [name_length + 1] = ' ';
1824 /* Called only from two places tex9.c for format name - specified and default */
1825 /* for specified format name args are 0, a, b name in buffer[a] --- buffer[b] */
1826 /* for default args are format_default_length-4, 1, 0 */
1828 void pack_buffered_name_(small_number n, integer a, integer b)
1834 if (n + b - a + 5 > PATHMAX)
1835 b = a + PATHMAX - n - 5;
1839 /* This loop kicks in when we want the default format name */
1840 for (j = 1; j <= n; j++)
1842 c = xord[TEX_format_default[j]];
1846 name_of_file[k] = xchr[c];
1848 /* This loop kicks in when we want a specififed format name */
1849 for (j = a; j <= b; j++)
1855 name_of_file[k] = xchr[c];
1858 /* This adds the extension from the default format name */
1859 for (j = format_default_length - 3; j <= format_default_length; j++)
1861 c = xord[TEX_format_default[j]];
1865 name_of_file[k] = xchr[c];
1871 name_length = PATHMAX - 1;
1873 /* pad it out with spaces ... what for ? */
1874 for (k = name_length + 1; k <= PATHMAX; k++)
1875 name_of_file[k]= ' ';
1877 name_of_file[PATHMAX] = '\0'; /* paranoia 94/Mar/24 */
1880 str_number make_name_string (void)
1884 #ifdef ALLOCATESTRING
1885 if (pool_ptr + name_length > current_pool_size)
1886 str_pool = realloc_str_pool(increment_pool_size + name_length);
1888 if (str_ptr == current_max_strings)
1889 str_start = realloc_str_start(increment_max_strings);
1891 if ((pool_ptr + name_length > current_pool_size) || (str_ptr == current_max_strings) || (cur_length > 0))
1893 if ((pool_ptr + name_length > pool_size) || (str_ptr == max_strings) || (cur_length > 0))
1900 for (k = 1; k <= name_length; k++)
1901 append_char(xord[name_of_file[k]]);
1903 return make_string();
1907 str_number a_make_name_string_(alpha_file * f)
1909 return make_name_string();
1912 str_number b_make_name_string_(byte_file * f)
1914 return make_name_string();
1917 str_number w_make_name_string_(word_file * f)
1919 return make_name_string();
1922 /* Used by start_input to scan file name on command line */
1923 /* Also in tex8.c new_font_, open_or_close_in, and do_extension */
1925 void scan_file_name (void)
1927 name_in_progress = true;
1934 while (!(cur_cmd != spacer));
1936 quoted_file_name = false;
1938 if (allow_quoted_names)
1942 quoted_file_name = 1;
1949 if ((cur_cmd > other_char) || (cur_chr > 255))
1955 if (!more_name(cur_chr)) /* up to next white space */
1963 name_in_progress = false;
1965 /* argument is string .fmt, .log, or .dvi */
1967 void pack_job_name_(str_number s)
1969 cur_area = 335; /* "" */
1971 cur_name = job_name;
1972 pack_file_name(cur_name, cur_area, cur_ext);
1975 /**********************************************************************/
1976 /* show TEXINPUTS=... or format specific */
1977 /* only show this if name was not fully qualified ? */
1978 void show_tex_inputs (void)
1982 s = "TEXINPUTS"; /* default */
1984 if (format_specific)
1986 s = format_name; /* try specific */
1988 if (grabenv(s) == NULL)
1989 s = "TEXINPUTS"; /* no format specific */
1992 if (grabenv(s) == NULL)
1993 s = "TEXINPUT"; /* 94/May/19 */
2017 /**********************************************************************/
2019 /* s - what can't be found, e - default */
2020 void prompt_file_name_(char * s, str_number e)
2024 if (interaction == scroll_mode);
2026 if (!strcmp("input file name", s))
2027 print_err("I can't find file `");
2029 print_err("I can't write on file `");
2031 print_file_name(cur_name, cur_area, cur_ext);
2034 if (!strcmp("input file name", s))
2036 if (cur_area == 335) /* "" only if path not specified */
2038 if (show_texinput_flag)
2043 if (e == 785) /* .tex */
2046 print_nl("Please type another ");
2049 if (interaction < 2)
2051 fatal_error("*** (job aborted, file error in nonstop mode)");
2052 return; // abort_flag set
2057 show_line(" (or ^z to exit)", 0);
2059 show_line(" (or Ctrl-Z to exit)", 0);
2063 term_input(": ", 0);
2065 /* should we deal with tilde and space in file name here ??? */
2070 while ((buffer[k] == ' ') && (k < last))
2072 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2073 quoted_file_name = 0; /* 98/March/15 */
2075 if (allow_quoted_names && k < last) /* check whether quoted name */
2077 if (buffer[k]== '"')
2079 quoted_file_name = 1;
2088 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2089 /* convert tilde '~' to pseudo tilde */
2090 if (pseudo_tilde != 0 && buffer[k]== '~')
2091 buffer[k] = pseudo_tilde;
2092 /* convert space ' ' to pseudo space */
2093 if (pseudo_space != 0 && buffer[k]== ' ')
2094 buffer[k] = pseudo_space;
2095 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2096 if (!more_name(buffer[k]))
2105 if (cur_ext == 335) /* "" */
2106 cur_ext = e; /* use default extension */
2108 pack_file_name(cur_name, cur_area, cur_ext);
2111 void open_log_file (void)
2118 old_setting = selector;
2123 pack_job_name(".log");
2125 while (!a_open_out(log_file))
2127 selector = term_only;
2128 prompt_file_name("transcript file name", ".log");
2131 texmf_log_name = a_make_name_string(log_file);
2132 selector = log_only;
2139 strcat(log_line, "\n");
2140 (void) fputs(log_line, log_file);
2141 stampcopy(log_line);
2142 strcat(log_line, "\n");
2143 (void) fputs(log_line, log_file);
2146 (void) fputs(tex_version, log_file);
2147 (void) fprintf(log_file, " (%s %s)", application, yandyversion);
2149 if (format_ident > 0)
2150 slow_print(format_ident);
2160 months = " JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
2162 for (k = 3 * month - 2; k <= 3 * month; k++)
2163 (void) putc(months[k], log_file);
2173 print_two(tex_time / 60);
2175 print_two(tex_time % 60);
2178 input_stack[input_ptr] = cur_input;
2180 l = input_stack[0].limit_field;
2182 if (buffer[l] == end_line_char)
2185 for (k = 1; k <= l; k++)
2192 if (format_file != NULL)
2194 fprintf(log_file, "(%s)\n", format_file);
2200 selector = old_setting + 2;
2203 /**************************** start of insertion 98/Feb/7 **************/
2204 // Attempt to deal with foo.bar.tex given as foo.bar on command line
2205 // Makes copy of job_name with extension
2207 void more_name_copy(ASCII_code c)
2209 #ifdef ALLOCATESTRING
2210 if (pool_ptr + 1 > current_pool_size)
2211 str_pool = realloc_str_pool (increment_pool_size);
2213 if (pool_ptr + 1 > current_pool_size)
2215 overflow("pool size", current_pool_size - init_pool_ptr);
2219 if (pool_ptr + 1 > pool_size)
2221 overflow("pool size", pool_size - init_pool_ptr);
2226 str_pool[pool_ptr] = c;
2230 int end_name_copy(void)
2232 #ifdef ALLOCATESTRING
2233 if (str_ptr + 1 > current_max_strings)
2234 str_start = realloc_str_start(increment_max_strings + 1);
2236 if (str_ptr + 1 > current_max_strings)
2238 overflow("number of strings", current_max_strings - init_str_ptr);
2242 if (str_ptr + 1 > max_strings)
2244 overflow("number of strings", max_strings - init_str_ptr);
2249 return make_string();
2252 void job_name_append (void)
2256 k = str_start[job_name];
2257 n = str_start[job_name + 1];
2260 more_name_copy(str_pool[k++]);
2262 k = str_start[cur_ext];
2263 n = str_start[cur_ext + 1];
2266 more_name_copy(str_pool[k++]);
2268 job_name = end_name_copy();
2271 /**************************** end of insertion 98/Feb/7 **************/
2273 void start_input(void)
2275 bool added_extension = false;
2278 pack_file_name(cur_name, cur_area, cur_ext);
2282 added_extension = false;
2283 begin_file_reading();
2285 if ((cur_ext != 335) && a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2288 if ((cur_ext != 785) && (name_length + 5 < PATHMAX))
2290 name_of_file[name_length + 1] = '.';
2291 name_of_file[name_length + 2] = 't';
2292 name_of_file[name_length + 3] = 'e';
2293 name_of_file[name_length + 4] = 'x';
2294 name_of_file[name_length + 5] = ' ';
2295 name_length = name_length + 4;
2297 added_extension = true;
2299 if (a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2302 name_length = name_length - 4;
2303 name_of_file[name_length + 1] = ' ';
2304 added_extension = false;
2307 if ((cur_ext == 335) && a_open_in(input_file[cur_input.index_field], TEXINPUTPATH))
2311 prompt_file_name("input file name", ".tex");
2315 cur_input.name_field = a_make_name_string(input_file[cur_input.index_field]);
2319 job_name = cur_name;
2321 if (cur_ext != 335 && added_extension)
2327 if (term_offset + length(cur_input.name_field) > max_print_line - 2)
2329 else if ((term_offset > 0) || (file_offset > 0))
2335 if (open_parens > max_open_parens)
2336 max_open_parens = open_parens;
2338 slow_print(cur_input.name_field);
2344 cur_input.state_field = new_line;
2349 if (input_ln(input_file[cur_input.index_field], false));
2353 if ((end_line_char < 0) || (end_line_char > 255))
2354 decr(cur_input.limit_field);
2356 buffer[cur_input.limit_field] = end_line_char;
2358 first = cur_input.limit_field + 1;
2359 cur_input.loc_field = cur_input.start_field;
2363 /**********************************************************************/
2364 /* show TEXFONTS=... or format specific */
2365 /* only show this if name was not fully qualified ? */
2366 void show_tex_fonts (void)
2368 char *s, *t, *v, *u;
2373 if (encoding_specific)
2375 u = encoding_name; /* try specific */
2377 if ((t = grabenv(u)) != NULL)
2379 if (strchr(t, ':') != NULL && sscanf(t, "%d", &n) == 0)
2381 s = u; /* look here instead of TEXFONTS=... */
2408 internal_font_number read_font_info_(halfword u, str_number nom, str_number aire, scaled s)
2412 /* halfword lf, lh, bc, ec, nw, nh, nd, ni, nl, nk, ne, np; */
2413 halfword lf, lh, nw, nh, nd, ni, nl, nk, ne, np;
2414 /* halfword bc, ec; */
2415 int bc, ec; /* 95/Jan/7 */
2416 internal_font_number f;
2417 internal_font_number g;
2418 eight_bits a, b, c, d;
2429 pack_file_name(nom, aire, 805); /* .tfm */
2431 if (!b_open_in(tfm_file)) /* new in C version d */
2435 /* was just: goto lab11; */
2438 /* tfm_temp = getc(tfm_file); */ /* done already in open_input, but why? */
2439 //tfm_temp = getc(tfm_file);
2444 tfm_temp = getc(tfm_file);
2445 lf = lf * 256 + tfm_temp;
2447 tfm_temp = getc(tfm_file);
2452 tfm_temp = getc(tfm_file);
2453 lh = lh * 256 + tfm_temp;
2455 tfm_temp = getc(tfm_file);
2460 tfm_temp = getc(tfm_file);
2461 bc = bc * 256 + tfm_temp;
2463 tfm_temp = getc(tfm_file);
2468 tfm_temp = getc(tfm_file);
2469 ec = ec * 256 + tfm_temp;
2471 if ((bc > ec + 1)||(ec > 255))
2478 tfm_temp = getc(tfm_file);
2483 tfm_temp = getc(tfm_file);
2484 nw = nw * 256 + tfm_temp;
2486 tfm_temp = getc(tfm_file);
2491 tfm_temp = getc(tfm_file);
2492 nh = nh * 256 + tfm_temp;
2494 tfm_temp = getc(tfm_file);
2499 tfm_temp = getc(tfm_file);
2500 nd = nd * 256 + tfm_temp;
2502 tfm_temp = getc(tfm_file);
2507 tfm_temp = getc(tfm_file);
2508 ni = ni * 256 + tfm_temp;
2510 tfm_temp = getc(tfm_file);
2515 tfm_temp = getc(tfm_file);
2516 nl = nl * 256 + tfm_temp;
2518 tfm_temp = getc(tfm_file);
2523 tfm_temp = getc(tfm_file);
2524 nk = nk * 256 + tfm_temp;
2526 tfm_temp = getc(tfm_file);
2531 tfm_temp = getc(tfm_file);
2532 ne = ne * 256 + tfm_temp;
2534 tfm_temp = getc(tfm_file);
2539 tfm_temp = getc(tfm_file);
2540 np = np * 256 + tfm_temp;
2542 if (lf != 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np)
2545 if ((nw == 0) || (nh == 0) || (nd == 0) || (ni == 0))
2553 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2555 if ((fmem_ptr + lf > current_font_mem_size)) /* 93/Nov/28 */
2556 font_info = realloc_font_info (increment_font_mem_size + lf);
2558 if ((font_ptr == font_max) || (fmem_ptr + lf > current_font_mem_size))
2560 if ((font_ptr == font_max) || (fmem_ptr + lf > font_mem_size))
2565 sprintf(log_line, "font_ptr %d font_max %d fmem_ptr %d lf %d font_mem_size %d\n",
2566 font_ptr, font_max, fmem_ptr, lf, font_mem_size); /* debugging */
2567 show_line(log_line, 0);
2573 print_file_name(nom, aire, 335); /* "" */
2577 print_string(" at ");
2581 else if (s != -1000)
2583 print_string(" scaled ");
2584 print_int(- (integer) s);
2587 print_string(" not loaded: Not enough room left");
2588 help4("I'm afraid I won't be able to make use of this font,",
2589 "because my memory for character-size data is too small.",
2590 "If you're really stuck, ask a wizard to enlarge me.",
2591 "Or maybe try `I\\font<same font id>=<name of loaded font>'.");
2597 char_base[f] = fmem_ptr - bc;
2598 width_base[f] = char_base[f] + ec + 1;
2599 height_base[f] = width_base[f] + nw;
2600 depth_base[f] = height_base[f] + nh;
2601 italic_base[f] = depth_base[f] + nd;
2602 lig_kern_base[f] = italic_base[f] + ni;
2603 kern_base[f] = lig_kern_base[f] + nl - 256 * (128);
2604 exten_base[f] = kern_base[f] + 256 * (128) + nk;
2605 param_base[f] = exten_base[f] + ne;
2610 /* build the font checksum now */
2612 tfm_temp = getc(tfm_file);
2615 tfm_temp = getc(tfm_file);
2618 tfm_temp = getc(tfm_file);
2621 tfm_temp = getc(tfm_file);
2627 tfm_temp = getc(tfm_file);
2632 tfm_temp = getc(tfm_file);
2633 z = z * 256 + tfm_temp;
2636 tfm_temp = getc(tfm_file);
2637 z = z * 256 + tfm_temp;
2638 tfm_temp = getc(tfm_file);
2639 z =(z * 16) + (tfm_temp / 16);
2646 tfm_temp = getc(tfm_file);
2647 tfm_temp = getc(tfm_file);
2648 tfm_temp = getc(tfm_file);
2649 tfm_temp = getc(tfm_file);
2659 z = xn_over_d(z, - (integer) s, 1000);
2664 for (k = fmem_ptr; k <= width_base[f] - 1; k++)
2667 tfm_temp = getc(tfm_file);
2670 tfm_temp = getc(tfm_file);
2673 tfm_temp = getc(tfm_file);
2676 tfm_temp = getc(tfm_file);
2679 font_info[k].qqqq = qw;
2682 if ((a >= nw) || (b / 16 >= nh) || (b % 16 >= nd) || (c / 4 >= ni))
2700 if ((d < bc)||(d > ec))
2704 while (d < k + bc - fmem_ptr)
2706 qw = font_info[char_base[f]+ d].qqqq;
2708 if (((qw.b2)% 4)!= 2)
2714 if (d == k + bc - fmem_ptr)
2728 while (z >= 8388608L) /* 2^23 */
2731 alpha = alpha + alpha;
2734 beta = (char) (256 / alpha);
2738 for (k = width_base[f]; k <= lig_kern_base[f] - 1; k++)
2740 tfm_temp = getc(tfm_file);
2742 tfm_temp = getc(tfm_file);
2744 tfm_temp = getc(tfm_file);
2746 tfm_temp = getc(tfm_file);
2748 sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2751 font_info[k].cint = sw;
2753 font_info[k].cint = sw - alpha;
2758 if (font_info[width_base[f]].cint != 0)
2761 if (font_info[height_base[f]].cint != 0)
2764 if (font_info[depth_base[f]].cint != 0)
2767 if (font_info[italic_base[f]].cint != 0)
2770 /* read ligature/kern program */
2771 bchlabel = 32767; /* '77777 */
2776 for (k = lig_kern_base[f]; k <= kern_base[f] + 256 * (128) - 1; k++)
2779 tfm_temp = getc(tfm_file);
2782 tfm_temp = getc(tfm_file);
2785 tfm_temp = getc(tfm_file);
2788 tfm_temp = getc(tfm_file);
2791 font_info[k].qqqq = qw; /* store_four_quarters(font_info[k].qqqq */
2796 if (256 * c + d >= nl)
2797 goto lab11; /* error in TFM, abort */
2800 if (k == lig_kern_base[f])
2808 if ((b < bc) || (b > ec)) /* check-existence(b) */
2809 goto lab11; /* error in TFM, abort */
2812 qw = font_info[char_base[f] + b].qqqq;
2815 goto lab11; /* error in TFM, abort */
2821 if ((d < bc) || (d > ec)) /* check-existence(d) */
2822 goto lab11; /* error in TFM, abort */
2825 qw = font_info[char_base[f] + d].qqqq;
2828 goto lab11; /* error in TFM, abort */
2830 else if (256 * (c - 128) + d >= nk)
2831 goto lab11; /* error in TFM, abort */
2833 if (k - lig_kern_base[f] + a + 1 >= nl)
2834 goto lab11; /* error in TFM, abort */
2839 bchlabel = 256 * c + d;
2842 for (k = kern_base[f] + 256 * (128); k <= exten_base[f] - 1; k++)
2844 tfm_temp = getc(tfm_file);
2846 tfm_temp = getc(tfm_file);
2848 tfm_temp = getc(tfm_file);
2850 tfm_temp = getc(tfm_file);
2852 sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2855 font_info[k].cint = sw;
2857 font_info[k].cint = sw - alpha;
2860 /* read extensible character recipes */
2861 /* for k:=exten_base[f] to param_base[f]-1 do */
2862 for (k = exten_base[f]; k <= param_base[f] - 1; k++)
2865 tfm_temp = getc(tfm_file);
2868 tfm_temp = getc(tfm_file);
2871 tfm_temp = getc(tfm_file);
2874 tfm_temp = getc(tfm_file);
2877 /* store_four_quarters(font_info[k].qqqq); */
2878 font_info[k].qqqq = qw;
2884 if ((a < bc) || (a > ec))
2888 qw = font_info[char_base[f] + a].qqqq;
2897 if ((b < bc) || (b > ec))
2901 qw = font_info[char_base[f] + b].qqqq;
2910 if ((c < bc) || (c > ec))
2914 qw = font_info[char_base[f] + c].qqqq;
2921 if ((d < bc) || (d > ec))
2925 qw = font_info[char_base[f] + d].qqqq;
2932 for (k = 1; k <= np; k++)
2935 tfm_temp = getc(tfm_file);
2941 tfm_temp = getc(tfm_file);
2942 sw = sw * 256 + tfm_temp;
2943 tfm_temp = getc(tfm_file);
2944 sw = sw * 256 + tfm_temp;
2945 tfm_temp = getc(tfm_file);
2946 font_info[param_base[f]].cint = (sw * 16) + (tfm_temp / 16);
2950 tfm_temp = getc(tfm_file);
2952 tfm_temp = getc(tfm_file);
2954 tfm_temp = getc(tfm_file);
2956 tfm_temp = getc(tfm_file);
2958 sw = (((((d * z) / 256) + (c * z)) / 256) + (b * z)) / beta;
2961 font_info[param_base[f] + k - 1].cint = sw;
2963 font_info[param_base[f] + k - 1].cint = sw - alpha;
2970 for (k = np + 1; k <= 7; k++)
2971 font_info[param_base[f] + k - 1].cint = 0;
2975 font_params[f] = np;
2979 hyphen_char[f] = default_hyphen_char;
2980 skew_char[f] = default_skew_char;
2983 bchar_label[f] = bchlabel + lig_kern_base[f];
2985 bchar_label[f] = non_address;
2987 font_bchar[f] = bchar;
2988 font_false_bchar[f] = bchar;
2993 qw = font_info[char_base[f] + bchar].qqqq;
2996 font_false_bchar[f] = 256;
3000 font_area[f] = aire;
3004 char_base[f] = char_base[f];
3005 width_base[f] = width_base[f];
3006 lig_kern_base[f] = lig_kern_base[f];
3007 kern_base[f] = kern_base[f];
3008 exten_base[f] = exten_base[f];
3009 decr(param_base[f]);
3010 fmem_ptr = fmem_ptr + lf;
3019 print_file_name(nom, aire, 335);
3023 print_string(" at ");
3027 else if (s != -1000)
3029 print_string("scaled");
3030 print_int(- (integer) s);
3034 print_string(" not loadable: Bad metric (TFM) file");
3036 print_string(" not loadable: Metric (TFM) file not found");
3040 if (show_texinput_flag)
3044 help5("I wasn't able to read the size data for this font,",
3045 "so I will ignore the font specification.",
3046 "[Wizards can fix TFM files using TFtoPL/PLtoTF.]",
3047 "You might try inserting a different font spec;",
3048 "e.g., type `I\\font<same font id>=<substitute font name>'.");