6 #pragma warning(disable:4115) // kill rpcasync.h complaint
8 #define MYLIBAPI __declspec(dllexport)
13 #pragma warning(disable:4996)
14 #pragma warning(disable:4131) // old style declarator
15 #pragma warning(disable:4135) // conversion between different integral types
16 #pragma warning(disable:4127) // conditional expression is constant
25 static void winerror (char * message)
27 (void) MessageBox(NULL, message, "YandYTeX.DLL", MB_ICONSTOP | MB_OK);
31 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
32 void set_cur_lang(void)
36 else if (language > 255)
41 INLINE void free_avail_(halfword p)
49 INLINE void dvi_out_(ASCII_code op)
51 dvi_buf[dvi_ptr] = op;
53 if (dvi_ptr == dvi_limit)
56 INLINE void succumb (void)
58 if (interaction == error_stop_mode)
59 interaction = scroll_mode;
72 INLINE void flush_string (void)
75 pool_ptr = str_start[str_ptr];
77 INLINE void append_char (ASCII_code c)
79 str_pool[pool_ptr] = c;
82 INLINE void append_lc_hex (ASCII_code c)
87 append_char(c - 10 + 'a');
89 INLINE void print_err (const char * s)
91 if (interaction == error_stop_mode);
95 INLINE void tex_help (unsigned int n, ...)
104 va_start(help_arg, n);
106 for (i = n - 1; i > n - 1; --i)
107 help_line[i] = va_arg(help_arg, char *);
111 INLINE void str_room_ (int val)
113 #ifdef ALLOCATESTRING
114 if (pool_ptr + val > current_pool_size)
115 str_pool = realloc_str_pool(increment_pool_size);
117 if (pool_ptr + val > current_pool_size)
119 overflow("pool size", current_pool_size - init_pool_ptr);
122 if (pool_ptr + val > pool_size)
124 overflow("pool size", pool_size - init_pool_ptr); /* pool size */
128 INLINE void tail_append_ (pointer val)
133 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
135 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
145 (void) putc ('\n', log_file);
149 (void) putc ('\n', log_file);
161 (void) putc ('\n', write_file[selector]);
166 void print_char_ (ASCII_code s)
168 if (s == new_line_char)
169 if (selector < pseudo)
178 (void) show_char(Xchr(s));
180 (void) putc(Xchr(s), log_file);
183 if (term_offset == max_print_line)
189 if (file_offset == max_print_line)
191 (void) putc ('\n', log_file);
197 (void) putc(Xchr(s), log_file);
199 if (file_offset == max_print_line)
203 (void) show_char(Xchr(s));
205 if (term_offset == max_print_line)
211 if (tally < trick_count)
212 trick_buf[tally % error_line] = s;
215 #ifdef ALLOCATESTRING
216 if (pool_ptr + 1 > current_pool_size)
218 str_pool = realloc_str_pool (increment_pool_size);
221 if (pool_ptr < current_pool_size)
223 str_pool[pool_ptr]= s;
227 if (pool_ptr < pool_size)
229 str_pool[pool_ptr]= s;
235 (void) putc(Xchr(s), write_file[selector]);
241 /* This could be made more efficient using fputs ? ... bkph */
242 void print_ (integer s)
252 if (selector > pseudo)
258 if ((s == new_line_char))
267 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
268 /* translate ansi to dos 850 */
269 if (!show_in_hex && s < 256 && s >= 32)
271 if (show_in_dos && s > 127)
273 if (wintodos[s-128] > 0)
274 print_char (wintodos[s - 128]);
278 while (j < str_start[s + 1])
280 print_char(str_pool[j]);
286 print_char(s); /* don't translate to hex */
289 { /* not just a character */
291 while (j < str_start[s + 1])
293 print_char(str_pool[j]);
297 new_line_char = nl; /* restore eol */
300 /* we get here with s > 256 - i.e. not a single character */
302 while (j < str_start[s + 1])
304 print_char(str_pool[j]);
308 /* string version print. */
309 void print_string_ (unsigned char *s)
315 // print string number s from string pool by calling print_
316 void slow_print_ (integer s)
320 if ((s >= str_ptr) || (s < 256))
325 while (j < str_start[s + 1])
327 /* if (str_pool[j]>= 128) print(str_pool[j] - 128); */ // debugging only
328 /* if (str_pool[j]== 0) print(36); */ // debugging only
335 // print newline followed by string number s (unless at start of line)
336 void print_nl_ (const char * s)
338 if (((term_offset > 0) && (odd(selector))) ||
339 ((file_offset > 0) && (selector >= log_only)))
345 // print string number s preceded by escape character
346 void print_esc_ (const char * s)
359 void print_the_digs_ (eight_bits k)
365 print_char('0' + dig[k]);
367 print_char('A' + dig[k]);
371 void print_int_ (integer n)
398 dig[k] = (char) (n % 10);
405 void print_cs_ (integer p)
408 if (p >= single_base)
412 print_esc("endcsname");
417 print_esc("");print(p - 257);
418 /* if cat_code(p - single_base) = letter then ... p.262 */
419 if (eqtb[(hash_size + 1883) + p - 257].hh.v.RH == letter)
423 print_esc("IMPOSSIBLE.");
425 else if (p >= (hash_size + 781)) /* undefined_control_sequence */
426 print_esc("IMPOSSIBLE.");
427 else if ((hash[p].v.RH >= str_ptr))
428 print_esc("NONEXISTENT.");
431 print_esc(""); print(hash[p].v.RH);
436 void sprint_cs_(halfword p)
438 if (p < hash_base) /* if p < hash_base then ... p.263 */
439 if (p < single_base) /* if p < single_base then ... p.263 */
440 print(p - active_base); /* print (p - active_base); */
441 else if (p < null_cs) /* else if p < null_cs then ... */
443 print_esc(""); print(p - single_base);
448 print_esc("endcsname");
452 print_esc(""); print(hash[p].v.RH);
456 /* ! I can't find file ` c:/foo/ accents .tex '. */
457 void print_file_name_(integer n, integer a, integer e)
459 /* sprintf(log_line, "\na %d n %d e %d\n", a, n, e); */
460 /* show_line(log_line, 0); */
461 // print_char('!'); // debugging only
463 // print_char('!'); // debugging only
465 // print_char('!'); // debugging only
467 // print_char('!'); // debugging only
470 void print_size_ (integer s)
473 print_esc("textfont");
475 print_esc("scriptfont");
477 print_esc("scriptscriptfont");
480 void print_write_whatsit_(str_number s, halfword p)
482 print_esc(""); print(s);
483 if (mem[p + 1].hh.v.LH < 16)
484 print_int(mem[p + 1].hh.v.LH);
485 else if (mem[p + 1].hh.v.LH == 16)
487 else print_char('-');
490 // called from itex.c and tex0.c only NASTY NASTY!
491 // now uses uses non-local goto (longjmp) 1999/Nov/7
494 close_files_and_terminate();
504 show_line("EXITING at JUMPOUT\n", 0);
506 if ((history != 0) && (history != 1))
515 // deal with error by asking for user response 0-9, D, E, H, I, X, Q, R, S
516 // NOTE: this may JUMPOUT either via X, or because of too many errors
520 integer s1, s2, s3, s4;
522 if (history < error_message_issued)
523 history = error_message_issued;
528 if (interaction == error_stop_mode)
532 clear_for_error_prompt();
535 term_input("? ", help_ptr);
541 c = buffer[first]; // analyze first letter typed
543 if (c >= 'a') // uppercase letter first
544 c = (unsigned char) (c + 'A' - 'a');
558 if (deletions_allowed)
564 align_state = 1000000L;
565 OK_to_interrupt = false;
567 if ((last > first + 1) && (buffer[first + 1] >= '0') && (buffer[first + 1] <= '9'))
568 c = (unsigned char) (c * 10 + buffer[first + 1] - '0' * 11);
570 c = (unsigned char) (c - 48);
582 OK_to_interrupt = true;
583 help2("I have just deleted some text, as you asked.",
584 "You can now delete more, or insert, or whatever.");
586 goto lab22; /* loop again */
593 goto lab22; /* loop again */
600 edit_name_start = str_start[input_stack[base_ptr].name_field];
601 edit_name_length = length(input_stack[base_ptr].name_field);
611 use_err_help = false;
616 help2("Sorry, I don't know how to help in this situation.",
617 "Maybe you should try asking a human?");
620 print_string(help_line[help_ptr]);
622 } while (!(help_ptr == 0));
625 help4("Sorry, I already gave what help I could...",
626 "Maybe you should try asking a human?",
627 "An error might have occurred before I noticed any problems.",
628 "``If all else fails, read the instructions.''");
629 goto lab22; /* loop again */
634 begin_file_reading();
636 if (last > first + 1)
638 cur_input.loc_field = first + 1;
644 print_string("insert>");
645 term_input("insert>", 0);
647 cur_input.loc_field = first;
650 cur_input.limit_field = last - 1;
659 interaction = 0 + c - 81; /* Q = 0, R = 1, S = 2, T = 3 */
660 print_string("OK, entering ");
665 print_esc("batchmode");
669 print_esc("nonstopmode");
672 print_esc("scrollmode");
692 } /* end of switch analysing response character */
695 print_string("Type <return> to proceed, S to scroll future error messages,");
696 print_nl("R to run without stopping, Q to run quietly,");
697 print_nl("I to insert something, ");
700 print_string("E to edit your file,");
702 if (deletions_allowed)
703 print_nl("1 or ... or 9 to ignore the next 1 to 9 tokens of input,");
705 print_nl("H for help, X to quit.");
707 } /* end of while(true) loop */
711 if (error_count == 100)
713 print_nl("(That makes 100 errors; please try again.)");
718 if (interaction > batch_mode)
726 else while(help_ptr > 0)
729 print_nl(help_line[help_ptr] == NULL ? "" : help_line[help_ptr]);
734 if (interaction > batch_mode)
740 void fatal_error_(char * s)
742 normalize_selector();
743 print_err("Emergency stop");
748 void overflow_(char * s, integer n)
750 normalize_selector();
751 print_err("TeX capacity exceeded, sorry [");
756 help2("If you really absolutely need more capacity,",
757 "you can ask a wizard to enlarge me.");
761 if (!strcmp(s, "pattern memory") && n == trie_size)
763 sprintf(log_line, "\n (Maybe use -h=... on command line in ini-TeX)\n");
764 show_line(log_line, 0);
765 } else if (!strcmp(s, "exception dictionary") && n == hyphen_prime)
767 sprintf(log_line, "\n (Maybe use -e=... on command line in ini-TeX)\n");
768 show_line(log_line, 0);
774 void confusion_(char * s)
776 normalize_selector();
778 if (history < error_message_issued)
780 print_err("This can't happen (");
783 help1("I'm broken. Please show this to someone who can fix can fix");
787 print_err("I can't go on meeting you like this");
788 help2("One of your faux pas seems to have wounded me deeply...",
789 "in fact, I'm barely conscious. Please fix it and try again.");
794 bool init_terminal (void)
796 register bool Result;
802 cur_input.loc_field = first;
803 while((cur_input.loc_field < last) && (buffer[cur_input.loc_field]== ' '))
804 incr(cur_input.loc_field); // step over initial white space
805 if (cur_input.loc_field < last)
808 return Result; // there is an input file name
812 // failed to find input file name
815 flag = ConsoleInput("**", "Please type a file name or a control sequence\r\n(or ^z to exit)", (char *) &buffer[first]);
816 last = first + strlen((char *) &buffer[first]); /* -1 ? */
817 // may need to be more elaborate see input_line in texmf.c
819 (void) fputs("**", stdout);
821 flag = input_ln(stdin, true);
826 show_line("! End of file on the terminal... why?\n", 1);
831 cur_input.loc_field = first;
832 while ((cur_input.loc_field < last) && (buffer[cur_input.loc_field]== ' '))
833 incr(cur_input.loc_field); // step over intial white space
834 if (cur_input.loc_field < last)
837 return Result; // there is an input file name
840 sprintf(log_line, "%s\n", "Please type the name of your input file.");
841 show_line(log_line, 1);
845 // Make string from str_start[str_ptr] to pool_ptr
846 str_number make_string (void)
848 register str_number Result;
850 #ifdef ALLOCATESTRING
851 if (str_ptr == current_max_strings)
852 str_start = realloc_str_start(increment_max_strings);
854 if (str_ptr == current_max_strings)
856 overflow("number of strings", current_max_strings - init_str_ptr); /* 97/Mar/9 */
857 return 0; // abort_flag set
860 if (str_ptr == max_strings)
862 overflow("number of strings", max_strings - init_str_ptr);
863 return 0; // abort_flag set
867 str_start[str_ptr] = pool_ptr;
868 Result = str_ptr - 1;
872 bool str_eq_buf_ (str_number s, integer k)
874 register bool Result;
878 while (j < str_start[s + 1])
880 if (str_pool[j]!= buffer[k])
894 bool str_eq_str_ (str_number s, str_number t)
896 register bool Result;
900 if (length(s) != length(t))
904 while (j < str_start[s + 1])
906 if (str_pool[j] != str_pool[k])
917 void print_two_(integer n)
920 print_char('0' + (n / 10));
921 print_char('0' + (n % 10));
924 void print_hex_(integer n)
930 dig[k] = (unsigned char) (n % 16);
937 void print_roman_int_(integer n)
940 nonnegative_integer u, v;
941 j = str_start[260]; /* m2d5c2l5x2v5i */
945 print_char(str_pool[j]);
951 u = v / (str_pool[k - 1] - '0');
952 if (str_pool[k - 1] == 50)
955 u = u / (str_pool[k - 1] - '0');
959 print_char(str_pool[k]);
965 v = v / (str_pool[j - 1]- '0');
970 void print_current_string (void)
973 j = str_start[str_ptr];
976 print_char(str_pool[j]);
981 int stringlength (int str_ptr)
984 nstart = str_start[str_ptr];
985 nnext = str_start[str_ptr + 1];
986 return (nnext - nstart) + 2;
989 char * add_string (char *s, char * str_string)
992 n = strlen(str_string);
993 memcpy(s, &str_string, n);
1002 // make one long \r\n separated string out of help lines
1003 // str_pool is packed_ASCII_code *
1005 char * make_up_help_string (int nhelplines)
1007 char * helpstring, *s;
1010 // get length of help for this specific message
1011 for (k = nhelplines - 1; k >= 0; k--) {
1012 //nlen += stringlength(help_line[k]);
1013 nlen += strlen(help_line[k]);
1015 nlen += 2; // for blank line separator: "\r\n"
1017 nlen += stringlength(265);
1018 nlen += stringlength(266);
1019 nlen += stringlength(267);
1021 nlen += stringlength(268);
1022 if (deletions_allowed)
1023 nlen += stringlength(269);
1024 nlen += stringlength(270);
1026 helpstring = (char *) malloc(nlen + 1); // +1 = '\0'
1028 for (k = nhelplines-1; k >= 0; k--) {
1029 s = add_string(s, help_line[k]);
1034 s = add_string(s, "Type <return> to proceed, S to scroll future error messages,");
1035 s = add_string(s, "R to run without stopping, Q to run quietly,");
1036 s = add_string(s, "I to insert something, ");
1038 s = add_string(s, "E to edit your file, ");
1039 if (deletions_allowed)
1040 s = add_string(s, "1 or ... or 9 to ignore the next 1 to 9 tokens of input,");
1041 s = add_string(s, "H for help, X to quit.");
1046 char * make_up_query_string (int promptstr)
1049 int nstart, nnext, n;
1051 nstart = str_start[ promptstr];
1052 nnext = str_start[ promptstr + 1];
1054 querystr = (char *) malloc(n + 1);
1056 memcpy(s, &str_pool[nstart], n);
1062 // abort_flag set if input_line / ConsoleInput returns non-zero
1063 // should set interrupt instead ???
1064 // called from tex0.c, tex2.c, tex3.c
1066 // void term_input(void)
1067 void term_input (char * term_str, int term_help_lines)
1071 char * helpstring = NULL;
1072 char * querystring = NULL;
1073 // if (nhelplines != 0) {
1074 // helpstring = make_up_help_string (nhelplines);
1075 // printf(helpstring);
1076 // free(helpstring);
1078 show_line("\n", 0); // force it to show what may be buffered up ???
1081 if (term_str != NULL) querystring = term_str;
1082 if (term_help_lines != NULL) helpstring = make_up_help_string(term_help_lines);
1083 if (helpstring == NULL && querystring != NULL)
1085 if (strcmp(querystring, ": ") == 0)
1086 helpstring = xstrdup("Please type another file name (or ^z to exit):");
1087 else if (strcmp(querystring, "=>") == 0) // from firm_up_the_line
1088 helpstring = xstrdup("Please type <enter> to accept this line\r\nor type a replacement line");
1089 else if (strcmp(querystring, "insert>") == 0) // from error() after "I"
1090 helpstring = xstrdup("Please type something to insert here");
1091 else if (strcmp(querystring, "") == 0) // from read_toks
1092 helpstring = xstrdup("Please type a control sequence");
1093 else if (strcmp(querystring, "= ") == 0) // from read_toks
1094 helpstring = xstrdup("Please type a token");
1095 else if (strcmp(querystring, "*") == 0) // get_next
1096 helpstring = xstrdup("Please type a control sequence\r\n(or ^z to exit)");
1098 flag = ConsoleInput(querystring, helpstring, (char *) &buffer[first]); // ???
1099 // flag == 0 means trouble --- EOF on terminal
1100 if (querystring != NULL) free(querystring);
1101 if (helpstring != NULL) free(helpstring);
1102 helpstring = querystring = NULL;
1104 last = first + strlen((char *) &buffer[first]); /* -1 ? */
1105 // flag = (last > first);
1106 // may need to be more elaborate see input_line in texmf.c ???
1107 // sprintf(log_line, "first %d last %d flag %d - %s",
1108 // first, last, flag, (char *) &buffer[first]);
1109 // winerror(log_line);
1112 flag = input_ln(stdin, true);
1116 fatal_error("End of file on the terminal!");
1117 return; // abort_flag set
1121 // echo what was typed into Console buffer also
1123 for (k = first; k <= last - 1; k++)
1127 decr(selector); // shut off echo
1129 for (k = first; k <= last - 1; k++)
1132 incr(selector); // reset selector again
1136 void int_error_ (integer n)
1144 void normalize_selector (void)
1147 selector = term_and_log;
1149 selector = term_only;
1154 if (interaction == batch_mode)
1158 void pause_for_instructions (void)
1160 if (OK_to_interrupt)
1162 interaction = error_stop_mode;
1163 if ((selector == log_only) || (selector == no_print))
1165 print_err("Interruption");
1167 "Try to insert some instructions for me (e.g.,`I\\showlists'),",
1168 "unless you just want to quit by typing `X'.");
1169 deletions_allowed = false;
1171 deletions_allowed = true;
1176 integer half_(integer x)
1178 register integer Result;
1180 Result =(x + 1) / 2;
1186 scaled round_decimals_(small_number k)
1188 register scaled Result;
1193 a = (a + dig[k] * 131072L) / 10; /* 2^17 */
1195 Result =(a + 1) / 2;
1199 /* This has some minor speedup changes - no real advantage probably ... */
1200 void print_scaled_(scaled s)
1209 print_int(s / 65536L);
1211 s = 10 * (s % 65536L) + 5;
1215 s = s - 17232; /* 2^15 - 50000 - rounding */
1216 print_char('0' + (s / 65536L));
1217 s = 10 * (s % 65536L);
1219 } while (!(s <= delta));
1222 scaled mult_and_add_(integer n, scaled x, scaled y, scaled maxanswer)
1224 register scaled Result;
1233 else if (((x <= (maxanswer - y) / n) && (- (integer) x <= (maxanswer + y) / n)))
1243 scaled x_over_n_(scaled x, integer n)
1245 register scaled Result;
1266 tex_remainder = x % n;
1270 Result = - (integer) ((- (integer) x)/ n);
1271 tex_remainder = - (integer) ((- (integer) x)% n);
1276 tex_remainder = - (integer) tex_remainder;
1281 scaled xn_over_d_(scaled x, integer n, integer d)
1283 register scaled Result;
1285 nonnegative_integer t, u, v;
1292 /* t =(x % 32768L)* n; */
1293 t =(x & 32767L) * n;
1294 /* u =(x / 32768L)* n +(t / 32768L); */
1295 u =(x >> 15) * n + (t >> 15);
1296 /* v =(u % d)* 32768L +(t % 32768L); */
1297 v =((u % d) << 15) + (t & 32767L);
1298 if (u / d >= 32768L)
1300 /* else u = 32768L *(u / d)+(v / d); */
1301 else u =((u / d) << 15) + (v / d);
1306 tex_remainder = v % d;
1310 Result = - (integer) u;
1311 tex_remainder = - (integer)(v % d);
1317 halfword badness_(scaled t, scaled s)
1319 register halfword Result;
1328 else if (s >= 1663497L)
1334 /* safe to assume that r is positive ? */
1335 /* else Result =(r * r * r + 131072L)/ 262144L; */
1337 Result = (r * r * r + 131072L) >> 18; /* 2^17 */
1343 void print_word_(memory_word w)
1347 print_scaled(w.cint);
1349 print_scaled(round(65536L * w.gr));
1351 print_int(w.hh.v.LH);
1357 print_int(w.hh.v.RH);
1359 print_int(w.qqqq.b0);
1361 print_int(w.qqqq.b1);
1363 print_int(w.qqqq.b2);
1365 print_int(w.qqqq.b3);
1367 /* need this version only if SHORTFONTINFO defined */
1368 void zprintfword(fmemoryword w)
1372 print_scaled(w.cint);
1374 print_scaled(round(65536L * w.gr));
1376 print_int(w.hh.v.LH);
1380 print_int(w .hh.b1);
1382 print_int(w.hh.v.RH);
1384 print_int(w.qqqq.b0);
1386 print_int(w.qqqq.b1);
1388 print_int(w.qqqq.b2);
1390 print_int(w.qqqq.b3);
1394 void show_token_list_(integer p, integer q, integer l)
1397 ASCII_code match_chr;
1402 /* while (p<>null) and (tally<l) do l.6239 */
1403 while ((p != 0) && (tally < l)) {
1406 first_count = tally;
1407 trick_count = tally + 1 + error_line - half_error_line;
1409 if (trick_count < error_line)
1410 trick_count = error_line;
1413 if ((p < hi_mem_min) || (p > mem_end))
1415 print_esc("CLOBBERED.");
1419 if (info(p) >= 4095)
1420 print_cs(info(p) - 4095);
1447 print_char(c + '0');
1455 match_chr = (ASCII_code) c;
1480 if (scanner_status > 1)
1482 print_nl("Runaway ");
1483 switch (scanner_status)
1486 print_string("definition");
1490 print_string("argument");
1494 print_string("preamble");
1498 print_string("text");
1504 show_token_list(link(p), 0, error_line - 10);
1508 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1509 /* first try list of available nodes (avail != NULL) */
1510 /* then see if can go upwards (mem_end < mem_max) */
1511 /* then see if can go downwards (hi_mem_min > lo_mem_max) */
1512 /* if not, extend memory at the top and grab from there --- new */
1513 /* else fail ! paragraph 120 */
1514 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1515 halfword get_avail (void)
1517 register halfword Result;
1520 if (p != 0) /* while p<>null do */
1521 avail = link(avail);
1522 else if (mem_end < mem_max) /* mem_end + 1 < mem_max ? NO */
1531 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1532 if (hi_mem_min <= lo_mem_max) /* have we run out in middle ? */
1534 incr(hi_mem_min); /* undo the change */
1535 /* realloc_main (0, mem_top/2); */ /* extend main memory at hi end */
1536 mem = realloc_main (0, mem_top / 2); /* zzzaa = zmem = mem */
1539 /* presumably now mem_end < mem_max - but need test in case allocation fails */
1540 if (mem_end >= mem_max)
1543 overflow("main memory size", mem_max + 1 - mem_min); /* main memory size */
1544 return 0; // abort_flag set
1546 incr(mem_end); /* then grab from new area */
1547 p = mem_end; /* 1993/Dec/14 */
1549 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1551 link(p) = 0; /* link(p) = null !!! */
1560 void flush_list_(halfword p) /* paragraph 123 */
1563 if (p != 0) /* null !!! */
1573 } while (!(r == 0)); /* r != null */
1579 halfword get_node_(integer s)
1581 register halfword Result;
1589 q = p + mem[p].hh.v.LH;
1590 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1591 while ((mem[q].hh.v.RH == empty_flag)) {
1592 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1594 /* should never happen, since this field is reference count for zeroglue */
1595 } /* debugging code 93/DEC/15 */ /* eventually remove */
1596 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1597 t = mem[q + 1].hh.v.RH;
1600 mem[t + 1].hh.v.LH = mem[q + 1].hh.v.LH;
1601 mem[mem[q + 1].hh.v.LH + 1].hh.v.RH = t;
1602 q = q + mem[q].hh.v.LH;
1605 if (r > toint(p + 1))
1607 mem[p].hh.v.LH = r - p;
1612 if (mem[p + 1].hh.v.RH != p)
1614 rover = mem[p + 1].hh.v.RH;
1615 t = mem[p + 1].hh.v.LH;
1616 mem[rover + 1].hh.v.LH = t;
1617 mem[t + 1].hh.v.RH = rover;
1620 mem[p].hh.v.LH = q - p;
1621 p = mem[p + 1].hh.v.RH;
1622 } while (!(p == rover));
1623 if (s == 1073741824L) /* 2^30 - special case - merge adjacent */
1625 Result = empty_flag;
1626 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1628 show_line("Merged adjacent multi-word nodes\n", 0);
1629 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1632 /* maybe try downward epxansion first instead ? */
1633 if (lo_mem_max + 2 < hi_mem_min)
1634 /* if (lo_mem_max + 2 <= 262143L) */ /* NO! */
1635 if (lo_mem_max + 2 <= mem_bot + max_halfword) /* silly ? flush 93/Dec/16 */
1637 /* if (hi_mem_min - lo_mem_max >= 1998) */
1638 if (hi_mem_min - lo_mem_max >= (block_size + block_size - 2))
1639 /* t = lo_mem_max + 1000; */
1640 t = lo_mem_max + block_size;
1642 t = lo_mem_max + 1 +(hi_mem_min - lo_mem_max) / 2;
1643 p = mem[rover + 1].hh.v.LH;
1645 mem[p + 1].hh.v.RH = q;
1646 mem[rover + 1].hh.v.LH = q;
1647 /* if (t > 262143L) t = 262143L; */ /* NO! */
1648 if (t > mem_bot + max_halfword)
1649 t = mem_bot + max_halfword; /* silly ? flush 93/Dec/16 */
1650 mem[q + 1].hh.v.RH = rover;
1651 mem[q + 1].hh.v.LH = p;
1652 mem[q].hh.v.RH = empty_flag;
1653 mem[q].hh.v.LH = t - lo_mem_max; /* block size */
1655 mem[lo_mem_max].hh.v.RH = 0;
1656 mem[lo_mem_max].hh.v.LH = 0;
1660 /* overflow("main memory size", mem_max + 1 - mem_min); */ /* what used to happen! */
1661 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1662 /* we've run out of space in the middle for variable length blocks */
1663 /* try and add new block from below mem_bot *//* first check if space ! */
1664 if (mem_min - (block_size + 1) <= mem_start) {/* extend lower memory downwards */
1665 /* realloc_main (mem_top/2, 0); */
1666 mem = realloc_main (mem_top/2 + block_size, 0); /* zzzaa = zmem = mem */
1671 /* if (trace_flag) show_line("Extending downwards by %d\n", block_size, 0); */
1672 if (mem_min - (block_size + 1) <= mem_start) { /* check again */
1674 sprintf(log_line, "mem_min %d, mem_start %d, block_size %d\n", mem_min, mem_start, block_size);
1675 show_line(log_line, 0);
1677 overflow("main memory size", mem_max + 1 - mem_min); /* darn: allocation failed ! */
1678 return 0; // abort_flag set
1680 /* avoid function call in following ? */
1681 add_variable_space (block_size); /* now to be found in itex.c */
1682 goto lab20; /* go try get_node again */
1683 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1685 lab40: mem[r].hh.v.RH = 0;
1688 var_used = var_used + s;
1691 /* if (trace_flag) {
1692 if (r == 0) show_line("r IS ZERO in ZGETNODE!\n", 0);
1693 } */ /* debugging code 93/dec/15 */
1699 void free_node_(halfword p, halfword s)
1703 link(p) = empty_flag;
1710 var_used = var_used - s;
1714 halfword new_null_box (void)
1717 p = get_node(box_node_size);
1718 type(p) = hlist_node;
1719 subtype(p) = min_quarterword;
1723 shift_amount(p) = 0;
1725 glue_sign(p) = normal;
1726 glue_order(p) = normal;
1731 halfword new_rule (void)
1734 p = get_node(rule_node_size);
1735 type(p) = rule_node;
1737 width(p) = null_flag;
1738 depth(p) = null_flag;
1739 height(p) = null_flag;
1743 halfword new_ligature_(quarterword f, quarterword c, halfword q)
1746 p = get_node(small_node_size);
1747 type(p) = ligature_node;
1748 font(lig_char(p)) = f;
1749 character(lig_char(p)) = c;
1755 halfword new_lig_item_(quarterword c)
1758 p = get_node(small_node_size);
1764 halfword new_disc (void)
1767 p = get_node(small_node_size);
1768 type(p) = disc_node;
1769 replace_count(p) = 0;
1775 halfword new_math_(scaled w, small_number s)
1778 p = get_node(small_node_size);
1779 type(p) = math_node;
1785 halfword new_spec_(halfword p)
1788 q = get_node(glue_spec_size);
1790 glue_ref_count(q) = 0;
1791 width(q) = width(p);
1792 stretch(q) = stretch(p);
1793 shrink(q) = shrink(p);
1797 halfword new_param_glue_(small_number n)
1801 p = get_node(small_node_size);
1802 type(p) = glue_node;
1807 incr(glue_ref_count(q));
1811 halfword new_glue_(halfword q)
1814 p = get_node(small_node_size);
1815 type(p) = glue_node;
1816 subtype(p) = normal;
1819 incr(glue_ref_count(q));
1823 halfword new_skip_param_(small_number n)
1826 temp_ptr = new_spec(glue_par(n));
1827 p = new_glue(temp_ptr);
1828 glue_ref_count(temp_ptr) = 0;
1833 halfword new_kern_(scaled w)
1836 p = get_node(small_node_size);
1837 type(p) = kern_node;
1838 subtype(p) = normal;
1843 halfword new_penalty_(integer m)
1846 p = get_node(small_node_size);
1847 type(p) = penalty_node;
1855 void check_mem_(bool printlocs)
1860 for (p = mem_min; p <= lo_mem_max; p++) freearr[p] = false;
1861 for (p = hi_mem_min; p <= mem_end; p++) freearr[p] = false;
1866 if ((p > mem_end) || (p < hi_mem_min))
1868 else if (freearr[p])
1873 print_nl("AVAIL list clobbered at ");
1886 if ((p >= lo_mem_max) || (p < mem_min))
1888 else if ((rlink(p) >= lo_mem_max) || (rlink(p) < mem_min))
1890 else if (!(is_empty(p)) || (node_size(p) < 2) ||
1891 (p + node_size(p) > lo_mem_max) || (llink(rlink(p)) != p))
1896 print_nl("Double-AVAIL list clobbered at ");
1901 for (q = p; q <= p + node_size(p) - 1; q++)
1905 print_nl("Doubly free location at ");
1913 } while (!(p == rover));
1916 while (p <= lo_mem_max) {
1919 print_nl("Bad flag at ");
1922 while ((p <= lo_mem_max) && !freearr[p]) incr(p);
1923 while ((p <= lo_mem_max) && freearr[p]) incr(p);
1928 print_nl("New busy locs:");
1930 for (p = mem_min; p <= lo_mem_max; p++)
1931 if (!freearr[p] && ((p > was_lo_max) || wasfree[p]))
1937 for (p = hi_mem_min; p <= mem_end; p++)
1938 if (!freearr[p] && ((p < was_hi_min) || (p > was_mem_end) || wasfree[p]))
1945 for (p = mem_min; p <= lo_mem_max; p++) wasfree[p] = freearr[p];
1946 for (p = hi_mem_min; p <= mem_end; p++) wasfree[p] = freearr[p];
1948 was_mem_end = mem_end;
1949 was_lo_max = lo_mem_max;
1950 was_hi_min = hi_mem_min;
1956 void search_mem_(halfword p)
1960 for (q = mem_min; q <= lo_mem_max; q++)
1976 for (q = hi_mem_min; q <= mem_end; q++)
1992 for (q = active_base; q <= box_base + 255; q++)
2001 for (q = 0; q <= save_ptr - 1; q++)
2003 if (equiv_field(save_stack[q]) == p)
2011 for (q = 0; q <= hyphen_prime; q++)
2012 if (hyph_list[q] == p)
2021 void short_display_(integer p)
2024 /* while(p > mem_min){ */
2025 while (p != 0) { /* want p != null here bkph 93/Dec/15 !!! NOTE: still not fixed in 3.14159 ! */
2026 if (is_char_node(p))
2030 if (font(p) != font_in_short_display)
2032 if ((font(p) > font_max))
2037 print(hash[(hash_size + hash_extra + 524) + mem[p].hh.b0].v.RH);
2040 font_in_short_display = font(p);
2042 print(character(p));
2045 else switch (mem[p].hh.b0)
2060 if (glue_ptr(p) != 0)
2067 short_display(lig_ptr(p));
2070 short_display(pre_break(p));
2071 short_display(post_break(p));
2072 n = replace_count(p);
2074 if (link(p) != 0) /* if link(p)<>null then */
2086 void print_font_and_char_ (integer p)
2089 print_esc("CLOBBERED.");
2091 if ((font(p) > font_max))
2096 print(hash[(hash_size + hash_extra + 524) + mem[p].hh.b0].v.RH);
2099 print(character(p));
2103 void print_mark_ (integer p)
2106 if ((p < hi_mem_min)||(p > mem_end))
2107 print_esc("CLOBBERED.");
2109 show_token_list(link(p), 0, max_print_line - 10);
2113 void print_rule_dimen_ (scaled d)
2115 if ((d == -1073741824L)) /* - 2^30 */
2121 void print_glue_(scaled d, integer order, char * s)
2124 if ((order < normal) || (order > filll))
2125 print_string("foul");
2128 print_string("fil");
2133 } else if (*s != '\0')
2137 void print_spec_(integer p, char * s)
2139 if ((p < mem_min)||(p >= lo_mem_max))
2142 print_scaled(mem[p + 1].cint);
2147 if (stretch(p) != 0)
2149 print_string("plus");
2150 print_glue(stretch(p), stretch_order(p), s);
2155 print_string("minus");
2156 print_glue(shrink(p), shrink_order(p), s);
2161 void print_fam_and_char_(halfword p)
2164 print_int(mem[p].hh.b0);
2166 print(mem[p].hh.b1);
2169 void print_delimiter_(halfword p)
2172 a = mem[p].qqqq.b0 * 256 + mem[p].qqqq.b1;
2173 a = a * 4096 + mem[p].qqqq.b2 * 256 + mem[p].qqqq.b3;
2180 void print_subsidiary_data_(halfword p, ASCII_code c)
2182 if ((pool_ptr - str_start[str_ptr]) >= depth_threshold)
2184 if (math_type(p) != 0)
2185 print_string(" []");
2191 switch (mem[p].hh.v.RH)
2195 print_current_string();
2196 print_fam_and_char(p);
2205 print_current_string();
2218 void print_style_(integer c)
2223 print_esc("displaystyle");
2226 print_esc("textstyle");
2229 print_esc("scriptstyle");
2232 print_esc("scriptscriptstyle");
2235 print_string("Unknown style!");
2240 void print_skip_param_(integer n)
2244 case line_skip_code:
2245 print_esc("lineskip");
2247 case baseline_skip_code:
2248 print_esc("baselineskip");
2251 print_esc("parskip");
2253 case above_display_skip_code:
2254 print_esc("abovedisplayskip");
2256 case below_display_skip_code:
2257 print_esc("belowdisplayskip");
2259 case above_display_short_skip_code:
2260 print_esc("abovedisplayshortskip");
2262 case below_display_short_skip_code:
2263 print_esc("belowdisplayshortskip");
2265 case left_skip_code:
2266 print_esc("leftskip");
2268 case right_skip_code:
2269 print_esc("rightskip");
2272 print_esc("topskip");
2274 case split_top_skip_code:
2275 print_esc("splittopskip");
2278 print_esc("tabskip");
2280 case space_skip_code:
2281 print_esc("spaceskip");
2283 case xspace_skip_code:
2284 print_esc("xspaceskip");
2286 case par_fill_skip_code:
2287 print_esc("parfillskip");
2289 case thin_mu_skip_code:
2290 print_esc("thinmuskip");
2292 case med_mu_skip_code:
2293 print_esc("medmuskip");
2295 case thick_mu_skip_code:
2296 print_esc("thickmuskip");
2299 print_string("[unknown glue parameter!]");
2304 void show_node_list_(integer p)
2309 if (cur_length > depth_threshold)
2311 /* if (p > 0) */ /* was p>null !!! line 3662 in tex.web */
2312 if (p != 0) /* fixed 94/Mar/23 BUG FIX NOTE: still not fixed in 3.14159 ! */
2313 print_string(" []");
2317 /* while(p > mem_min){ */ /* was p>mem_min !!! line 3667 in tex.web */
2318 while (p != 0) { /* want p != null - bkph 93/Dec/15 NOTE: still not fixed in 3.14159 ! */
2320 print_current_string();
2323 print_string("Bad link, display aborted.");
2327 if (n > breadth_max)
2329 print_string("etc.");
2332 if ((p >= hi_mem_min))
2333 print_font_and_char(p);
2334 else switch (mem[p].hh.b0)
2340 if (mem[p].hh.b0 == 0)
2342 else if (mem[p].hh.b0 == 1)
2344 else print_esc("unset");
2345 print_string("box(");
2346 print_scaled(mem[p + 3].cint);
2348 print_scaled(mem[p + 2].cint);
2349 print_string(", shifted ");
2350 print_scaled(mem[p + 1].cint);
2351 if (mem[p].hh.b0 == 13)
2353 if (mem[p].hh.b1 != 0)
2356 print_int(mem[p].hh.b1 + 1);
2357 print_string(" columns)");
2359 if (mem[p + 6].cint != 0)
2361 print_string(", stretch ");
2362 print_glue(mem[p + 6].cint, mem[p + 5].hh.b1, "");
2364 if (mem[p + 4].cint != 0)
2366 print_string(", shrink ");
2367 print_glue(mem[p + 4].cint, mem[p + 5].hh.b0, "");
2371 if ((g != 0.0)&&(mem[p + 5].hh.b0 != 0))
2373 print_string(", glue set ");
2374 if (mem[p + 5].hh.b0 == 2)
2376 if (fabs(g)> 20000.0)
2381 print_string("< -");
2382 print_glue(20000 * 65536L, mem[p + 5].hh.b1, "");
2383 } else print_glue(round(65536L * g), mem[p + 5].hh.b1, "");
2385 if (mem[p + 4].cint != 0)
2387 print_string("shifted");
2388 print_scaled(mem[p + 4].cint);
2393 str_pool[pool_ptr]= 46;
2396 show_node_list(mem[p + 5].hh.v.RH);
2404 print_rule_dimen(mem[p + 3].cint);
2406 print_rule_dimen(mem[p + 2].cint);
2408 print_rule_dimen(mem[p + 1].cint);
2413 print_esc("insert");
2414 print_int(mem[p].hh.b1);
2415 print_string(", natural size ");
2416 print_scaled(mem[p + 3].cint);
2417 print_string("; split(");
2418 print_spec(mem[p + 4].hh.v.RH, "");
2420 print_scaled(mem[p + 2].cint);
2421 print_string("); float cost ");
2422 print_int(mem[p + 1].cint);
2425 str_pool[pool_ptr]= 46;
2428 show_node_list(mem[p + 4].hh.v.LH);
2434 switch (mem[p].hh.b1)
2438 print_write_whatsit(1279, p); /* debug # (-1 to exit): */
2440 print_file_name(mem[p + 1].hh.v.RH, mem[p + 2].hh.v.LH, mem[p + 2].hh.v.RH);
2445 print_write_whatsit(591, p); /* write */
2446 print_mark(mem[p + 1].hh.v.RH);
2450 print_write_whatsit(1280, p); /* closeout */
2454 print_esc("special");
2455 print_mark(mem[p + 1].hh.v.RH);
2460 print_esc("setlanguage");
2461 print_int(mem[p + 1].hh.v.RH);
2462 print_string(" (hyphenmin");
2463 print_int(mem[p + 1].hh.b0);
2465 print_int(mem[p + 1].hh.b1);
2470 print_string("whatsit");
2475 if (mem[p].hh.b1 >= 100)
2478 if (mem[p].hh.b1 == 101)
2480 else if (mem[p].hh.b1 == 102)
2482 print_string("leaders ");
2483 print_spec(mem[p + 1].hh.v.LH, "");
2486 str_pool[pool_ptr]= 46;
2489 show_node_list(mem[p + 1].hh.v.RH);
2494 if (mem[p].hh.b1 != 0)
2497 if (mem[p].hh.b1 < 98)
2498 print_skip_param(mem[p].hh.b1 - 1);
2499 else if (mem[p].hh.b1 == 98)
2500 print_esc("nonscript");
2501 else print_esc("mskip");
2504 if (mem[p].hh.b1 != 98)
2507 if (mem[p].hh.b1 < 98)
2508 print_spec(mem[p + 1].hh.v.LH, "");
2510 print_spec(mem[p + 1].hh.v.LH, "mu");
2515 if (mem[p].hh.b1 != 99)
2518 if (mem[p].hh.b1 != 0)
2520 print_scaled(mem[p + 1].cint);
2521 if (mem[p].hh.b1 == 2)
2522 print_string(" (for accent)");
2525 print_scaled(mem[p + 1].cint);
2532 if (mem[p].hh.b1 == 0)
2534 else print_string("off");
2535 if (mem[p + 1].cint != 0)
2537 print_string(", surrounded ");
2538 print_scaled(mem[p + 1].cint);
2544 print_font_and_char(p + 1);
2545 print_string("(ligature ");
2546 if (mem[p].hh.b1 > 1)
2548 font_in_short_display = mem[p + 1].hh.b0;
2549 short_display(mem[p + 1].hh.v.RH);
2550 if (odd(mem[p].hh.b1))
2557 print_esc("penalty ");
2558 print_int(mem[p + 1].cint);
2563 print_esc("discretionary");
2564 if (mem[p].hh.b1 > 0)
2566 print_string(" replacing ");
2567 print_int(mem[p].hh.b1);
2571 str_pool[pool_ptr]= 46;
2574 show_node_list(mem[p + 1].hh.v.LH);
2578 str_pool[pool_ptr]= 124;
2581 show_node_list(mem[p + 1].hh.v.RH);
2588 print_mark(mem[p + 1].cint);
2593 print_esc("vadjust");
2596 str_pool[pool_ptr]= 46;
2599 show_node_list(mem[p + 1].cint);
2605 print_style(mem[p].hh.b1);
2609 print_esc("mathchoice");
2611 str_pool[pool_ptr]= 68;
2614 show_node_list(mem[p + 1].hh.v.LH);
2617 str_pool[pool_ptr]= 84;
2620 show_node_list(mem[p + 1].hh.v.RH);
2623 str_pool[pool_ptr]= 83;
2626 show_node_list(mem[p + 2].hh.v.LH);
2629 str_pool[pool_ptr]= 115;
2632 show_node_list(mem[p + 2].hh.v.RH);
2652 switch (mem[p].hh.b0)
2655 print_esc("mathord");
2658 print_esc("mathop");
2661 print_esc("mathbin");
2664 print_esc("mathrel");
2667 print_esc("mathopen");
2670 print_esc("mathclose");
2673 print_esc("mathpunct");
2676 print_esc("mathinner");
2679 print_esc("overline");
2682 print_esc("underline");
2685 print_esc("vcenter");
2689 print_esc("radical");
2690 print_delimiter(p + 4);
2695 print_esc("accent");
2696 print_fam_and_char(p + 4);
2702 print_delimiter(p + 1);
2708 print_delimiter(p + 1);
2712 if (mem[p].hh.b1 != 0)
2713 if (mem[p].hh.b1 == 1)
2714 print_esc("limits");
2715 else print_esc("nolimits");
2716 if (mem[p].hh.b0 < 30)
2717 print_subsidiary_data(p + 1, 46);
2718 print_subsidiary_data(p + 2, 94);
2719 print_subsidiary_data(p + 3, 95);
2724 print_esc("fraction");
2725 if (mem[p + 1].cint == 1073741824L) /* 2^30 */
2726 print_string("= default");
2727 else print_scaled(mem[p + 1].cint);
2728 if ((mem[p + 4].qqqq.b0 != 0) || (mem[p + 4].qqqq.b1 != 0) ||
2729 (mem[p + 4].qqqq.b2 != 0) || (mem[p + 4].qqqq.b3 != 0))
2731 print_string(", left");
2732 print_delimiter(p + 4);
2734 if ((mem[p + 5].qqqq.b0 != 0) || (mem[p + 5].qqqq.b1 != 0) ||
2735 (mem[p + 5].qqqq.b2 != 0)||(mem[p + 5].qqqq.b3 != 0))
2737 print_string(", right");
2738 print_delimiter(p + 5);
2740 print_subsidiary_data(p + 2, 92);
2741 print_subsidiary_data(p + 3, 47);
2745 print_string("Unknown node type!");
2751 /* NOTE: 262143L should be empty_flag */