OSDN Git Service

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