OSDN Git Service

updated.
[putex/putex.git] / src / texsourc / tex3.c
1 /* Copyright 2014 Clerk Ma\r
2 \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
7 \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
12 \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
16    02110-1301 USA.  */\r
17 \r
18 #define EXTERN extern\r
19 \r
20 #include "yandytex.h"\r
21 \r
22 /* sec 0440 */\r
23 void scan_int (void)\r
24 {\r
25   boolean negative;\r
26   integer m;\r
27   small_number d;\r
28   boolean vacuous;\r
29   boolean OK_so_far;\r
30 \r
31   radix = 0;\r
32   OK_so_far = true;\r
33   negative = false;\r
34 \r
35   do\r
36     {\r
37       do \r
38         {\r
39           get_x_token();\r
40         }\r
41       while (!(cur_cmd != spacer));\r
42 \r
43       if (cur_tok == other_token + '-')\r
44       {\r
45         negative = !negative;\r
46         cur_tok = other_token + '+';\r
47       }\r
48     }\r
49   while (!(cur_tok != other_token + '+'));\r
50 \r
51   if (cur_tok == alpha_token)\r
52   {\r
53     get_token();\r
54 \r
55     if (cur_tok < cs_token_flag)\r
56     {\r
57       cur_val = cur_chr;\r
58 \r
59       if (cur_cmd <= right_brace)\r
60         if (cur_cmd == right_brace)\r
61           incr(align_state);\r
62         else\r
63           decr(align_state);\r
64     }\r
65     else if (cur_tok < cs_token_flag + single_base)\r
66       cur_val = cur_tok - cs_token_flag - active_base;\r
67     else\r
68       cur_val = cur_tok - cs_token_flag - single_base;\r
69 \r
70     if (cur_val > 255)\r
71     {\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
75       cur_val = '0';\r
76       back_error();\r
77     }\r
78     else\r
79     {\r
80       get_x_token();\r
81 \r
82       if (cur_cmd != spacer)\r
83         back_input();\r
84     }\r
85   }\r
86   else if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))\r
87   {\r
88     scan_something_internal(int_val, false);\r
89   }\r
90   else\r
91   {\r
92     radix = 10;\r
93     m = 214748364L;   /* 7FFFFFFF hex */\r
94 \r
95     if (cur_tok == octal_token)\r
96     {\r
97       radix = 8;\r
98       m = 268435456L;   /* 2^28 */\r
99       get_x_token();\r
100     }\r
101     else if (cur_tok == hex_token)\r
102     {\r
103       radix = 16;\r
104       m = 134217728L;   /* 2^27 8000000 hex */\r
105       get_x_token();\r
106     }\r
107 \r
108     vacuous = true;\r
109     cur_val = 0;\r
110 \r
111     while (true)\r
112     {\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
120         else\r
121           goto done;\r
122       else\r
123         goto done;\r
124 \r
125       vacuous = false;\r
126 \r
127       if ((cur_val >= m) && ((cur_val > m) || (d > 7) || (radix != 10)))\r
128       {\r
129         if (OK_so_far)\r
130         {\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
134           error();\r
135           cur_val = 2147483647L;    /* 7FFFFFFF hex */\r
136           OK_so_far = false;\r
137         }\r
138       }\r
139       else\r
140         cur_val = cur_val * radix + d;\r
141 \r
142       get_x_token();\r
143     }\r
144 \r
145 done:\r
146     if (vacuous)\r
147     {\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
152       back_error();\r
153     } \r
154     else if (cur_cmd != spacer)\r
155       back_input();\r
156   }\r
157 \r
158   if (negative)\r
159     cur_val = - (integer) cur_val;\r
160 }\r
161 /* sec 0448 */\r
162 void scan_dimen (boolean mu, boolean inf, boolean shortcut)\r
163 {\r
164   boolean negative;\r
165   integer f;\r
166   integer num, denom;\r
167   small_number k, kk;\r
168   halfword p, q;\r
169   scaled v;\r
170   integer save_cur_val;\r
171 \r
172   f = 0;\r
173   arith_error = false;\r
174   cur_order = normal;\r
175   negative = false;\r
176 \r
177   if (!shortcut)\r
178   {\r
179     negative = false;\r
180 \r
181     do\r
182       {\r
183         do\r
184           {\r
185             get_x_token();\r
186           }\r
187         while (!(cur_cmd != spacer));\r
188 \r
189         if (cur_tok == other_token + '-')\r
190         {\r
191           negative = ! negative;\r
192           cur_tok = other_token + '+';\r
193         }\r
194       }\r
195     while (!(cur_tok != other_token + '+'));\r
196 \r
197     if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))\r
198     {\r
199       if (mu)\r
200       {\r
201         scan_something_internal(mu_val, false);\r
202 \r
203         if (cur_val_level >= glue_val)\r
204         {\r
205           v = width(cur_val);\r
206           delete_glue_ref(cur_val);\r
207           cur_val = v;\r
208         }\r
209 \r
210         if (cur_val_level == mu_val)\r
211           goto attach_sign;\r
212 \r
213         if (cur_val_level != int_val)\r
214           mu_error();\r
215       }\r
216       else\r
217       {\r
218         scan_something_internal(dimen_val, false);\r
219 \r
220         if (cur_val_level == dimen_val)\r
221           goto attach_sign;\r
222       }\r
223     }\r
224     else\r
225     {\r
226       back_input();\r
227 \r
228       if (cur_tok == continental_point_token)\r
229         cur_tok = point_token;\r
230 \r
231       if (cur_tok != point_token)\r
232       {\r
233         scan_int();\r
234       }\r
235       else\r
236       {\r
237         radix = 10;\r
238         cur_val = 0;\r
239       }\r
240 \r
241       if (cur_tok == continental_point_token)\r
242         cur_tok = point_token;\r
243 \r
244       if ((radix == 10) && (cur_tok == point_token))\r
245       {\r
246         k = 0;\r
247         p = 0;\r
248         get_token();\r
249 \r
250         while (true)\r
251         {\r
252           get_x_token();\r
253 \r
254           if ((cur_tok > zero_token + 9) || (cur_tok < zero_token))\r
255             goto done1;\r
256 \r
257           if (k < 17)\r
258           {\r
259             q = get_avail();\r
260             link(q) = p;\r
261             info(q) = cur_tok - zero_token;\r
262             p = q;\r
263             incr(k);\r
264           }\r
265         }\r
266 \r
267 done1:\r
268         for (kk = k; kk >= 1; kk--)\r
269         {\r
270           dig[kk - 1] = info(p);\r
271           q = p;\r
272           p = link(p);\r
273           free_avail(q);\r
274         }\r
275 \r
276         f = round_decimals(k);\r
277 \r
278         if (cur_cmd != spacer)\r
279           back_input();\r
280         }\r
281       }\r
282   }\r
283 \r
284   if (cur_val < 0)\r
285   {\r
286     negative = !negative;\r
287     cur_val = - (integer) cur_val;\r
288   }\r
289 \r
290   if (inf)\r
291   {\r
292     if (scan_keyword("fil"))\r
293     {\r
294       cur_order = fil;\r
295 \r
296       while (scan_keyword("l"))\r
297       {\r
298         if (cur_order == filll)\r
299         {\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
303           error();\r
304         }\r
305         else\r
306           incr(cur_order);\r
307       }\r
308 \r
309       goto attach_fraction;\r
310     }\r
311   }\r
312 \r
313   save_cur_val = cur_val;\r
314 \r
315   do\r
316     {\r
317       get_x_token();\r
318     }\r
319   while (!(cur_cmd != spacer));\r
320 \r
321   if ((cur_cmd < min_internal) || (cur_cmd > max_internal))\r
322     back_input();\r
323   else\r
324   {\r
325     if (mu)\r
326     {\r
327       scan_something_internal(mu_val, false);\r
328 \r
329       if (cur_val_level >= glue_val)\r
330       {\r
331         v = width(cur_val);\r
332         delete_glue_ref(cur_val);\r
333         cur_val = v;\r
334       }\r
335 \r
336       if (cur_val_level != mu_val)\r
337       {\r
338         mu_error();\r
339       }\r
340     }\r
341     else\r
342     {\r
343       scan_something_internal(dimen_val, false);\r
344     }\r
345 \r
346     v = cur_val;\r
347     goto found;\r
348   }\r
349 \r
350   if (mu)\r
351     goto not_found;\r
352 \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
357   else\r
358     goto not_found;\r
359 \r
360   {\r
361     get_x_token();\r
362 \r
363     if (cur_cmd != spacer)\r
364       back_input();\r
365   }\r
366 \r
367 found:\r
368   cur_val = nx_plus_y(save_cur_val, v, xn_over_d(v, f, 65536L));\r
369   goto attach_sign;\r
370 \r
371 not_found:\r
372   if (mu)\r
373   {\r
374     if (scan_keyword("mu"))\r
375       goto attach_fraction;\r
376     else\r
377     {\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
384       error();\r
385       goto attach_fraction;\r
386     }\r
387   }\r
388 \r
389   if (scan_keyword("true"))\r
390   {\r
391     prepare_mag();\r
392 \r
393     if (mag != 1000)\r
394     {\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
398       f = f % 65536L;\r
399     }\r
400   }\r
401 \r
402   if (scan_keyword("pt"))\r
403     goto attach_fraction;\r
404 \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
426     goto done;\r
427   else\r
428   {\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
437     error();\r
438     goto done2;\r
439   }\r
440 \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
444   f = f % 65536L;\r
445 \r
446 done2:\r
447 attach_fraction:\r
448   if (cur_val >= 16384)     /* 2^14 */\r
449     arith_error = true;\r
450   else\r
451     cur_val = cur_val * unity + f;\r
452 \r
453 done:\r
454   {\r
455     get_x_token();\r
456 \r
457     if (cur_cmd != spacer)\r
458       back_input();\r
459   }\r
460 \r
461 attach_sign:\r
462   if (arith_error || (abs(cur_val) >= 1073741824L)) /* 2^30 */\r
463   {\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
467     error();\r
468     cur_val = max_dimen;\r
469     arith_error = false;\r
470   }\r
471 \r
472   if (negative)\r
473     cur_val = - (integer) cur_val;\r
474 }\r
475 /* sec 0461 */\r
476 void scan_glue (small_number level)\r
477 {\r
478   boolean negative;\r
479   pointer q;\r
480   boolean mu;\r
481 \r
482   mu = (level == mu_val);\r
483   negative = false;\r
484 \r
485   do\r
486     {\r
487       do\r
488         {\r
489           get_x_token();\r
490         }\r
491       while (!(cur_cmd != spacer));\r
492 \r
493       if (cur_tok == other_token + '-')\r
494       {\r
495         negative = !negative;\r
496         cur_tok = other_token + '+';\r
497       }\r
498     }\r
499   while (!(cur_tok != other_token + '+'));\r
500 \r
501   if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))\r
502   {\r
503     scan_something_internal(level, negative);\r
504 \r
505     if (cur_val_level >= glue_val)\r
506     {\r
507       if (cur_val_level != level)\r
508         mu_error();\r
509 \r
510       return;\r
511     }\r
512 \r
513     if (cur_val_level == int_val)\r
514       scan_dimen(mu, false, true);\r
515     else if (level == mu_val)\r
516       mu_error();\r
517   }\r
518   else\r
519   {\r
520     back_input();\r
521     scan_dimen(mu, false, false);\r
522 \r
523     if (negative)\r
524       cur_val = - (integer) cur_val;\r
525   }\r
526 \r
527   q = new_spec(zero_glue);\r
528   width(q) = cur_val;\r
529 \r
530   if (scan_keyword("plus"))\r
531   {\r
532     scan_dimen(mu, true, false);\r
533     stretch(q) = cur_val;\r
534     stretch_order(q) = cur_order;\r
535   }\r
536 \r
537   if (scan_keyword("minus"))\r
538   {\r
539     scan_dimen(mu, true, false);\r
540     shrink(q) = cur_val;\r
541     shrink_order(q) = cur_order;\r
542   }\r
543 \r
544   cur_val = q;\r
545 }\r
546 /* sec 0463 */\r
547 pointer scan_rule_spec (void)\r
548 {\r
549   pointer q;\r
550 \r
551   q = new_rule();\r
552 \r
553   if (cur_cmd == vrule)\r
554     width(q) = default_rule;\r
555   else\r
556   {\r
557     height(q) = default_rule;\r
558     depth(q) = 0;\r
559   }\r
560 \r
561 reswitch:\r
562 \r
563   if (scan_keyword("width"))\r
564   {\r
565     scan_dimen(false, false, false);\r
566     width(q) = cur_val;\r
567     goto reswitch;\r
568   }\r
569 \r
570   if (scan_keyword("height"))\r
571   {\r
572     scan_dimen(false, false, false);\r
573     height(q) = cur_val;\r
574     goto reswitch;\r
575   }\r
576 \r
577   if (scan_keyword("depth"))\r
578   {\r
579     scan_dimen(false, false, false);\r
580     depth(q) = cur_val;\r
581     goto reswitch;\r
582   }\r
583 \r
584   return q;\r
585 }\r
586 /* sec 0464 */\r
587 pointer str_toks (pool_pointer b)\r
588 {\r
589   pointer p;\r
590   pointer q;\r
591   halfword t;\r
592   pool_pointer k;\r
593 \r
594   str_room(1);\r
595   p = temp_head;\r
596   link(p) = 0;\r
597   k = b;\r
598 \r
599   while (k < pool_ptr)\r
600   {\r
601     t = str_pool[k];\r
602 \r
603     if (t == ' ')\r
604       t = space_token;\r
605     else\r
606       t = other_token + t;\r
607 \r
608     fast_store_new_token(t);\r
609     incr(k);\r
610   }\r
611 \r
612   pool_ptr = b;\r
613 \r
614   return p;\r
615 }\r
616 /* sec 0465 */\r
617 pointer the_toks (void)\r
618 {\r
619   char old_setting;\r
620   pointer p, q, r;\r
621   pool_pointer b;\r
622 \r
623   get_x_token();\r
624   scan_something_internal(tok_val, false);\r
625 \r
626   if (cur_val_level >= ident_val)\r
627   {\r
628     p = temp_head;\r
629     link(p) = 0;\r
630 \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
634     {\r
635       r = link(cur_val);\r
636 \r
637       while (r != 0)\r
638       {\r
639         fast_store_new_token(info(r));\r
640         r = link(r);\r
641       }\r
642     }\r
643 \r
644     return p;\r
645   }\r
646   else\r
647   {\r
648     old_setting = selector;\r
649     selector = new_string;\r
650     b = pool_ptr;\r
651 \r
652     switch (cur_val_level)\r
653     {\r
654       case int_val:\r
655         print_int(cur_val);\r
656         break;\r
657 \r
658       case dimen_val:\r
659         {\r
660           print_scaled(cur_val);\r
661           prints("pt");\r
662         }\r
663         break;\r
664 \r
665       case glue_val:\r
666         {\r
667           print_spec(cur_val, "pt");\r
668           delete_glue_ref(cur_val);\r
669         }\r
670         break;\r
671 \r
672       case mu_val:\r
673         {\r
674           print_spec(cur_val, "mu");\r
675           delete_glue_ref(cur_val);\r
676         }\r
677         break;\r
678     }\r
679 \r
680     selector = old_setting;\r
681     return str_toks(b);\r
682   }\r
683 }\r
684 /* sec 0467 */\r
685 void ins_the_toks (void) \r
686\r
687   link(garbage) = the_toks();\r
688   ins_list(link(temp_head));\r
689 }\r
690 /* sec 0470 */\r
691 void conv_toks (void)\r
692 {\r
693   char old_setting;\r
694   char c;\r
695   small_number save_scanner_status;\r
696   pool_pointer b;\r
697 \r
698   c = cur_chr;\r
699 \r
700   switch (c)\r
701   {\r
702     case number_code:\r
703     case roman_numeral_code:\r
704       scan_int();\r
705       break;\r
706 \r
707     case string_code:\r
708     case meaning_code:\r
709       save_scanner_status = scanner_status;\r
710       scanner_status = 0;\r
711       get_token();\r
712       scanner_status = save_scanner_status;\r
713       break;\r
714 \r
715     case font_name_code:\r
716       scan_font_ident();\r
717       break;\r
718 \r
719     case job_name_code:\r
720       if (job_name == 0)\r
721         open_log_file();\r
722       break;\r
723   }\r
724 \r
725   old_setting = selector;\r
726   selector = new_string;\r
727   b = pool_ptr;\r
728 \r
729   switch (c)\r
730   {\r
731     case number_code:\r
732       print_int(cur_val);\r
733       break;\r
734 \r
735     case roman_numeral_code:\r
736       print_roman_int(cur_val);\r
737       break;\r
738 \r
739     case string_code:\r
740       if (cur_cs != 0)\r
741         sprint_cs(cur_cs);\r
742       else\r
743         print_char(cur_chr);\r
744       break;\r
745 \r
746     case meaning_code:\r
747       print_meaning();\r
748       break;\r
749 \r
750     case font_name_code:\r
751       print(font_name[cur_val]);\r
752 \r
753       if (font_size[cur_val] != font_dsize[cur_val])\r
754       {\r
755         prints(" at ");\r
756         print_scaled(font_size[cur_val]);\r
757         prints("pt");\r
758       }\r
759       break;\r
760 \r
761     case job_name_code:\r
762       print(job_name);\r
763       break;\r
764   }\r
765 \r
766   selector = old_setting;\r
767   link(garbage) = str_toks(b);\r
768   begin_token_list(link(temp_head), 4);\r
769 }\r
770 /* sec 0473 */\r
771 pointer scan_toks (boolean macro_def, boolean xpand)\r
772 {\r
773   halfword t;\r
774   halfword s;\r
775   pointer p;\r
776   pointer q;\r
777   halfword unbalance;\r
778   halfword hash_brace;\r
779 \r
780   if (macro_def)\r
781     scanner_status = defining;\r
782   else\r
783     scanner_status = absorbing;\r
784 \r
785   warning_index = cur_cs;\r
786   def_ref = get_avail();\r
787   token_ref_count(def_ref) = 0;\r
788   p = def_ref;\r
789   hash_brace = 0;\r
790   t = zero_token;\r
791 \r
792   if (macro_def)\r
793   {\r
794     while (true)\r
795     {\r
796       get_token();\r
797 \r
798       if (cur_tok < right_brace_limit)\r
799         goto done1;\r
800 \r
801       if (cur_cmd == mac_param)\r
802       {\r
803         s = match_token + cur_chr;\r
804         get_token();\r
805 \r
806         if (cur_cmd == left_brace)\r
807         {\r
808           hash_brace = cur_tok;\r
809           store_new_token(cur_tok);\r
810           store_new_token(end_match_token);\r
811           goto done;\r
812         }\r
813 \r
814         if (t == zero_token + 9)\r
815         {\r
816           print_err("You already have nine parameters");\r
817           help1("I'm going to ignore the # sign you just used.");\r
818           error();\r
819         }\r
820         else\r
821         {\r
822           incr(t);\r
823 \r
824           if (cur_tok != t)\r
825           {\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
829             back_error();\r
830           }\r
831 \r
832           cur_tok = s;\r
833         }\r
834       }\r
835 \r
836       store_new_token(cur_tok);\r
837     }\r
838 \r
839 done1:\r
840     store_new_token(end_match_token);\r
841 \r
842     if (cur_cmd == right_brace)\r
843     {\r
844       print_err("Missing { inserted");\r
845       incr(align_state);\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
848       error();\r
849       goto found;\r
850     }\r
851 done:;\r
852   }\r
853   else\r
854   {\r
855     scan_left_brace();\r
856   }\r
857 \r
858   unbalance = 1;\r
859 \r
860   while (true)\r
861   {\r
862     if (xpand)\r
863     {\r
864       while (true)\r
865       {\r
866         get_next();\r
867 \r
868         if (cur_cmd <= max_command)\r
869           goto done2;\r
870 \r
871         if (cur_cmd != the)\r
872         {\r
873           expand();\r
874         }\r
875         else\r
876         {\r
877           q = the_toks();\r
878 \r
879           if (link(temp_head) != 0)\r
880           {\r
881             link(p) = link(temp_head);\r
882             p = q;\r
883           }\r
884         }\r
885       }\r
886 done2:\r
887       x_token();\r
888     }\r
889     else\r
890       get_token();\r
891 \r
892     if (cur_tok < right_brace_limit)\r
893       if (cur_cmd < right_brace)\r
894         incr(unbalance);\r
895       else\r
896       {\r
897         decr(unbalance);\r
898 \r
899         if (unbalance == 0)\r
900           goto found;\r
901       }\r
902     else if (cur_cmd == mac_param)\r
903       if (macro_def)\r
904       {\r
905         s = cur_tok;\r
906 \r
907         if (xpand)\r
908           get_x_token();\r
909         else\r
910           get_token();\r
911 \r
912         if (cur_cmd != mac_param)\r
913           if ((cur_tok <= zero_token) || (cur_tok > t))\r
914           {\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
920             back_error();\r
921             cur_tok = s;\r
922           }\r
923           else\r
924             cur_tok = out_param_token - '0' + cur_chr;\r
925       }\r
926 \r
927     store_new_token(cur_tok);\r
928   }\r
929 \r
930 found:\r
931   scanner_status = 0;\r
932 \r
933   if (hash_brace != 0)\r
934     store_new_token(hash_brace);\r
935 \r
936   return p;\r
937 }\r
938 /* sec 0482 */\r
939 void read_toks (integer n, pointer r)\r
940 {\r
941   pointer p;\r
942   pointer q;\r
943   integer s;\r
944   /* small_number m; */\r
945   int m;\r
946 \r
947   scanner_status = defining;\r
948   warning_index = r;\r
949   def_ref = get_avail();\r
950   token_ref_count(def_ref) = 0;\r
951   p = def_ref;\r
952   store_new_token(end_match_token);\r
953 \r
954   if ((n < 0) || (n > 15))\r
955     m = 16;\r
956   else\r
957     m = n;\r
958 \r
959   s = align_state;\r
960   align_state = 1000000L;\r
961 \r
962   do\r
963     {\r
964       begin_file_reading();\r
965       name = m + 1;\r
966 \r
967       if (read_open[m] == closed)\r
968         if (interaction > nonstop_mode)\r
969           if (n < 0)\r
970             prompt_input("");\r
971           else\r
972           {\r
973             print_ln();\r
974             sprint_cs(r);\r
975             prompt_input("=");\r
976             n = -1;\r
977           }\r
978         else\r
979         {\r
980           fatal_error("*** (cannot \\read from terminal in nonstop modes)");\r
981           return;\r
982         }\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
986         else\r
987         {\r
988           a_close(read_file[m]);\r
989           read_open[m] = closed;\r
990         }\r
991       else\r
992       {\r
993         if (!input_ln(read_file[m], true))\r
994         {\r
995           a_close(read_file[m]);\r
996           read_open[m] = closed;\r
997 \r
998           if (align_state != 1000000L)\r
999           {\r
1000             runaway();\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
1005             error();\r
1006           }\r
1007         }\r
1008       }\r
1009 \r
1010       limit = last;\r
1011 \r
1012       if (end_line_char_inactive())\r
1013         decr(limit);\r
1014       else\r
1015         buffer[limit] = end_line_char;\r
1016 \r
1017       first = limit + 1;\r
1018       loc = start;\r
1019       state = new_line;\r
1020 \r
1021       while (true)\r
1022       {\r
1023         get_token();\r
1024 \r
1025         if (cur_tok == 0)\r
1026           goto done;\r
1027 \r
1028         if (align_state < 1000000L)\r
1029         {\r
1030           do\r
1031             {\r
1032               get_token();\r
1033             }\r
1034           while (!(cur_tok == 0));\r
1035 \r
1036           align_state = 1000000L;\r
1037           goto done;\r
1038         }\r
1039 \r
1040         store_new_token(cur_tok);\r
1041       }\r
1042 \r
1043 done:\r
1044       end_file_reading();\r
1045     }\r
1046   while (!(align_state == 1000000L));\r
1047 \r
1048   cur_val = def_ref;\r
1049   scanner_status = normal;\r
1050   align_state = s;\r
1051 }\r
1052 /* sec 0494 */\r
1053 void pass_text (void)\r
1054 {\r
1055   integer l;\r
1056   small_number save_scanner_status;\r
1057 \r
1058   save_scanner_status = scanner_status;\r
1059   scanner_status = skipping;\r
1060   l = 0;\r
1061   skip_line = line;\r
1062 \r
1063   while (true)\r
1064   {\r
1065     get_next();\r
1066 \r
1067     if (cur_cmd == fi_or_else)\r
1068     {\r
1069       if (l == 0)\r
1070         goto done;\r
1071 \r
1072       if (cur_chr == fi_code)\r
1073         decr(l);\r
1074     }\r
1075     else if (cur_cmd == if_test)\r
1076       incr(l);\r
1077   }\r
1078 \r
1079 done:\r
1080   scanner_status = save_scanner_status;\r
1081 }\r
1082 /* sec 0497 */\r
1083 void change_if_limit (small_number l, pointer p)\r
1084 {\r
1085   pointer q;\r
1086 \r
1087   if (p == cond_ptr)\r
1088     if_limit = l;\r
1089   else\r
1090   {\r
1091     q = cond_ptr;\r
1092 \r
1093     while (true)\r
1094     {\r
1095       if (q == 0)\r
1096       {\r
1097         confusion("if");\r
1098         return;\r
1099       }\r
1100 \r
1101       if (link(q) == p)\r
1102       {\r
1103         type(p) = l;\r
1104         return;\r
1105       }\r
1106 \r
1107       q = link(q);\r
1108     }\r
1109   }\r
1110 }\r
1111 /* sec 0498 */\r
1112 void conditional (void)\r
1113 {\r
1114   boolean b;\r
1115   char r;\r
1116   integer m, n;\r
1117   pointer p, q;\r
1118   small_number save_scanner_status;\r
1119   pointer save_cond_ptr;\r
1120   small_number this_if;\r
1121 \r
1122   {\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
1128     cond_ptr = p;\r
1129     cur_if = cur_chr;\r
1130     if_limit = if_code;\r
1131     if_line = line;\r
1132   }\r
1133 \r
1134   save_cond_ptr = cond_ptr;\r
1135   this_if = cur_chr;\r
1136 \r
1137   switch (this_if)\r
1138   {\r
1139     case if_char_code:\r
1140     case if_cat_code:\r
1141       {\r
1142         get_x_token_or_active_char();\r
1143 \r
1144         if ((cur_cmd > active_char) || (cur_chr > 255))\r
1145         {\r
1146           m = relax;\r
1147           n = 256;\r
1148         }\r
1149         else\r
1150         {\r
1151           m = cur_cmd;\r
1152           n = cur_chr;\r
1153         }\r
1154 \r
1155         get_x_token_or_active_char();\r
1156 \r
1157         if ((cur_cmd > active_char) || (cur_chr > 255))\r
1158         {\r
1159           cur_cmd = relax;\r
1160           cur_chr = 256;\r
1161         }\r
1162 \r
1163         if (this_if == if_char_code)\r
1164           b = (n == cur_chr); \r
1165         else\r
1166           b = (m == cur_cmd);\r
1167       }\r
1168       break;\r
1169 \r
1170     case if_int_code:\r
1171     case if_dim_code:\r
1172       {\r
1173         if (this_if == if_int_code)\r
1174           scan_int();\r
1175         else\r
1176           scan_dimen(false, false, false);\r
1177 \r
1178         n = cur_val;\r
1179         \r
1180         do\r
1181           {\r
1182             get_x_token();\r
1183           }\r
1184         while (!(cur_cmd != spacer));\r
1185 \r
1186         if ((cur_tok >= other_token + '<') && (cur_tok <= other_token + '>'))\r
1187           r = cur_tok - other_token;\r
1188         else\r
1189         {\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
1193           back_error();\r
1194           r = '=';\r
1195         }\r
1196 \r
1197         if (this_if == if_int_code)\r
1198           scan_int();\r
1199         else \r
1200           scan_dimen(false, false, false);\r
1201 \r
1202         switch (r)\r
1203         {\r
1204           case '<':\r
1205             b = (n < cur_val);\r
1206             break;\r
1207 \r
1208           case '=':\r
1209             b = (n == cur_val);\r
1210             break;\r
1211 \r
1212           case '>':\r
1213             b = (n > cur_val);\r
1214             break;\r
1215         }\r
1216       }\r
1217       break;\r
1218 \r
1219     case if_odd_code:\r
1220       scan_int();\r
1221       b = odd(cur_val);\r
1222       break;\r
1223 \r
1224     case if_vmode_code:\r
1225       b = (abs(mode) == vmode);\r
1226       break;\r
1227 \r
1228     case if_hmode_code:\r
1229       b = (abs(mode) == hmode);\r
1230       break;\r
1231 \r
1232     case if_mmode_code:\r
1233       b = (abs(mode) == mmode);\r
1234       break;\r
1235 \r
1236     case if_inner_code:\r
1237       b = (mode < 0);\r
1238       break;\r
1239 \r
1240     case if_void_code:\r
1241     case if_hbox_code:\r
1242     case if_vbox_code:\r
1243       {\r
1244         scan_eight_bit_int();\r
1245         p = box(cur_val);\r
1246 \r
1247         if (this_if == if_void_code)\r
1248           b = (p == 0);\r
1249         else if (p == 0)\r
1250           b = false;\r
1251         else if (this_if == if_hbox_code)\r
1252           b = (type(p) == hlist_node);\r
1253         else\r
1254           b = (type(p) == vlist_node);\r
1255       }\r
1256       break;\r
1257 \r
1258     case ifx_code:\r
1259       {\r
1260         save_scanner_status = scanner_status;\r
1261         scanner_status = 0;\r
1262         get_next();\r
1263         n = cur_cs;\r
1264         p = cur_cmd;\r
1265         q = cur_chr;\r
1266         get_next();\r
1267 \r
1268         if (cur_cmd != p)\r
1269           b = false;\r
1270         else if (cur_cmd < call)\r
1271           b = (cur_chr == q);\r
1272         else\r
1273         {\r
1274           p = link(cur_chr);\r
1275           q = link(equiv(n));\r
1276 \r
1277           if (p == q)\r
1278             b = true;\r
1279           else\r
1280           {\r
1281             while ((p != 0) && (q != 0))\r
1282               if (info(p) != info(q))\r
1283                 p = 0;\r
1284               else\r
1285               {\r
1286                 p = link(p);\r
1287                 q = link(q);\r
1288               }\r
1289 \r
1290             b = ((p == 0) && (q == 0));\r
1291           }\r
1292         }\r
1293 \r
1294         scanner_status = save_scanner_status;\r
1295       }\r
1296       break;\r
1297 \r
1298     case if_eof_code:\r
1299       {\r
1300         scan_four_bit_int();\r
1301         b = (read_open[cur_val] == closed);\r
1302       }\r
1303       break;\r
1304 \r
1305     case if_true_code:\r
1306       b = true;\r
1307       break;\r
1308 \r
1309     case if_false_code:\r
1310       b = false;\r
1311       break;\r
1312 \r
1313     case if_case_code:\r
1314       {\r
1315         scan_int();\r
1316         n = cur_val;\r
1317 \r
1318         if (tracing_commands > 1)\r
1319         {\r
1320           begin_diagnostic();\r
1321           prints("{case ");\r
1322           print_int(n); \r
1323           print_char('}');\r
1324           end_diagnostic(false);\r
1325         }\r
1326 \r
1327         while (n != 0)\r
1328         {\r
1329           pass_text();\r
1330 \r
1331           if (cond_ptr == save_cond_ptr)\r
1332             if (cur_chr == or_code)\r
1333               decr(n);\r
1334             else \r
1335               goto common_ending;\r
1336           else if (cur_chr == fi_code)\r
1337           {\r
1338             p = cond_ptr;\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
1344           }\r
1345         }\r
1346 \r
1347         change_if_limit(or_code, save_cond_ptr);\r
1348         return;\r
1349       }\r
1350       break;\r
1351   }\r
1352 \r
1353   if (tracing_commands > 1)\r
1354   {\r
1355     begin_diagnostic();\r
1356 \r
1357     if (b)\r
1358       prints("{true}");\r
1359     else\r
1360       prints("{false}");\r
1361 \r
1362     end_diagnostic(false);\r
1363   }\r
1364 \r
1365   if (b)\r
1366   {\r
1367     change_if_limit(else_code, save_cond_ptr);\r
1368     return;\r
1369   }\r
1370 \r
1371   while (true)\r
1372   {\r
1373     pass_text();\r
1374 \r
1375     if (cond_ptr == save_cond_ptr)\r
1376     {\r
1377       if (cur_chr != or_code)\r
1378         goto common_ending;\r
1379 \r
1380       print_err("Extra ");\r
1381       print_esc("or");\r
1382       help1("I'm ignoring this; it doesn't match any \\if.");\r
1383       error();\r
1384     }\r
1385     else if (cur_chr == fi_code)\r
1386     {\r
1387       p = cond_ptr;\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
1393     }\r
1394   }\r
1395 \r
1396 common_ending:\r
1397   if (cur_chr == fi_code)\r
1398   {\r
1399     p = cond_ptr;\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
1405   }\r
1406   else\r
1407     if_limit = fi_code;\r
1408 }\r
1409 /* sec 0515 */\r
1410 void begin_name (void)\r
1411 {\r
1412   area_delimiter = 0;\r
1413   ext_delimiter = 0;\r
1414 }\r
1415 /* sec 0516 */\r
1416 boolean more_name (ASCII_code c)\r
1417 {\r
1418   if (quoted_file_name == false && c == ' ')\r
1419     return false;\r
1420   else if (quoted_file_name != false && c == '"')\r
1421   {\r
1422     quoted_file_name = false; /* catch next space character */\r
1423     return true;     /* accept ending quote, but throw away */\r
1424   }\r
1425   else\r
1426   {   \r
1427     str_room(1);\r
1428     append_char(c);\r
1429 \r
1430     //  for DOS/Windows\r
1431     if ((c == '/' || c == '\\' || c == ':')) \r
1432     {\r
1433       area_delimiter = cur_length;\r
1434       ext_delimiter = 0;\r
1435     } \r
1436     else if (c == '.')\r
1437       ext_delimiter = cur_length;\r
1438 \r
1439     return true;\r
1440   }\r
1441 }\r
1442 \r
1443 /* sec 0517 */\r
1444 void end_name (void) \r
1445 {\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
1449 \r
1450   if (str_ptr + 3 > current_max_strings)\r
1451   {\r
1452     overflow("number of strings", current_max_strings - init_str_ptr);\r
1453     return;\r
1454   }\r
1455 #else\r
1456   if (str_ptr + 3 > max_strings)\r
1457   {\r
1458     overflow("number of strings", max_strings - init_str_ptr);\r
1459     return;\r
1460   }\r
1461 #endif\r
1462 \r
1463   if (area_delimiter == 0) // no area delimiter ':' '/' or '\' found\r
1464     cur_area = 335;        // "" default area \r
1465   else\r
1466   {\r
1467     cur_area = str_ptr;\r
1468     str_start[str_ptr + 1] = str_start[str_ptr] + area_delimiter;\r
1469     incr(str_ptr);\r
1470   }\r
1471 \r
1472   if (ext_delimiter == 0) // no extension delimiter '.' found\r
1473   {\r
1474     cur_ext = 335;        // "" default extension \r
1475     cur_name = make_string();\r
1476   } \r
1477   else\r
1478   {\r
1479     cur_name = str_ptr;\r
1480     str_start[str_ptr + 1] = str_start[str_ptr] + ext_delimiter - area_delimiter - 1;\r
1481     incr(str_ptr);\r
1482     cur_ext = make_string();\r
1483   }\r
1484 }\r
1485 /* sec 0519 */\r
1486 void pack_file_name (str_number n, str_number a, str_number e)\r
1487 {\r
1488   integer k;\r
1489   ASCII_code c;\r
1490   pool_pointer j;\r
1491 \r
1492   k = 0;\r
1493 \r
1494   for (j = str_start[a]; j <= str_start[a + 1] - 1; j++)\r
1495     append_to_name(str_pool[j]);\r
1496 \r
1497   for (j = str_start[n]; j <= str_start[n + 1] - 1; j++)\r
1498     append_to_name(str_pool[j]);\r
1499 \r
1500   for (j = str_start[e]; j <= str_start[e + 1] - 1; j++)\r
1501     append_to_name(str_pool[j]);\r
1502 \r
1503   if (k < file_name_size)\r
1504     name_length = k;\r
1505   else\r
1506     name_length = file_name_size - 1;\r
1507 \r
1508   for (k = name_length + 1; k <= file_name_size; k++)\r
1509     name_of_file[k] = ' ';\r
1510 \r
1511   name_of_file[file_name_size] = '\0'; /* paranoia */\r
1512 \r
1513   {\r
1514     name_of_file [name_length + 1] = '\0';\r
1515 \r
1516     if (trace_flag)\r
1517       printf(" pack_file_name `%s' (%lld) ", name_of_file + 1, name_length);\r
1518 \r
1519     name_of_file [name_length + 1] = ' ';\r
1520   }\r
1521 }\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
1525 /* sec 0523 */\r
1526 void pack_buffered_name_(small_number n, integer a, integer b)\r
1527 {\r
1528   integer k;\r
1529   ASCII_code c;\r
1530   integer j;\r
1531 \r
1532   if (n + b - a + 5 > file_name_size)\r
1533     b = a + file_name_size - n - 5;\r
1534 \r
1535   k = 0;\r
1536 \r
1537   for (j = 1; j <= n; j++)\r
1538     append_to_name(xord[TEX_format_default[j]]);\r
1539 \r
1540   for (j = a; j <= b; j++)\r
1541     append_to_name(buffer[j]);\r
1542 \r
1543   for (j = format_default_length - 3; j <= format_default_length; j++)\r
1544     append_to_name(xord[TEX_format_default[j]]);\r
1545 \r
1546   if (k < file_name_size)\r
1547     name_length = k;\r
1548   else\r
1549     name_length = file_name_size - 1;\r
1550 \r
1551   for (k = name_length + 1; k <= file_name_size; k++)\r
1552     name_of_file[k]= ' ';\r
1553 \r
1554   name_of_file[file_name_size] = '\0';\r
1555 }\r
1556 /* sec 0525 */\r
1557 str_number make_name_string (void)\r
1558 {\r
1559   integer k;\r
1560 \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
1564 \r
1565   if (str_ptr == current_max_strings)\r
1566     str_start = realloc_str_start(increment_max_strings);\r
1567 \r
1568   if ((pool_ptr + name_length > current_pool_size) || (str_ptr == current_max_strings) || (cur_length > 0))\r
1569 #else\r
1570   if ((pool_ptr + name_length > pool_size) || (str_ptr == max_strings) || (cur_length > 0))\r
1571 #endif\r
1572   {\r
1573     return '?';\r
1574   }\r
1575   else\r
1576   {\r
1577     for (k = 1; k <= name_length; k++)\r
1578       append_char(xord[name_of_file[k]]);\r
1579 \r
1580     return make_string();\r
1581   }\r
1582 }\r
1583 /* sec 0525 */\r
1584 //str_number a_make_name_string (alpha_file * f)\r
1585 str_number a_make_name_string_(void)\r
1586 {\r
1587   return make_name_string();\r
1588 }\r
1589 /* sec 0525 */\r
1590 //str_number b_make_name_string_(byte_file * f)\r
1591 str_number b_make_name_string_(void)\r
1592 {\r
1593   return make_name_string(); \r
1594 }\r
1595 /* sec 0525 */\r
1596 //str_number w_make_name_string_(word_file * f)\r
1597 str_number w_make_name_string_(void)\r
1598 {\r
1599   return make_name_string();\r
1600 }\r
1601 /* sec 0526 */\r
1602 void scan_file_name (void)\r
1603 {\r
1604   name_in_progress = true;\r
1605   begin_name();\r
1606 \r
1607   do\r
1608     {\r
1609       get_x_token(); \r
1610     }\r
1611   while (!(cur_cmd != spacer));\r
1612 \r
1613   quoted_file_name = false;\r
1614 \r
1615   if (allow_quoted_names)\r
1616   {\r
1617     if (cur_chr == '"')\r
1618     {\r
1619       quoted_file_name = true;\r
1620       get_x_token();\r
1621     }\r
1622   }\r
1623 \r
1624   while (true)\r
1625   {\r
1626     if ((cur_cmd > other_char) || (cur_chr > 255)) \r
1627     {\r
1628       back_input();\r
1629       goto done; \r
1630     } \r
1631 \r
1632     if (!more_name(cur_chr))\r
1633       goto done;\r
1634 \r
1635     get_x_token();\r
1636   }\r
1637 \r
1638 done:\r
1639   end_name();\r
1640   name_in_progress = false;\r
1641 }\r
1642 /* argument is string .fmt, .log, .pdf, or .dvi */\r
1643 /* sec 0529 */\r
1644 void pack_job_name_(str_number s)\r
1645 {\r
1646   cur_area = 335; /* "" */\r
1647   cur_ext  = s;\r
1648   cur_name = job_name;\r
1649   pack_file_name(cur_name, cur_area, cur_ext);\r
1650 }\r
1651 /* sec 0530 */\r
1652 void prompt_file_name_(const char * s, str_number e) \r
1653 {\r
1654   integer k;\r
1655 \r
1656   if (interaction == scroll_mode)\r
1657     do_nothing();\r
1658 \r
1659   if (!strcmp("input file name", s))\r
1660     print_err("I can't find file `");\r
1661   else\r
1662     print_err("I can't write on file `");\r
1663 \r
1664   print_file_name(cur_name, cur_area, cur_ext);\r
1665   prints("'.");\r
1666 \r
1667   if (e == 785)    /* .tex */\r
1668     show_context();\r
1669 \r
1670   print_nl("Please type another ");\r
1671   prints(s); \r
1672 \r
1673   if (interaction < scroll_mode)\r
1674   {\r
1675     fatal_error("*** (job aborted, file error in nonstop mode)");\r
1676     return;\r
1677   }\r
1678 \r
1679   if (!knuth_flag)\r
1680     show_line(" (or Ctrl-Z to exit)", 0);\r
1681 \r
1682   prompt_input(": ");\r
1683 \r
1684   {\r
1685     begin_name();\r
1686     k = first;\r
1687 \r
1688     while ((buffer[k] == ' ') && (k < last))\r
1689       incr(k);\r
1690 \r
1691     quoted_file_name = false;\r
1692 \r
1693     if (allow_quoted_names && k < last) /* check whether quoted name */\r
1694     {\r
1695       if (buffer[k]== '"')\r
1696       {\r
1697         quoted_file_name = true;\r
1698         incr(k);\r
1699       }\r
1700     }\r
1701 \r
1702     while (true)\r
1703     {\r
1704       if (k == last)\r
1705         goto done;\r
1706 \r
1707       /* convert tilde '~' to pseudo tilde */\r
1708       if (pseudo_tilde != 0 && buffer[k]== '~')\r
1709         buffer[k] = pseudo_tilde;\r
1710 \r
1711       /* convert space ' ' to pseudo space */\r
1712       if (pseudo_space != 0 && buffer[k]== ' ')\r
1713         buffer[k] = pseudo_space;\r
1714 \r
1715       if (!more_name(buffer[k]))\r
1716         goto done;\r
1717 \r
1718       incr(k);\r
1719     }\r
1720 \r
1721 done:\r
1722     end_name();\r
1723   }\r
1724 \r
1725   if (cur_ext == 335) /* "" */\r
1726     cur_ext = e;      /* use default extension */\r
1727 \r
1728   pack_file_name(cur_name, cur_area, cur_ext);\r
1729 }\r
1730 /* sec 0534 */\r
1731 void open_log_file (void)\r
1732 {\r
1733   char old_setting;\r
1734   integer k;\r
1735   integer l;\r
1736   char * months;\r
1737 \r
1738   old_setting = selector;\r
1739 \r
1740   if (job_name == 0)\r
1741     job_name = get_job_name(790);\r
1742     //job_name = 790;\r
1743 \r
1744   pack_job_name(".log");\r
1745 \r
1746   while (!a_open_out(log_file))\r
1747   {\r
1748     selector = term_only;\r
1749     prompt_file_name("transcript file name", ".log");\r
1750   }\r
1751 \r
1752   log_name = a_make_name_string(log_file);\r
1753   selector = log_only;\r
1754   log_opened = true;\r
1755 \r
1756   {\r
1757     fprintf(log_file, "%s (%s %s)", banner, application, yandyversion);\r
1758 \r
1759     if (format_ident > 0)\r
1760       slow_print(format_ident);\r
1761 \r
1762     prints("  ");\r
1763 \r
1764     if (civilize_flag)\r
1765       print_int(year);\r
1766     else\r
1767       print_int(day);\r
1768 \r
1769     print_char(' ');\r
1770     months = " JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";\r
1771 \r
1772     for (k = 3 * month - 2; k <= 3 * month; k++)\r
1773       putc(months[k], log_file);\r
1774 \r
1775     print_char(' ');\r
1776 \r
1777     if (civilize_flag)\r
1778       print_int(day);\r
1779     else\r
1780       print_int(year);\r
1781 \r
1782     print_char(' ');\r
1783     print_two(tex_time / 60);\r
1784     print_char(':');\r
1785     print_two(tex_time % 60);\r
1786   }\r
1787 \r
1788   input_stack[input_ptr] = cur_input;\r
1789   print_nl("**");\r
1790   l = input_stack[0].limit_field;\r
1791 \r
1792   if (buffer[l] == end_line_char)\r
1793     decr(l);\r
1794 \r
1795   for (k = 1; k <= l; k++)\r
1796     print(buffer[k]);\r
1797 \r
1798   print_ln(); \r
1799 \r
1800   if (show_fmt_flag)\r
1801   {\r
1802     if (format_file != NULL)\r
1803     {\r
1804       fprintf(log_file, "(%s)\n", format_file);\r
1805       free(format_file);\r
1806       format_file = NULL;\r
1807     }\r
1808   }\r
1809 \r
1810   selector = old_setting + 2;\r
1811 }\r
1812 /* sec 0537 */\r
1813 void start_input (void)\r
1814 {\r
1815   scan_file_name();\r
1816   pack_file_name(cur_name, cur_area, cur_ext); \r
1817 \r
1818   while (true)\r
1819   {\r
1820     begin_file_reading();\r
1821     \r
1822     if (a_open_in(cur_file, kpse_tex_format))\r
1823       goto done;\r
1824 \r
1825     end_file_reading();\r
1826     prompt_file_name("input file name", ".tex");\r
1827   }\r
1828 \r
1829 done: \r
1830   name = a_make_name_string(cur_file);\r
1831 \r
1832   if (job_name == 0)\r
1833   {\r
1834     job_name = get_job_name(cur_name);\r
1835     //job_name = cur_name;\r
1836     open_log_file();\r
1837   }\r
1838 \r
1839   if (term_offset + length(name) > max_print_line - 2)\r
1840     print_ln();\r
1841   else if ((term_offset > 0) || (file_offset > 0))\r
1842     print_char(' ');\r
1843 \r
1844   print_char('(');\r
1845   incr(open_parens);\r
1846 \r
1847   if (open_parens > max_open_parens)\r
1848     max_open_parens = open_parens;\r
1849 \r
1850   slow_print(name);\r
1851   update_terminal();\r
1852   state = new_line;\r
1853 \r
1854   {\r
1855     line = 1;\r
1856 \r
1857     if (input_ln(cur_file, false))\r
1858       do_nothing();\r
1859 \r
1860     firm_up_the_line();\r
1861 \r
1862     if (end_line_char_inactive())\r
1863       decr(limit);\r
1864     else\r
1865       buffer[limit] = end_line_char;\r
1866 \r
1867     first = limit + 1;\r
1868     loc = start;\r
1869   }\r
1870 }\r
1871 /* sec 0560 */\r
1872 internal_font_number read_font_info (pointer u, str_number nom, str_number aire, scaled s)\r
1873 {\r
1874   font_index k;\r
1875   boolean file_opened;\r
1876   halfword lf, lh, nw, nh, nd, ni, nl, nk, ne, np;\r
1877   int bc, ec;\r
1878   internal_font_number f;\r
1879   internal_font_number g;\r
1880   eight_bits a, b, c, d;\r
1881   four_quarters qw;\r
1882   scaled sw;\r
1883   integer bch_label;\r
1884   short bchar;\r
1885   scaled z;\r
1886   integer alpha;\r
1887   char beta;\r
1888 \r
1889   g = 0;\r
1890   file_opened = false;\r
1891   pack_file_name(nom, aire, 805); /* .tfm */\r
1892 \r
1893   if (!b_open_in(tfm_file))\r
1894     goto bad_tfm;\r
1895 \r
1896   file_opened = true;\r
1897 \r
1898   {\r
1899     read_sixteen(lf);\r
1900     fget();\r
1901     read_sixteen(lh);\r
1902     fget();\r
1903     read_sixteen(bc);\r
1904     fget();\r
1905     read_sixteen(ec);\r
1906 \r
1907     if ((bc > ec + 1) || (ec > 255))\r
1908       goto bad_tfm;\r
1909 \r
1910     if (bc > 255)\r
1911     {\r
1912       bc = 1;\r
1913       ec = 0;\r
1914     }\r
1915 \r
1916     fget();\r
1917     read_sixteen(nw);\r
1918     fget();\r
1919     read_sixteen(nh);\r
1920     fget();\r
1921     read_sixteen(nd);\r
1922     fget();\r
1923     read_sixteen(ni);\r
1924     fget();\r
1925     read_sixteen(nl);\r
1926     fget();\r
1927     read_sixteen(nk);\r
1928     fget();\r
1929     read_sixteen(ne);\r
1930     fget();\r
1931     read_sixteen(np);\r
1932 \r
1933     if (lf != 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np)\r
1934       goto bad_tfm;\r
1935 \r
1936     if ((nw == 0) || (nh == 0) || (nd == 0) || (ni == 0))\r
1937       goto bad_tfm;\r
1938   }\r
1939 \r
1940   lf = lf - 6 - lh;\r
1941 \r
1942   if (np < 7)\r
1943     lf = lf + 7 - np;\r
1944 \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
1948 \r
1949   if ((font_ptr == font_max) || (fmem_ptr + lf > current_font_mem_size))\r
1950 #else\r
1951   if ((font_ptr == font_max) || (fmem_ptr + lf > font_mem_size))\r
1952 #endif\r
1953   {\r
1954     if (trace_flag)\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
1957 \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
1964     error();\r
1965     goto done;\r
1966   }\r
1967 \r
1968   f = font_ptr + 1;\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
1978 \r
1979   {\r
1980     if (lh < 2)\r
1981       goto bad_tfm;\r
1982     \r
1983     store_four_quarters(font_check[f]);\r
1984     fget();\r
1985     read_sixteen(z);\r
1986     fget();\r
1987     z = z * 256 + fbyte;\r
1988     fget();\r
1989     z = (z * 16) + (fbyte / 16);\r
1990 \r
1991     if (z < unity)\r
1992       goto bad_tfm; \r
1993 \r
1994     while (lh > 2)\r
1995     {\r
1996       fget();\r
1997       fget();\r
1998       fget();\r
1999       fget();\r
2000       decr(lh);\r
2001     }\r
2002 \r
2003     font_dsize[f] = z;\r
2004 \r
2005     if (s != -1000)\r
2006       if (s >= 0)\r
2007         z = s;\r
2008       else\r
2009         z = xn_over_d(z, - (integer) s, 1000);\r
2010 \r
2011     font_size[f] = z;\r
2012   }\r
2013 \r
2014   for (k = fmem_ptr; k <= width_base[f] - 1; k++)\r
2015   {\r
2016     store_four_quarters(font_info[k].qqqq);\r
2017 \r
2018     if ((a >= nw) || (b / 16 >= nh) || (b % 16 >= nd) || (c / 4 >= ni))\r
2019       goto bad_tfm;\r
2020 \r
2021     switch (c % 4)\r
2022     {\r
2023       case lig_tag:\r
2024         if (d >= nl)\r
2025           goto bad_tfm;\r
2026         break;\r
2027 \r
2028       case ext_tag:\r
2029         if (d >= ne)\r
2030           goto bad_tfm;\r
2031         break;\r
2032 \r
2033       case list_tag:\r
2034         {\r
2035           check_byte_range(d);\r
2036 \r
2037           while (d < k + bc - fmem_ptr)\r
2038           {\r
2039             qw = char_info(f, d);\r
2040  \r
2041             if (char_tag(qw) != list_tag)\r
2042               goto not_found;\r
2043 \r
2044             d = rem_byte(qw);\r
2045           }\r
2046 \r
2047           if (d == k + bc - fmem_ptr)\r
2048             goto bad_tfm;\r
2049 not_found:;\r
2050         }\r
2051         break;\r
2052 \r
2053       default:\r
2054         break;\r
2055     }\r
2056   }\r
2057 \r
2058   {\r
2059     {\r
2060       alpha = 16;\r
2061 \r
2062       while (z >= 8388608L)   /* 2^23 */\r
2063       {\r
2064         z = z / 2;\r
2065         alpha = alpha + alpha;\r
2066       }\r
2067 \r
2068       beta = (char) (256 / alpha);\r
2069       alpha = alpha * z;\r
2070     }\r
2071 \r
2072     for (k = width_base[f]; k <= lig_kern_base[f] - 1; k++)\r
2073       store_scaled(font_info[k].cint);\r
2074 \r
2075     if (font_info[width_base[f]].cint != 0)\r
2076       goto bad_tfm;\r
2077 \r
2078     if (font_info[height_base[f]].cint != 0)\r
2079       goto bad_tfm;\r
2080 \r
2081     if (font_info[depth_base[f]].cint != 0)\r
2082       goto bad_tfm;\r
2083 \r
2084     if (font_info[italic_base[f]].cint != 0)\r
2085       goto bad_tfm;\r
2086   }\r
2087 \r
2088   bch_label = 32767;     /* '77777 */\r
2089   bchar = 256;\r
2090 \r
2091   if (nl > 0)\r
2092   {\r
2093     for (k = lig_kern_base[f]; k <= kern_base[f] + kern_base_offset - 1; k++)\r
2094     {\r
2095       store_four_quarters(font_info[k].qqqq);\r
2096 \r
2097       if (a > 128)\r
2098       {\r
2099         if (256 * c + d >= nl)\r
2100           goto bad_tfm;\r
2101 \r
2102         if (a == 255)\r
2103           if (k == lig_kern_base[f])\r
2104             bchar = b;\r
2105       }\r
2106       else\r
2107       {\r
2108         if (b != bchar)\r
2109           check_existence(b);\r
2110 \r
2111         if (c < 128)\r
2112           check_existence(d);\r
2113         else if (256 * (c - 128) + d >= nk)\r
2114           goto bad_tfm;\r
2115 \r
2116         if (a < 128)\r
2117           if (k - lig_kern_base[f] + a + 1 >= nl)\r
2118             goto bad_tfm;\r
2119       }\r
2120     }\r
2121 \r
2122     if (a == 255)\r
2123       bch_label = 256 * c + d;\r
2124   }\r
2125 \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
2128 \r
2129   for (k = exten_base[f]; k <= param_base[f] - 1; k++)\r
2130   {\r
2131     store_four_quarters(font_info[k].qqqq);\r
2132 \r
2133     if (a != 0)\r
2134       check_existence(a);\r
2135 \r
2136     if (b != 0)\r
2137       check_existence(b);\r
2138 \r
2139     if (c != 0)\r
2140       check_existence(c);\r
2141 \r
2142     check_existence(d);\r
2143   }\r
2144 \r
2145   {\r
2146     for (k = 1; k <= np; k++)\r
2147       if (k == 1)\r
2148       {\r
2149         fget();\r
2150         sw = fbyte;\r
2151 \r
2152         if (sw > 127)\r
2153           sw = sw - 256;\r
2154 \r
2155         fget();\r
2156         sw = sw * 256 + fbyte;\r
2157         fget();\r
2158         sw = sw * 256 + fbyte;\r
2159         fget();\r
2160         font_info[param_base[f]].cint = (sw * 16) + (fbyte / 16);\r
2161       }\r
2162       else\r
2163         store_scaled(font_info[param_base[f] + k - 1].cint);\r
2164 \r
2165     if (feof(tfm_file))\r
2166       goto bad_tfm;\r
2167 \r
2168     for (k = np + 1; k <= 7; k++)\r
2169       font_info[param_base[f] + k - 1].cint = 0;\r
2170   }\r
2171 \r
2172   if (np >= 7)\r
2173     font_params[f] = np;\r
2174   else\r
2175     font_params[f] = 7;\r
2176 \r
2177   hyphen_char[f] = default_hyphen_char;\r
2178   skew_char[f] = default_skew_char;\r
2179 \r
2180   if (bch_label < nl)\r
2181     bchar_label[f] = bch_label + lig_kern_base[f];\r
2182   else\r
2183     bchar_label[f] = non_address;\r
2184 \r
2185   font_bchar[f] = bchar;\r
2186   font_false_bchar[f] = bchar;\r
2187 \r
2188   if (bchar <= ec)\r
2189     if (bchar >= bc)\r
2190     {\r
2191       qw = char_info(f, bchar);\r
2192 \r
2193       if (char_exists(qw))\r
2194         font_false_bchar[f] = 256;\r
2195     }\r
2196 \r
2197   font_name[f] = nom;\r
2198   font_area[f] = aire;\r
2199   font_bc[f] = bc;\r
2200   font_ec[f] = ec;\r
2201   font_glue[f] = 0;\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
2209   font_ptr = f;\r
2210   g = f;\r
2211   goto done;\r
2212 \r
2213 bad_tfm:\r
2214   start_font_error_message();\r
2215 \r
2216   if (file_opened)\r
2217     prints(" not loadable: Bad metric (TFM) file");\r
2218   else\r
2219     prints(" not loadable: Metric (TFM) file not found");\r
2220 \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
2226   error();\r
2227 \r
2228 done:\r
2229   if (file_opened)\r
2230     b_close(tfm_file);\r
2231 \r
2232   return g;\r
2233 }