OSDN Git Service

version 2.3.0-final.
[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 #include "yandytex.h"\r
22 \r
23 /* sec 0440 */\r
24 void scan_int (void)\r
25 {\r
26   boolean negative;\r
27   integer m;\r
28   small_number d;\r
29   boolean vacuous;\r
30   boolean OK_so_far;\r
31 \r
32   radix = 0;\r
33   OK_so_far = true;\r
34   negative = false;\r
35 \r
36   do\r
37     {\r
38       do \r
39         {\r
40           get_x_token();\r
41         }\r
42       while (!(cur_cmd != spacer));\r
43 \r
44       if (cur_tok == other_token + '-')\r
45       {\r
46         negative = !negative;\r
47         cur_tok = other_token + '+';\r
48       }\r
49     }\r
50   while (!(cur_tok != other_token + '+'));\r
51 \r
52   if (cur_tok == alpha_token)\r
53   {\r
54     get_token();\r
55 \r
56     if (cur_tok < cs_token_flag)\r
57     {\r
58       cur_val = cur_chr;\r
59 \r
60       if (cur_cmd <= right_brace)\r
61         if (cur_cmd == right_brace)\r
62           incr(align_state);\r
63         else\r
64           decr(align_state);\r
65     }\r
66     else if (cur_tok < cs_token_flag + single_base)\r
67       cur_val = cur_tok - cs_token_flag - active_base;\r
68     else\r
69       cur_val = cur_tok - cs_token_flag - single_base;\r
70 \r
71     if (cur_val > 255)\r
72     {\r
73       print_err("Improper alphabetic constant");\r
74       help2("A one-character control sequence belongs after a ` mark.",\r
75         "So I'm essentially inserting \\0 here.");\r
76       cur_val = '0';\r
77       back_error();\r
78     }\r
79     else\r
80     {\r
81       get_x_token();\r
82 \r
83       if (cur_cmd != spacer)\r
84         back_input();\r
85     }\r
86   }\r
87   else if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))\r
88   {\r
89     scan_something_internal(int_val, false);\r
90   }\r
91   else\r
92   {\r
93     radix = 10;\r
94     m = 214748364L;   /* 7FFFFFFF hex */\r
95 \r
96     if (cur_tok == octal_token)\r
97     {\r
98       radix = 8;\r
99       m = 268435456L;   /* 2^28 */\r
100       get_x_token();\r
101     }\r
102     else if (cur_tok == hex_token)\r
103     {\r
104       radix = 16;\r
105       m = 134217728L;   /* 2^27 8000000 hex */\r
106       get_x_token();\r
107     }\r
108 \r
109     vacuous = true;\r
110     cur_val = 0;\r
111 \r
112     while (true)\r
113     {\r
114       if ((cur_tok < zero_token + radix) && (cur_tok >= zero_token) && (cur_tok <= zero_token + 9))\r
115         d = cur_tok - zero_token;\r
116       else if (radix == 16)\r
117         if ((cur_tok <= A_token + 5) && (cur_tok >= A_token))\r
118           d = cur_tok - A_token + 10;\r
119         else if ((cur_tok <= other_A_token + 5) && (cur_tok >= other_A_token))\r
120           d = cur_tok - other_A_token;\r
121         else\r
122           goto done;\r
123       else\r
124         goto done;\r
125 \r
126       vacuous = false;\r
127 \r
128       if ((cur_val >= m) && ((cur_val > m) || (d > 7) || (radix != 10)))\r
129       {\r
130         if (OK_so_far)\r
131         {\r
132           print_err("Number too big");\r
133           help2("I can only go up to 2147483647='17777777777=\"7FFFFFFF,",\r
134             "so I'm using that number instead of yours.");\r
135           error();\r
136           cur_val = 2147483647L;    /* 7FFFFFFF hex */\r
137           OK_so_far = false;\r
138         }\r
139       }\r
140       else\r
141         cur_val = cur_val * radix + d;\r
142 \r
143       get_x_token();\r
144     }\r
145 \r
146 done:\r
147     if (vacuous)\r
148     {\r
149       print_err("Missing number, treated as zero");\r
150       help3("A number should have been here; I inserted `0'.",\r
151         "(If you can't figure out why I needed to see a number,",\r
152         "look up `weird error' in the index to The TeXbook.)");\r
153       back_error();\r
154     } \r
155     else if (cur_cmd != spacer)\r
156       back_input();\r
157   }\r
158 \r
159   if (negative)\r
160     cur_val = - (integer) cur_val;\r
161 }\r
162 /* sec 0448 */\r
163 void scan_dimen (boolean mu, boolean inf, boolean shortcut)\r
164 {\r
165   boolean negative;\r
166   integer f;\r
167   integer num, denom;\r
168   small_number k, kk;\r
169   halfword p, q;\r
170   scaled v;\r
171   integer save_cur_val;\r
172 \r
173   f = 0;\r
174   arith_error = false;\r
175   cur_order = normal;\r
176   negative = false;\r
177 \r
178   if (!shortcut)\r
179   {\r
180     negative = false;\r
181 \r
182     do\r
183       {\r
184         do\r
185           {\r
186             get_x_token();\r
187           }\r
188         while (!(cur_cmd != spacer));\r
189 \r
190         if (cur_tok == other_token + '-')\r
191         {\r
192           negative = ! negative;\r
193           cur_tok = other_token + '+';\r
194         }\r
195       }\r
196     while (!(cur_tok != other_token + '+'));\r
197 \r
198     if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))\r
199     {\r
200       if (mu)\r
201       {\r
202         scan_something_internal(mu_val, false);\r
203 \r
204         if (cur_val_level >= glue_val)\r
205         {\r
206           v = width(cur_val);\r
207           delete_glue_ref(cur_val);\r
208           cur_val = v;\r
209         }\r
210 \r
211         if (cur_val_level == mu_val)\r
212           goto attach_sign;\r
213 \r
214         if (cur_val_level != int_val)\r
215           mu_error();\r
216       }\r
217       else\r
218       {\r
219         scan_something_internal(dimen_val, false);\r
220 \r
221         if (cur_val_level == dimen_val)\r
222           goto attach_sign;\r
223       }\r
224     }\r
225     else\r
226     {\r
227       back_input();\r
228 \r
229       if (cur_tok == continental_point_token)\r
230         cur_tok = point_token;\r
231 \r
232       if (cur_tok != point_token)\r
233       {\r
234         scan_int();\r
235       }\r
236       else\r
237       {\r
238         radix = 10;\r
239         cur_val = 0;\r
240       }\r
241 \r
242       if (cur_tok == continental_point_token)\r
243         cur_tok = point_token;\r
244 \r
245       if ((radix == 10) && (cur_tok == point_token))\r
246       {\r
247         k = 0;\r
248         p = 0;\r
249         get_token();\r
250 \r
251         while (true)\r
252         {\r
253           get_x_token();\r
254 \r
255           if ((cur_tok > zero_token + 9) || (cur_tok < zero_token))\r
256             goto done1;\r
257 \r
258           if (k < 17)\r
259           {\r
260             q = get_avail();\r
261             link(q) = p;\r
262             info(q) = cur_tok - zero_token;\r
263             p = q;\r
264             incr(k);\r
265           }\r
266         }\r
267 \r
268 done1:\r
269         for (kk = k; kk >= 1; kk--)\r
270         {\r
271           dig[kk - 1] = info(p);\r
272           q = p;\r
273           p = link(p);\r
274           free_avail(q);\r
275         }\r
276 \r
277         f = round_decimals(k);\r
278 \r
279         if (cur_cmd != spacer)\r
280           back_input();\r
281         }\r
282       }\r
283   }\r
284 \r
285   if (cur_val < 0)\r
286   {\r
287     negative = !negative;\r
288     cur_val = - (integer) cur_val;\r
289   }\r
290 \r
291   if (inf)\r
292   {\r
293     if (scan_keyword("fil"))\r
294     {\r
295       cur_order = fil;\r
296 \r
297       while (scan_keyword("l"))\r
298       {\r
299         if (cur_order == filll)\r
300         {\r
301           print_err("Illegal unit of measure (");\r
302           prints("replaced by filll)");\r
303           help1("I dddon't go any higher than filll.");\r
304           error();\r
305         }\r
306         else\r
307           incr(cur_order);\r
308       }\r
309 \r
310       goto attach_fraction;\r
311     }\r
312   }\r
313 \r
314   save_cur_val = cur_val;\r
315 \r
316   do\r
317     {\r
318       get_x_token();\r
319     }\r
320   while (!(cur_cmd != spacer));\r
321 \r
322   if ((cur_cmd < min_internal) || (cur_cmd > max_internal))\r
323     back_input();\r
324   else\r
325   {\r
326     if (mu)\r
327     {\r
328       scan_something_internal(mu_val, false);\r
329 \r
330       if (cur_val_level >= glue_val)\r
331       {\r
332         v = width(cur_val);\r
333         delete_glue_ref(cur_val);\r
334         cur_val = v;\r
335       }\r
336 \r
337       if (cur_val_level != mu_val)\r
338       {\r
339         mu_error();\r
340       }\r
341     }\r
342     else\r
343     {\r
344       scan_something_internal(dimen_val, false);\r
345     }\r
346 \r
347     v = cur_val;\r
348     goto found;\r
349   }\r
350 \r
351   if (mu)\r
352     goto not_found;\r
353 \r
354   if (scan_keyword("em"))\r
355     v = quad(cur_font);\r
356   else if (scan_keyword("ex"))\r
357     v = x_height(cur_font);\r
358   else\r
359     goto not_found;\r
360 \r
361   {\r
362     get_x_token();\r
363 \r
364     if (cur_cmd != spacer)\r
365       back_input();\r
366   }\r
367 \r
368 found:\r
369   cur_val = nx_plus_y(save_cur_val, v, xn_over_d(v, f, 65536L));\r
370   goto attach_sign;\r
371 \r
372 not_found:\r
373   if (mu)\r
374   {\r
375     if (scan_keyword("mu"))\r
376       goto attach_fraction;\r
377     else\r
378     {\r
379       print_err("Illegal unit of measure (");\r
380       prints("mu inserted)");\r
381       help4("The unit of measurement in math glue must be mu.",\r
382           "To recover gracefully from this error, it's best to",\r
383           "delete the erroneous units; e.g., type `2' to delete",\r
384           "two letters. (See Chapter 27 of The TeXbook.)");\r
385       error();\r
386       goto attach_fraction;\r
387     }\r
388   }\r
389 \r
390   if (scan_keyword("true"))\r
391   {\r
392     prepare_mag();\r
393 \r
394     if (mag != 1000)\r
395     {\r
396       cur_val = xn_over_d(cur_val, 1000, mag);\r
397       f = (1000 * f + 65536L * tex_remainder) / mag;\r
398       cur_val = cur_val + (f / 65536L);\r
399       f = f % 65536L;\r
400     }\r
401   }\r
402 \r
403   if (scan_keyword("pt"))\r
404     goto attach_fraction;\r
405 \r
406   if (scan_keyword("in"))\r
407     set_conversion(7227, 100);\r
408   else if (scan_keyword("pc"))\r
409     set_conversion(12, 1);\r
410   else if (scan_keyword("cm"))\r
411     set_conversion(7227, 254);\r
412   else if (scan_keyword("mm"))\r
413     set_conversion(7227, 2540);\r
414   else if (scan_keyword("bp"))\r
415     set_conversion(7227, 7200);\r
416   else if (scan_keyword("dd"))\r
417     set_conversion(1238, 1157);\r
418   else if (scan_keyword("cc"))\r
419     set_conversion(14856, 1157);\r
420   else if (scan_keyword("Q"))\r
421     set_conversion(7227, 10160);\r
422   else if (scan_keyword("H"))\r
423     set_conversion(7227, 10160);\r
424   else if (scan_keyword("twip"))\r
425     set_conversion(1, 20);\r
426   else if (scan_keyword("sp"))\r
427     goto done;\r
428   else\r
429   {\r
430     print_err("Illegal unit of measure (");\r
431     prints("pt inserted)");\r
432     help6("Dimensions can be in units of em, ex, in, pt, pc,",\r
433       "cm, mm, dd, cc, bp, or sp; but yours is a new one!",\r
434       "I'll assume that you meant to say pt, for printer's points.",\r
435       "To recover gracefully from this error, it's best to",\r
436       "delete the erroneous units; e.g., type `2' to delete",\r
437       "two letters. (See Chapter 27 of The TeXbook.)");\r
438     error();\r
439     goto done2;\r
440   }\r
441 \r
442   cur_val = xn_over_d(cur_val, num, denom);\r
443   f = (num * f + 65536L * tex_remainder) / denom;\r
444   cur_val = cur_val + (f / 65536L);\r
445   f = f % 65536L;\r
446 \r
447 done2:\r
448 attach_fraction:\r
449   if (cur_val >= 16384)     /* 2^14 */\r
450     arith_error = true;\r
451   else\r
452     cur_val = cur_val * unity + f;\r
453 \r
454 done:\r
455   {\r
456     get_x_token();\r
457 \r
458     if (cur_cmd != spacer)\r
459       back_input();\r
460   }\r
461 \r
462 attach_sign:\r
463   if (arith_error || (abs(cur_val) >= 1073741824L)) /* 2^30 */\r
464   {\r
465     print_err("Dimension too large");\r
466     help2("I can't work with sizes bigger than about 19 feet.",\r
467         "Continue and I'll use the largest value I can.");\r
468     error();\r
469     cur_val = max_dimen;\r
470     arith_error = false;\r
471   }\r
472 \r
473   if (negative)\r
474     cur_val = - (integer) cur_val;\r
475 }\r
476 /* sec 0461 */\r
477 void scan_glue (small_number level)\r
478 {\r
479   boolean negative;\r
480   pointer q;\r
481   boolean mu;\r
482 \r
483   mu = (level == mu_val);\r
484   negative = false;\r
485 \r
486   do\r
487     {\r
488       do\r
489         {\r
490           get_x_token();\r
491         }\r
492       while (!(cur_cmd != spacer));\r
493 \r
494       if (cur_tok == other_token + '-')\r
495       {\r
496         negative = !negative;\r
497         cur_tok = other_token + '+';\r
498       }\r
499     }\r
500   while (!(cur_tok != other_token + '+'));\r
501 \r
502   if ((cur_cmd >= min_internal) && (cur_cmd <= max_internal))\r
503   {\r
504     scan_something_internal(level, negative);\r
505 \r
506     if (cur_val_level >= glue_val)\r
507     {\r
508       if (cur_val_level != level)\r
509         mu_error();\r
510 \r
511       return;\r
512     }\r
513 \r
514     if (cur_val_level == int_val)\r
515       scan_dimen(mu, false, true);\r
516     else if (level == mu_val)\r
517       mu_error();\r
518   }\r
519   else\r
520   {\r
521     back_input();\r
522     scan_dimen(mu, false, false);\r
523 \r
524     if (negative)\r
525       cur_val = - (integer) cur_val;\r
526   }\r
527 \r
528   q = new_spec(zero_glue);\r
529   width(q) = cur_val;\r
530 \r
531   if (scan_keyword("plus"))\r
532   {\r
533     scan_dimen(mu, true, false);\r
534     stretch(q) = cur_val;\r
535     stretch_order(q) = cur_order;\r
536   }\r
537 \r
538   if (scan_keyword("minus"))\r
539   {\r
540     scan_dimen(mu, true, false);\r
541     shrink(q) = cur_val;\r
542     shrink_order(q) = cur_order;\r
543   }\r
544 \r
545   cur_val = q;\r
546 }\r
547 /* sec 0463 */\r
548 pointer scan_rule_spec (void)\r
549 {\r
550   pointer q;\r
551 \r
552   q = new_rule();\r
553 \r
554   if (cur_cmd == vrule)\r
555     width(q) = default_rule;\r
556   else\r
557   {\r
558     height(q) = default_rule;\r
559     depth(q) = 0;\r
560   }\r
561 \r
562 reswitch:\r
563 \r
564   if (scan_keyword("width"))\r
565   {\r
566     scan_dimen(false, false, false);\r
567     width(q) = cur_val;\r
568     goto reswitch;\r
569   }\r
570 \r
571   if (scan_keyword("height"))\r
572   {\r
573     scan_dimen(false, false, false);\r
574     height(q) = cur_val;\r
575     goto reswitch;\r
576   }\r
577 \r
578   if (scan_keyword("depth"))\r
579   {\r
580     scan_dimen(false, false, false);\r
581     depth(q) = cur_val;\r
582     goto reswitch;\r
583   }\r
584 \r
585   return q;\r
586 }\r
587 /* sec 0464 */\r
588 pointer str_toks (pool_pointer b)\r
589 {\r
590   pointer p;\r
591   pointer q;\r
592   halfword t;\r
593   pool_pointer k;\r
594 \r
595   str_room(1);\r
596   p = temp_head;\r
597   link(p) = 0;\r
598   k = b;\r
599 \r
600   while (k < pool_ptr)\r
601   {\r
602     t = str_pool[k];\r
603 \r
604     if (t == ' ')\r
605       t = space_token;\r
606     else\r
607       t = other_token + t;\r
608 \r
609     fast_store_new_token(t);\r
610     incr(k);\r
611   }\r
612 \r
613   pool_ptr = b;\r
614 \r
615   return p;\r
616 }\r
617 /* sec 0465 */\r
618 pointer the_toks (void)\r
619 {\r
620   char old_setting;\r
621   pointer p, q, r;\r
622   pool_pointer b;\r
623 \r
624   get_x_token();\r
625   scan_something_internal(tok_val, false);\r
626 \r
627   if (cur_val_level >= ident_val)\r
628   {\r
629     p = temp_head;\r
630     link(p) = 0;\r
631 \r
632     if (cur_val_level == ident_val)\r
633       store_new_token(cs_token_flag + cur_val);\r
634     else if (cur_val != 0)\r
635     {\r
636       r = link(cur_val);\r
637 \r
638       while (r != 0)\r
639       {\r
640         fast_store_new_token(info(r));\r
641         r = link(r);\r
642       }\r
643     }\r
644 \r
645     return p;\r
646   }\r
647   else\r
648   {\r
649     old_setting = selector;\r
650     selector = new_string;\r
651     b = pool_ptr;\r
652 \r
653     switch (cur_val_level)\r
654     {\r
655       case int_val:\r
656         print_int(cur_val);\r
657         break;\r
658 \r
659       case dimen_val:\r
660         {\r
661           print_scaled(cur_val);\r
662           prints("pt");\r
663         }\r
664         break;\r
665 \r
666       case glue_val:\r
667         {\r
668           print_spec(cur_val, "pt");\r
669           delete_glue_ref(cur_val);\r
670         }\r
671         break;\r
672 \r
673       case mu_val:\r
674         {\r
675           print_spec(cur_val, "mu");\r
676           delete_glue_ref(cur_val);\r
677         }\r
678         break;\r
679     }\r
680 \r
681     selector = old_setting;\r
682     return str_toks(b);\r
683   }\r
684 }\r
685 /* sec 0467 */\r
686 void ins_the_toks (void) \r
687\r
688   link(garbage) = the_toks();\r
689   ins_list(link(temp_head));\r
690 }\r
691 /* sec 0470 */\r
692 void conv_toks (void)\r
693 {\r
694   char old_setting;\r
695   char c;\r
696   small_number save_scanner_status;\r
697   pool_pointer b;\r
698 \r
699   c = cur_chr;\r
700 \r
701   switch (c)\r
702   {\r
703     case number_code:\r
704     case roman_numeral_code:\r
705       scan_int();\r
706       break;\r
707 \r
708     case string_code:\r
709     case meaning_code:\r
710       save_scanner_status = scanner_status;\r
711       scanner_status = 0;\r
712       get_token();\r
713       scanner_status = save_scanner_status;\r
714       break;\r
715 \r
716     case font_name_code:\r
717       scan_font_ident();\r
718       break;\r
719 \r
720     case job_name_code:\r
721       if (job_name == 0)\r
722         open_log_file();\r
723       break;\r
724   }\r
725 \r
726   old_setting = selector;\r
727   selector = new_string;\r
728   b = pool_ptr;\r
729 \r
730   switch (c)\r
731   {\r
732     case number_code:\r
733       print_int(cur_val);\r
734       break;\r
735 \r
736     case roman_numeral_code:\r
737       print_roman_int(cur_val);\r
738       break;\r
739 \r
740     case string_code:\r
741       if (cur_cs != 0)\r
742         sprint_cs(cur_cs);\r
743       else\r
744         print_char(cur_chr);\r
745       break;\r
746 \r
747     case meaning_code:\r
748       print_meaning();\r
749       break;\r
750 \r
751     case font_name_code:\r
752       print(font_name[cur_val]);\r
753 \r
754       if (font_size[cur_val] != font_dsize[cur_val])\r
755       {\r
756         prints(" at ");\r
757         print_scaled(font_size[cur_val]);\r
758         prints("pt");\r
759       }\r
760       break;\r
761 \r
762     case job_name_code:\r
763       print(job_name);\r
764       break;\r
765   }\r
766 \r
767   selector = old_setting;\r
768   link(garbage) = str_toks(b);\r
769   begin_token_list(link(temp_head), 4);\r
770 }\r
771 /* sec 0473 */\r
772 pointer scan_toks (boolean macro_def, boolean xpand)\r
773 {\r
774   halfword t;\r
775   halfword s;\r
776   pointer p;\r
777   pointer q;\r
778   halfword unbalance;\r
779   halfword hash_brace;\r
780 \r
781   if (macro_def)\r
782     scanner_status = defining;\r
783   else\r
784     scanner_status = absorbing;\r
785 \r
786   warning_index = cur_cs;\r
787   def_ref = get_avail();\r
788   token_ref_count(def_ref) = 0;\r
789   p = def_ref;\r
790   hash_brace = 0;\r
791   t = zero_token;\r
792 \r
793   if (macro_def)\r
794   {\r
795     while (true)\r
796     {\r
797       get_token();\r
798 \r
799       if (cur_tok < right_brace_limit)\r
800         goto done1;\r
801 \r
802       if (cur_cmd == mac_param)\r
803       {\r
804         s = match_token + cur_chr;\r
805         get_token();\r
806 \r
807         if (cur_cmd == left_brace)\r
808         {\r
809           hash_brace = cur_tok;\r
810           store_new_token(cur_tok);\r
811           store_new_token(end_match_token);\r
812           goto done;\r
813         }\r
814 \r
815         if (t == zero_token + 9)\r
816         {\r
817           print_err("You already have nine parameters");\r
818           help1("I'm going to ignore the # sign you just used.");\r
819           error();\r
820         }\r
821         else\r
822         {\r
823           incr(t);\r
824 \r
825           if (cur_tok != t)\r
826           {\r
827             print_err("Parameters must be numbered consecutively");\r
828             help2("I've inserted the digit you should have used after the #.",\r
829                 "Type `1' to delete what you did use.");\r
830             back_error();\r
831           }\r
832 \r
833           cur_tok = s;\r
834         }\r
835       }\r
836 \r
837       store_new_token(cur_tok);\r
838     }\r
839 \r
840 done1:\r
841     store_new_token(end_match_token);\r
842 \r
843     if (cur_cmd == right_brace)\r
844     {\r
845       print_err("Missing { inserted");\r
846       incr(align_state);\r
847       help2("Where was the left brace? You said something like `\\def\\a}',",\r
848           "which I'm going to interpret as `\\def\\a{}'.");\r
849       error();\r
850       goto found;\r
851     }\r
852 done:;\r
853   }\r
854   else\r
855   {\r
856     scan_left_brace();\r
857   }\r
858 \r
859   unbalance = 1;\r
860 \r
861   while (true)\r
862   {\r
863     if (xpand)\r
864     {\r
865       while (true)\r
866       {\r
867         get_next();\r
868 \r
869         if (cur_cmd <= max_command)\r
870           goto done2;\r
871 \r
872         if (cur_cmd != the)\r
873         {\r
874           expand();\r
875         }\r
876         else\r
877         {\r
878           q = the_toks();\r
879 \r
880           if (link(temp_head) != 0)\r
881           {\r
882             link(p) = link(temp_head);\r
883             p = q;\r
884           }\r
885         }\r
886       }\r
887 done2:\r
888       x_token();\r
889     }\r
890     else\r
891       get_token();\r
892 \r
893     if (cur_tok < right_brace_limit)\r
894       if (cur_cmd < right_brace)\r
895         incr(unbalance);\r
896       else\r
897       {\r
898         decr(unbalance);\r
899 \r
900         if (unbalance == 0)\r
901           goto found;\r
902       }\r
903     else if (cur_cmd == mac_param)\r
904       if (macro_def)\r
905       {\r
906         s = cur_tok;\r
907 \r
908         if (xpand)\r
909           get_x_token();\r
910         else\r
911           get_token();\r
912 \r
913         if (cur_cmd != mac_param)\r
914           if ((cur_tok <= zero_token) || (cur_tok > t))\r
915           {\r
916             print_err("Illegal parameter number in definition of ");\r
917             sprint_cs(warning_index);\r
918             help3("You meant to type ## instead of #, right?",\r
919                 "Or maybe a } was forgotten somewhere earlier, and things",\r
920                 "are all screwed up? I'm going to assume that you meant ##.");\r
921             back_error();\r
922             cur_tok = s;\r
923           }\r
924           else\r
925             cur_tok = out_param_token - '0' + cur_chr;\r
926       }\r
927 \r
928     store_new_token(cur_tok);\r
929   }\r
930 \r
931 found:\r
932   scanner_status = 0;\r
933 \r
934   if (hash_brace != 0)\r
935     store_new_token(hash_brace);\r
936 \r
937   return p;\r
938 }\r
939 /* sec 0482 */\r
940 void read_toks (integer n, pointer r)\r
941 {\r
942   pointer p;\r
943   pointer q;\r
944   integer s;\r
945   /* small_number m; */\r
946   int m;\r
947 \r
948   scanner_status = defining;\r
949   warning_index = r;\r
950   def_ref = get_avail();\r
951   token_ref_count(def_ref) = 0;\r
952   p = def_ref;\r
953   store_new_token(end_match_token);\r
954 \r
955   if ((n < 0) || (n > 15))\r
956     m = 16;\r
957   else\r
958     m = n;\r
959 \r
960   s = align_state;\r
961   align_state = 1000000L;\r
962 \r
963   do\r
964     {\r
965       begin_file_reading();\r
966       name = m + 1;\r
967 \r
968       if (read_open[m] == closed)\r
969         if (interaction > nonstop_mode)\r
970           if (n < 0)\r
971             prompt_input("");\r
972           else\r
973           {\r
974             wake_up_terminal();\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';\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 /* sec 0523 */\r
1525 void pack_buffered_name_(small_number n, integer a, integer b)\r
1526 {\r
1527   integer k;\r
1528   ASCII_code c;\r
1529   integer j;\r
1530 \r
1531   if (n + b - a + 5 > file_name_size)\r
1532     b = a + file_name_size - n - 5;\r
1533 \r
1534   k = 0;\r
1535 \r
1536   for (j = 1; j <= n; j++)\r
1537     append_to_name(xord[TEX_format_default[j]]);\r
1538 \r
1539   for (j = a; j <= b; j++)\r
1540     append_to_name(buffer[j]);\r
1541 \r
1542   for (j = format_default_length - 3; j <= format_default_length; j++)\r
1543     append_to_name(xord[TEX_format_default[j]]);\r
1544 \r
1545   if (k < file_name_size)\r
1546     name_length = k;\r
1547   else\r
1548     name_length = file_name_size - 1;\r
1549 \r
1550   for (k = name_length + 1; k <= file_name_size; k++)\r
1551     name_of_file[k]= ' ';\r
1552 \r
1553   name_of_file[file_name_size] = '\0';\r
1554 }\r
1555 /* sec 0525 */\r
1556 str_number make_name_string (void)\r
1557 {\r
1558   integer k;\r
1559 \r
1560 #ifdef ALLOCATESTRING\r
1561   if (pool_ptr + name_length > current_pool_size)\r
1562     str_pool = realloc_str_pool(increment_pool_size + name_length);\r
1563 \r
1564   if (str_ptr == current_max_strings)\r
1565     str_start = realloc_str_start(increment_max_strings);\r
1566 \r
1567   if ((pool_ptr + name_length > current_pool_size) || (str_ptr == current_max_strings) || (cur_length > 0))\r
1568 #else\r
1569   if ((pool_ptr + name_length > pool_size) || (str_ptr == max_strings) || (cur_length > 0))\r
1570 #endif\r
1571   {\r
1572     return '?';\r
1573   }\r
1574   else\r
1575   {\r
1576     for (k = 1; k <= name_length; k++)\r
1577       append_char(xord[name_of_file[k]]);\r
1578 \r
1579     return make_string();\r
1580   }\r
1581 }\r
1582 /* sec 0525 */\r
1583 //str_number a_make_name_string (alpha_file * f)\r
1584 str_number a_make_name_string_(void)\r
1585 {\r
1586   return make_name_string();\r
1587 }\r
1588 /* sec 0525 */\r
1589 //str_number b_make_name_string_(byte_file * f)\r
1590 str_number b_make_name_string_(void)\r
1591 {\r
1592   return make_name_string(); \r
1593 }\r
1594 /* sec 0525 */\r
1595 //str_number w_make_name_string_(word_file * f)\r
1596 str_number w_make_name_string_(void)\r
1597 {\r
1598   return make_name_string();\r
1599 }\r
1600 /* sec 0526 */\r
1601 void scan_file_name (void)\r
1602 {\r
1603   name_in_progress = true;\r
1604   begin_name();\r
1605 \r
1606   do\r
1607     {\r
1608       get_x_token(); \r
1609     }\r
1610   while (!(cur_cmd != spacer));\r
1611 \r
1612   quoted_file_name = false;\r
1613 \r
1614   if (allow_quoted_names)\r
1615   {\r
1616     if (cur_chr == '"')\r
1617     {\r
1618       quoted_file_name = true;\r
1619       get_x_token();\r
1620     }\r
1621   }\r
1622 \r
1623   while (true)\r
1624   {\r
1625     if ((cur_cmd > other_char) || (cur_chr > 255)) \r
1626     {\r
1627       back_input();\r
1628       goto done; \r
1629     } \r
1630 \r
1631     if (!more_name(cur_chr))\r
1632       goto done;\r
1633 \r
1634     get_x_token();\r
1635   }\r
1636 \r
1637 done:\r
1638   end_name();\r
1639   name_in_progress = false;\r
1640 }\r
1641 /* argument is string .fmt, .log, .pdf, or .dvi */\r
1642 /* sec 0529 */\r
1643 void pack_job_name_(str_number s)\r
1644 {\r
1645   cur_area = 335; /* "" */\r
1646   cur_ext  = s;\r
1647   cur_name = job_name;\r
1648   pack_file_name(cur_name, cur_area, cur_ext);\r
1649 }\r
1650 /* sec 0530 */\r
1651 void prompt_file_name_(const char * s, str_number e) \r
1652 {\r
1653   integer k;\r
1654 \r
1655   if (interaction == scroll_mode)\r
1656     wake_up_terminal();\r
1657 \r
1658   if (!strcmp("input file name", s))\r
1659     print_err("I can't find file `");\r
1660   else\r
1661     print_err("I can't write on file `");\r
1662 \r
1663   print_file_name(cur_name, cur_area, cur_ext);\r
1664   prints("'.");\r
1665 \r
1666   if (e == 785)    /* .tex */\r
1667     show_context();\r
1668 \r
1669   print_nl("Please type another ");\r
1670   prints(s); \r
1671 \r
1672   if (interaction < scroll_mode)\r
1673   {\r
1674     fatal_error("*** (job aborted, file error in nonstop mode)");\r
1675     return;\r
1676   }\r
1677 \r
1678   if (!knuth_flag)\r
1679     show_line(" (or Ctrl-Z to exit)", 0);\r
1680 \r
1681   prompt_input(": ");\r
1682 \r
1683   {\r
1684     begin_name();\r
1685     k = first;\r
1686 \r
1687     while ((buffer[k] == ' ') && (k < last))\r
1688       incr(k);\r
1689 \r
1690     quoted_file_name = false;\r
1691 \r
1692     if (allow_quoted_names && k < last) /* check whether quoted name */\r
1693     {\r
1694       if (buffer[k]== '"')\r
1695       {\r
1696         quoted_file_name = true;\r
1697         incr(k);\r
1698       }\r
1699     }\r
1700 \r
1701     while (true)\r
1702     {\r
1703       if (k == last)\r
1704         goto done;\r
1705 \r
1706       /* convert tilde '~' to pseudo tilde */\r
1707       if (pseudo_tilde != 0 && buffer[k]== '~')\r
1708         buffer[k] = pseudo_tilde;\r
1709 \r
1710       /* convert space ' ' to pseudo space */\r
1711       if (pseudo_space != 0 && buffer[k]== ' ')\r
1712         buffer[k] = pseudo_space;\r
1713 \r
1714       if (!more_name(buffer[k]))\r
1715         goto done;\r
1716 \r
1717       incr(k);\r
1718     }\r
1719 \r
1720 done:\r
1721     end_name();\r
1722   }\r
1723 \r
1724   if (cur_ext == 335) /* "" */\r
1725     cur_ext = e;      /* use default extension */\r
1726 \r
1727   pack_file_name(cur_name, cur_area, cur_ext);\r
1728 }\r
1729 /* sec 0534 */\r
1730 void open_log_file (void)\r
1731 {\r
1732   char old_setting;\r
1733   integer k;\r
1734   integer l;\r
1735   char * months;\r
1736 \r
1737   old_setting = selector;\r
1738 \r
1739   if (job_name == 0)\r
1740     job_name = get_job_name(790);\r
1741     //job_name = 790;\r
1742 \r
1743   pack_job_name(".log");\r
1744 \r
1745   while (!a_open_out(log_file))\r
1746   {\r
1747     selector = term_only;\r
1748     prompt_file_name("transcript file name", ".log");\r
1749   }\r
1750 \r
1751   log_name = a_make_name_string(log_file);\r
1752   selector = log_only;\r
1753   log_opened = true;\r
1754 \r
1755   {\r
1756     log_printf("%s (%s %s)", banner, application, yandyversion);\r
1757 \r
1758     if (format_ident > 0)\r
1759       slow_print(format_ident);\r
1760 \r
1761     prints("  ");\r
1762 \r
1763     if (civilize_flag)\r
1764       print_int(year);\r
1765     else\r
1766       print_int(day);\r
1767 \r
1768     print_char(' ');\r
1769     months = " JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";\r
1770 \r
1771     for (k = 3 * month - 2; k <= 3 * month; k++)\r
1772       putc(months[k], log_file);\r
1773 \r
1774     print_char(' ');\r
1775 \r
1776     if (civilize_flag)\r
1777       print_int(day);\r
1778     else\r
1779       print_int(year);\r
1780 \r
1781     print_char(' ');\r
1782     print_two(tex_time / 60);\r
1783     print_char(':');\r
1784     print_two(tex_time % 60);\r
1785   }\r
1786 \r
1787   input_stack[input_ptr] = cur_input;\r
1788   print_nl("**");\r
1789   l = input_stack[0].limit_field;\r
1790 \r
1791   if (buffer[l] == end_line_char)\r
1792     decr(l);\r
1793 \r
1794   for (k = 1; k <= l; k++)\r
1795     print(buffer[k]);\r
1796 \r
1797   print_ln(); \r
1798 \r
1799   if (show_fmt_flag)\r
1800   {\r
1801     if (format_file != NULL)\r
1802     {\r
1803       log_printf("(%s)\n", format_file);\r
1804       free(format_file);\r
1805       format_file = NULL;\r
1806     }\r
1807   }\r
1808 \r
1809   selector = old_setting + 2;\r
1810 }\r
1811 /* sec 0537 */\r
1812 void start_input (void)\r
1813 {\r
1814   scan_file_name();\r
1815   pack_file_name(cur_name, cur_area, cur_ext); \r
1816 \r
1817   while (true)\r
1818   {\r
1819     begin_file_reading();\r
1820     \r
1821     if (a_open_in(cur_file, kpse_tex_format))\r
1822       goto done;\r
1823 \r
1824     end_file_reading();\r
1825     prompt_file_name("input file name", ".tex");\r
1826   }\r
1827 \r
1828 done: \r
1829   name = a_make_name_string(cur_file);\r
1830 \r
1831   if (job_name == 0)\r
1832   {\r
1833     job_name = get_job_name(cur_name);\r
1834     //job_name = cur_name;\r
1835     open_log_file();\r
1836   }\r
1837 \r
1838   if (term_offset + length(name) > max_print_line - 2)\r
1839     print_ln();\r
1840   else if ((term_offset > 0) || (file_offset > 0))\r
1841     print_char(' ');\r
1842 \r
1843   print_char('(');\r
1844   incr(open_parens);\r
1845 \r
1846   if (open_parens > max_open_parens)\r
1847     max_open_parens = open_parens;\r
1848 \r
1849   slow_print(name);\r
1850   update_terminal();\r
1851   state = new_line;\r
1852 \r
1853   {\r
1854     line = 1;\r
1855 \r
1856     if (input_ln(cur_file, false))\r
1857       do_nothing();\r
1858 \r
1859     firm_up_the_line();\r
1860 \r
1861     if (end_line_char_inactive())\r
1862       decr(limit);\r
1863     else\r
1864       buffer[limit] = end_line_char;\r
1865 \r
1866     first = limit + 1;\r
1867     loc = start;\r
1868   }\r
1869 }\r
1870 /* sec 0560 */\r
1871 internal_font_number read_font_info (pointer u, str_number nom, str_number aire, scaled s)\r
1872 {\r
1873   font_index k;\r
1874   boolean file_opened;\r
1875   halfword lf, lh, nw, nh, nd, ni, nl, nk, ne, np;\r
1876   int bc, ec;\r
1877   internal_font_number f;\r
1878   internal_font_number g;\r
1879   eight_bits a, b, c, d;\r
1880   four_quarters qw;\r
1881   scaled sw;\r
1882   integer bch_label;\r
1883   short bchar;\r
1884   scaled z;\r
1885   integer alpha;\r
1886   char beta;\r
1887 \r
1888   g = 0;\r
1889   file_opened = false;\r
1890   pack_file_name(nom, aire, 805); /* .tfm */\r
1891 \r
1892   if (!b_open_in(tfm_file))\r
1893     goto bad_tfm;\r
1894 \r
1895   file_opened = true;\r
1896 \r
1897   {\r
1898     read_sixteen(lf);\r
1899     fget();\r
1900     read_sixteen(lh);\r
1901     fget();\r
1902     read_sixteen(bc);\r
1903     fget();\r
1904     read_sixteen(ec);\r
1905 \r
1906     if ((bc > ec + 1) || (ec > 255))\r
1907       goto bad_tfm;\r
1908 \r
1909     if (bc > 255)\r
1910     {\r
1911       bc = 1;\r
1912       ec = 0;\r
1913     }\r
1914 \r
1915     fget();\r
1916     read_sixteen(nw);\r
1917     fget();\r
1918     read_sixteen(nh);\r
1919     fget();\r
1920     read_sixteen(nd);\r
1921     fget();\r
1922     read_sixteen(ni);\r
1923     fget();\r
1924     read_sixteen(nl);\r
1925     fget();\r
1926     read_sixteen(nk);\r
1927     fget();\r
1928     read_sixteen(ne);\r
1929     fget();\r
1930     read_sixteen(np);\r
1931 \r
1932     if (lf != 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np)\r
1933       goto bad_tfm;\r
1934 \r
1935     if ((nw == 0) || (nh == 0) || (nd == 0) || (ni == 0))\r
1936       goto bad_tfm;\r
1937   }\r
1938 \r
1939   lf = lf - 6 - lh;\r
1940 \r
1941   if (np < 7)\r
1942     lf = lf + 7 - np;\r
1943 \r
1944 #ifdef ALLOCATEFONT\r
1945   if ((fmem_ptr + lf > current_font_mem_size))\r
1946     font_info = realloc_font_info (increment_font_mem_size + lf);\r
1947 \r
1948   if ((font_ptr == font_max) || (fmem_ptr + lf > current_font_mem_size))\r
1949 #else\r
1950   if ((font_ptr == font_max) || (fmem_ptr + lf > font_mem_size))\r
1951 #endif\r
1952   {\r
1953     if (trace_flag)\r
1954       printf("font_ptr %lld font_max %d fmem_ptr %lld lf %d font_mem_size %ld\n",\r
1955           font_ptr, font_max, fmem_ptr, lf, font_mem_size);\r
1956 \r
1957     start_font_error_message();\r
1958     prints(" not loaded: Not enough room left");\r
1959     help4("I'm afraid I won't be able to make use of this font,",\r
1960         "because my memory for character-size data is too small.",\r
1961         "If you're really stuck, ask a wizard to enlarge me.",\r
1962         "Or maybe try `I\\font<same font id>=<name of loaded font>'.");\r
1963     error();\r
1964     goto done;\r
1965   }\r
1966 \r
1967   f = font_ptr + 1;\r
1968   char_base[f] = fmem_ptr - bc;\r
1969   width_base[f] = char_base[f] + ec + 1;\r
1970   height_base[f] = width_base[f] + nw;\r
1971   depth_base[f] = height_base[f] + nh;\r
1972   italic_base[f] = depth_base[f] + nd;\r
1973   lig_kern_base[f] = italic_base[f] + ni;\r
1974   kern_base[f] = lig_kern_base[f] + nl - kern_base_offset;\r
1975   exten_base[f] = kern_base[f] + kern_base_offset + nk;\r
1976   param_base[f] = exten_base[f] + ne;\r
1977 \r
1978   {\r
1979     if (lh < 2)\r
1980       goto bad_tfm;\r
1981     \r
1982     store_four_quarters(font_check[f]);\r
1983     fget();\r
1984     read_sixteen(z);\r
1985     fget();\r
1986     z = z * 256 + fbyte;\r
1987     fget();\r
1988     z = (z * 16) + (fbyte / 16);\r
1989 \r
1990     if (z < unity)\r
1991       goto bad_tfm; \r
1992 \r
1993     while (lh > 2)\r
1994     {\r
1995       fget();\r
1996       fget();\r
1997       fget();\r
1998       fget();\r
1999       decr(lh);\r
2000     }\r
2001 \r
2002     font_dsize[f] = z;\r
2003 \r
2004     if (s != -1000)\r
2005       if (s >= 0)\r
2006         z = s;\r
2007       else\r
2008         z = xn_over_d(z, - (integer) s, 1000);\r
2009 \r
2010     font_size[f] = z;\r
2011   }\r
2012 \r
2013   for (k = fmem_ptr; k <= width_base[f] - 1; k++)\r
2014   {\r
2015     store_four_quarters(font_info[k].qqqq);\r
2016 \r
2017     if ((a >= nw) || (b / 16 >= nh) || (b % 16 >= nd) || (c / 4 >= ni))\r
2018       goto bad_tfm;\r
2019 \r
2020     switch (c % 4)\r
2021     {\r
2022       case lig_tag:\r
2023         if (d >= nl)\r
2024           goto bad_tfm;\r
2025         break;\r
2026 \r
2027       case ext_tag:\r
2028         if (d >= ne)\r
2029           goto bad_tfm;\r
2030         break;\r
2031 \r
2032       case list_tag:\r
2033         {\r
2034           check_byte_range(d);\r
2035 \r
2036           while (d < k + bc - fmem_ptr)\r
2037           {\r
2038             qw = char_info(f, d);\r
2039  \r
2040             if (char_tag(qw) != list_tag)\r
2041               goto not_found;\r
2042 \r
2043             d = rem_byte(qw);\r
2044           }\r
2045 \r
2046           if (d == k + bc - fmem_ptr)\r
2047             goto bad_tfm;\r
2048 not_found:;\r
2049         }\r
2050         break;\r
2051 \r
2052       default:\r
2053         break;\r
2054     }\r
2055   }\r
2056 \r
2057   {\r
2058     {\r
2059       alpha = 16;\r
2060 \r
2061       while (z >= 8388608L)   /* 2^23 */\r
2062       {\r
2063         z = z / 2;\r
2064         alpha = alpha + alpha;\r
2065       }\r
2066 \r
2067       beta = (char) (256 / alpha);\r
2068       alpha = alpha * z;\r
2069     }\r
2070 \r
2071     for (k = width_base[f]; k <= lig_kern_base[f] - 1; k++)\r
2072       store_scaled(font_info[k].cint);\r
2073 \r
2074     if (font_info[width_base[f]].cint != 0)\r
2075       goto bad_tfm;\r
2076 \r
2077     if (font_info[height_base[f]].cint != 0)\r
2078       goto bad_tfm;\r
2079 \r
2080     if (font_info[depth_base[f]].cint != 0)\r
2081       goto bad_tfm;\r
2082 \r
2083     if (font_info[italic_base[f]].cint != 0)\r
2084       goto bad_tfm;\r
2085   }\r
2086 \r
2087   bch_label = 32767;     /* '77777 */\r
2088   bchar = 256;\r
2089 \r
2090   if (nl > 0)\r
2091   {\r
2092     for (k = lig_kern_base[f]; k <= kern_base[f] + kern_base_offset - 1; k++)\r
2093     {\r
2094       store_four_quarters(font_info[k].qqqq);\r
2095 \r
2096       if (a > 128)\r
2097       {\r
2098         if (256 * c + d >= nl)\r
2099           goto bad_tfm;\r
2100 \r
2101         if (a == 255)\r
2102           if (k == lig_kern_base[f])\r
2103             bchar = b;\r
2104       }\r
2105       else\r
2106       {\r
2107         if (b != bchar)\r
2108           check_existence(b);\r
2109 \r
2110         if (c < 128)\r
2111           check_existence(d);\r
2112         else if (256 * (c - 128) + d >= nk)\r
2113           goto bad_tfm;\r
2114 \r
2115         if (a < 128)\r
2116           if (k - lig_kern_base[f] + a + 1 >= nl)\r
2117             goto bad_tfm;\r
2118       }\r
2119     }\r
2120 \r
2121     if (a == 255)\r
2122       bch_label = 256 * c + d;\r
2123   }\r
2124 \r
2125   for (k = kern_base[f] + kern_base_offset; k <= exten_base[f] - 1; k++)\r
2126     store_scaled(font_info[k].cint);\r
2127 \r
2128   for (k = exten_base[f]; k <= param_base[f] - 1; k++)\r
2129   {\r
2130     store_four_quarters(font_info[k].qqqq);\r
2131 \r
2132     if (a != 0)\r
2133       check_existence(a);\r
2134 \r
2135     if (b != 0)\r
2136       check_existence(b);\r
2137 \r
2138     if (c != 0)\r
2139       check_existence(c);\r
2140 \r
2141     check_existence(d);\r
2142   }\r
2143 \r
2144   {\r
2145     for (k = 1; k <= np; k++)\r
2146       if (k == 1)\r
2147       {\r
2148         fget();\r
2149         sw = fbyte;\r
2150 \r
2151         if (sw > 127)\r
2152           sw = sw - 256;\r
2153 \r
2154         fget();\r
2155         sw = sw * 256 + fbyte;\r
2156         fget();\r
2157         sw = sw * 256 + fbyte;\r
2158         fget();\r
2159         font_info[param_base[f]].cint = (sw * 16) + (fbyte / 16);\r
2160       }\r
2161       else\r
2162         store_scaled(font_info[param_base[f] + k - 1].cint);\r
2163 \r
2164     if (feof(tfm_file))\r
2165       goto bad_tfm;\r
2166 \r
2167     for (k = np + 1; k <= 7; k++)\r
2168       font_info[param_base[f] + k - 1].cint = 0;\r
2169   }\r
2170 \r
2171   if (np >= 7)\r
2172     font_params[f] = np;\r
2173   else\r
2174     font_params[f] = 7;\r
2175 \r
2176   hyphen_char[f] = default_hyphen_char;\r
2177   skew_char[f] = default_skew_char;\r
2178 \r
2179   if (bch_label < nl)\r
2180     bchar_label[f] = bch_label + lig_kern_base[f];\r
2181   else\r
2182     bchar_label[f] = non_address;\r
2183 \r
2184   font_bchar[f] = bchar;\r
2185   font_false_bchar[f] = bchar;\r
2186 \r
2187   if (bchar <= ec)\r
2188     if (bchar >= bc)\r
2189     {\r
2190       qw = char_info(f, bchar);\r
2191 \r
2192       if (char_exists(qw))\r
2193         font_false_bchar[f] = 256;\r
2194     }\r
2195 \r
2196   font_name[f] = nom;\r
2197   font_area[f] = aire;\r
2198   font_bc[f] = bc;\r
2199   font_ec[f] = ec;\r
2200   font_glue[f] = 0;\r
2201   adjust(char_base);\r
2202   adjust(width_base);\r
2203   adjust(lig_kern_base);\r
2204   adjust(kern_base);\r
2205   adjust(exten_base);\r
2206   decr(param_base[f]);\r
2207   fmem_ptr = fmem_ptr + lf;\r
2208   font_ptr = f;\r
2209   g = f;\r
2210   goto done;\r
2211 \r
2212 bad_tfm:\r
2213   start_font_error_message();\r
2214 \r
2215   if (file_opened)\r
2216     prints(" not loadable: Bad metric (TFM) file");\r
2217   else\r
2218     prints(" not loadable: Metric (TFM) file not found");\r
2219 \r
2220   help5("I wasn't able to read the size data for this font,",\r
2221       "so I will ignore the font specification.",\r
2222       "[Wizards can fix TFM files using TFtoPL/PLtoTF.]",\r
2223       "You might try inserting a different font spec;",\r
2224       "e.g., type `I\\font<same font id>=<substitute font name>'.");\r
2225   error();\r
2226 \r
2227 done:\r
2228   if (file_opened)\r
2229     b_close(tfm_file);\r
2230 \r
2231   return g;\r
2232 }