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 INLINE void free_avail_(halfword p)
40 INLINE void dvi_out_(ASCII_code op)
42 dvi_buf[dvi_ptr] = op;
44 if (dvi_ptr == dvi_limit)
47 INLINE void succumb (void)
49 if (interaction == error_stop_mode)
50 interaction = scroll_mode;
61 INLINE void flush_string (void)
64 pool_ptr = str_start[str_ptr];
66 INLINE void append_char (ASCII_code c)
68 str_pool[pool_ptr] = c;
71 INLINE void print_err (const char * s)
73 if (interaction == error_stop_mode);
77 INLINE void tex_help (unsigned int n, ...)
84 va_start(help_arg, n);
85 for (i = n - 1; i > n - 1; --i)
86 help_line[i] = va_arg(help_arg, char *);
89 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
91 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
101 (void) putc ('\n', log_file);
105 (void) putc ('\n', log_file);
117 (void) putc ('\n', write_file[selector]);
122 void print_char_ (ASCII_code s)
124 if (s == new_line_char)
125 if (selector < pseudo)
134 (void) show_char(Xchr(s));
136 (void) putc(Xchr(s), log_file);
139 if (term_offset == max_print_line)
145 if (file_offset == max_print_line)
147 (void) putc ('\n', log_file);
153 (void) putc(Xchr(s), log_file);
155 if (file_offset == max_print_line)
159 (void) show_char(Xchr(s));
161 if (term_offset == max_print_line)
167 if (tally < trick_count)
168 trick_buf[tally % error_line] = s;
171 #ifdef ALLOCATESTRING
172 if (pool_ptr + 1 > current_pool_size)
174 str_pool = realloc_str_pool (increment_pool_size);
177 if (pool_ptr < current_pool_size)
179 str_pool[pool_ptr]= s;
183 if (pool_ptr < pool_size)
185 str_pool[pool_ptr]= s;
191 (void) putc(Xchr(s), write_file[selector]);
197 /* This could be made more efficient using fputs ? ... bkph */
198 void print_ (integer s)
208 if (selector > pseudo)
214 if ((s == new_line_char))
223 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
224 /* translate ansi to dos 850 */
225 if (!show_in_hex && s < 256 && s >= 32)
227 if (show_in_dos && s > 127)
229 if (wintodos[s-128] > 0)
230 print_char (wintodos[s - 128]);
234 while (j < str_start[s + 1])
236 print_char(str_pool[j]);
242 print_char(s); /* don't translate to hex */
245 { /* not just a character */
247 while (j < str_start[s + 1])
249 print_char(str_pool[j]);
253 new_line_char = nl; /* restore eol */
256 /* we get here with s > 256 - i.e. not a single character */
258 while (j < str_start[s + 1])
260 print_char(str_pool[j]);
264 /* string version print. */
265 void print_string_ (unsigned char *s)
271 // print string number s from string pool by calling print_
272 void slow_print_ (integer s)
276 if ((s >= str_ptr) || (s < 256))
281 while (j < str_start[s + 1])
283 /* if (str_pool[j]>= 128) print(str_pool[j] - 128); */ // debugging only
284 /* if (str_pool[j]== 0) print(36); */ // debugging only
291 // print newline followed by string number s (unless at start of line)
292 void print_nl_ (const char * s)
294 if (((term_offset > 0) && (odd(selector))) ||
295 ((file_offset > 0) && (selector >= log_only)))
301 // print string number s preceded by escape character
302 void print_esc_ (const char * s)
315 void print_the_digs_ (eight_bits k)
321 print_char('0' + dig[k]);
323 print_char('A' + dig[k]);
327 void print_int_ (integer n)
354 dig[k] = (char) (n % 10);
361 void print_cs_ (integer p)
364 if (p >= single_base)
368 print_esc("endcsname");
373 print_esc("");print(p - 257);
374 /* if cat_code(p - single_base) = letter then ... p.262 */
375 if (eqtb[(hash_size + 1883) + p - 257].hh.v.RH == letter)
379 print_esc("IMPOSSIBLE.");
381 else if (p >= (hash_size + 781)) /* undefined_control_sequence */
382 print_esc("IMPOSSIBLE.");
383 else if ((hash[p].v.RH >= str_ptr))
384 print_esc("NONEXISTENT.");
387 print_esc(""); print(hash[p].v.RH);
392 void sprint_cs_(halfword p)
394 if (p < hash_base) /* if p < hash_base then ... p.263 */
395 if (p < single_base) /* if p < single_base then ... p.263 */
396 print(p - active_base); /* print (p - active_base); */
397 else if (p < null_cs) /* else if p < null_cs then ... */
399 print_esc(""); print(p - single_base);
404 print_esc("endcsname");
408 print_esc(""); print(hash[p].v.RH);
412 /* ! I can't find file ` c:/foo/ accents .tex '. */
413 void print_file_name_(integer n, integer a, integer e)
415 /* sprintf(log_line, "\na %d n %d e %d\n", a, n, e); */
416 /* show_line(log_line, 0); */
417 // print_char('!'); // debugging only
419 // print_char('!'); // debugging only
421 // print_char('!'); // debugging only
423 // print_char('!'); // debugging only
426 void print_size_ (integer s)
429 print_esc("textfont");
431 print_esc("scriptfont");
433 print_esc("scriptscriptfont");
436 void print_write_whatsit_(str_number s, halfword p)
438 print_esc(""); print(s);
439 if (mem[p + 1].hh.v.LH < 16)
440 print_int(mem[p + 1].hh.v.LH);
441 else if (mem[p + 1].hh.v.LH == 16)
443 else print_char('-');
446 // called from itex.c and tex0.c only NASTY NASTY!
447 // now uses uses non-local goto (longjmp) 1999/Nov/7
450 close_files_and_terminate();
459 show_line("EXITING at JUMPOUT\n", 0);
461 if ((history != 0) && (history != 1))
470 // deal with error by asking for user response 0-9, D, E, H, I, X, Q, R, S
471 // NOTE: this may JUMPOUT either via X, or because of too many errors
475 integer s1, s2, s3, s4;
477 if (history < error_message_issued)
478 history = error_message_issued;
483 if (interaction == error_stop_mode)
487 clear_for_error_prompt();
490 term_input("? ", help_ptr);
494 c = buffer[first]; // analyze first letter typed
495 if (c >= 'a') // uppercase letter first
496 c = (unsigned char) (c + 'A' - 'a');
509 if (deletions_allowed)
515 align_state = 1000000L;
516 OK_to_interrupt = false;
518 if ((last > first + 1) && (buffer[first + 1] >= '0') && (buffer[first + 1] <= '9'))
519 c = (unsigned char) (c * 10 + buffer[first + 1] - '0' * 11);
521 c = (unsigned char) (c - 48);
532 OK_to_interrupt = true;
533 help2("I have just deleted some text, as you asked.",
534 "You can now delete more, or insert, or whatever.");
536 goto lab22; /* loop again */
543 goto lab22; /* loop again */
550 edit_name_start = str_start[input_stack[base_ptr].name_field];
551 edit_name_length = length(input_stack[base_ptr].name_field);
561 use_err_help = false;
566 help2("Sorry, I don't know how to help in this situation.",
567 "Maybe you should try asking a human?");
570 print_string(help_line[help_ptr]);
572 } while (!(help_ptr == 0));
575 help4("Sorry, I already gave what help I could...",
576 "Maybe you should try asking a human?",
577 "An error might have occurred before I noticed any problems.",
578 "``If all else fails, read the instructions.''");
579 goto lab22; /* loop again */
584 begin_file_reading();
586 if (last > first + 1)
588 cur_input.loc_field = first + 1;
594 print_string("insert>");
595 term_input("insert>", 0);
597 cur_input.loc_field = first;
600 cur_input.limit_field = last - 1;
609 interaction = 0 + c - 81; /* Q = 0, R = 1, S = 2, T = 3 */
610 print_string("OK, entering ");
614 print_esc("batchmode");
618 print_esc("nonstopmode");
621 print_esc("scrollmode");
640 } /* end of switch analysing response character */
642 print_string("Type <return> to proceed, S to scroll future error messages,");
643 print_nl("R to run without stopping, Q to run quietly,");
644 print_nl("I to insert something, ");
647 print_string("E to edit your file,");
648 if (deletions_allowed)
649 print_nl("1 or ... or 9 to ignore the next 1 to 9 tokens of input,");
651 print_nl("H for help, X to quit.");
653 } /* end of while(true) loop */
656 if (error_count == 100)
658 print_nl("(That makes 100 errors; please try again.)");
663 if (interaction > batch_mode)
671 else while(help_ptr > 0)
674 print_nl(help_line[help_ptr]);
679 if (interaction > batch_mode)
685 void fatal_error_(char * s)
687 normalize_selector();
688 print_err("Emergency stop");
693 void overflow_(char * s, integer n)
695 normalize_selector();
696 print_err("TeX capacity exceeded, sorry[");
701 help2("If you really absolutely need more capacity,",
702 "you can ask a wizard to enlarge me.");
706 if (!strcmp(s, "pattern memory") && n == trie_size)
708 sprintf(log_line, "\n (Maybe use -h=... on command line in ini-TeX)\n");
709 show_line(log_line, 0);
710 } else if (!strcmp(s, "exception dictionary") && n == hyphen_prime)
712 sprintf(log_line, "\n (Maybe use -e=... on command line in ini-TeX)\n");
713 show_line(log_line, 0);
719 void confusion_(char * s)
721 normalize_selector();
723 if (history < error_message_issued)
725 print_err("This can't happen (");
728 help1("I'm broken. Please show this to someone who can fix can fix");
732 print_err("I can't go on meeting you like this");
733 help2("One of your faux pas seems to have wounded me deeply...",
734 "in fact, I'm barely conscious. Please fix it and try again.");
739 bool init_terminal (void)
741 register bool Result;
747 cur_input.loc_field = first;
748 while((cur_input.loc_field < last) && (buffer[cur_input.loc_field]== ' '))
749 incr(cur_input.loc_field); // step over initial white space
750 if (cur_input.loc_field < last)
753 return Result; // there is an input file name
757 // failed to find input file name
760 flag = ConsoleInput("**", "Please type a file name or a control sequence\r\n(or ^z to exit)", (char *) &buffer[first]);
761 last = first + strlen((char *) &buffer[first]); /* -1 ? */
762 // may need to be more elaborate see input_line in texmf.c
764 (void) fputs("**", stdout);
766 flag = input_ln(stdin, true);
771 show_line("! End of file on the terminal... why?\n", 1);
776 cur_input.loc_field = first;
777 while ((cur_input.loc_field < last) && (buffer[cur_input.loc_field]== ' '))
778 incr(cur_input.loc_field); // step over intial white space
779 if (cur_input.loc_field < last)
782 return Result; // there is an input file name
785 sprintf(log_line, "%s\n", "Please type the name of your input file.");
786 show_line(log_line, 1);
790 // Make string from str_start[str_ptr] to pool_ptr
791 str_number make_string (void)
793 register str_number Result;
794 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
795 #ifdef ALLOCATESTRING
796 if (str_ptr == current_max_strings)
797 str_start = realloc_str_start(increment_max_strings);
799 if (str_ptr == current_max_strings)
801 overflow("number of strings", current_max_strings - init_str_ptr); /* 97/Mar/9 */
802 return 0; // abort_flag set
805 if (str_ptr == max_strings)
807 overflow("number of strings", max_strings - init_str_ptr);
808 return 0; // abort_flag set
812 str_start[str_ptr] = pool_ptr;
813 Result = str_ptr - 1;
817 bool str_eq_buf_ (str_number s, integer k)
819 register bool Result;
823 while (j < str_start[s + 1])
825 if (str_pool[j]!= buffer[k])
839 bool str_eq_str_ (str_number s, str_number t)
841 register bool Result;
845 if (length(s) != length(t))
849 while (j < str_start[s + 1])
851 if (str_pool[j] != str_pool[k])
862 void print_two_(integer n)
865 print_char('0' + (n / 10));
866 print_char('0' + (n % 10));
869 void print_hex_(integer n)
875 dig[k] = (unsigned char) (n % 16);
882 void print_roman_int_(integer n)
885 nonnegative_integer u, v;
886 j = str_start[260]; /* m2d5c2l5x2v5i */
890 print_char(str_pool[j]);
896 u = v / (str_pool[k - 1] - '0');
897 if (str_pool[k - 1] == 50)
900 u = u / (str_pool[k - 1] - '0');
904 print_char(str_pool[k]);
910 v = v / (str_pool[j - 1]- '0');
915 void print_current_string (void)
918 j = str_start[str_ptr];
921 print_char(str_pool[j]);
926 int stringlength (int str_ptr)
929 nstart = str_start[str_ptr];
930 nnext = str_start[str_ptr + 1];
931 return (nnext - nstart) + 2;
934 char * add_string (char *s, char * str_string)
937 n = strlen(str_string);
938 memcpy(s, &str_string, n);
947 // make one long \r\n separated string out of help lines
948 // str_pool is packed_ASCII_code *
950 char * make_up_help_string (int nhelplines)
952 char * helpstring, *s;
955 // get length of help for this specific message
956 for (k = nhelplines - 1; k >= 0; k--) {
957 //nlen += stringlength(help_line[k]);
958 nlen += strlen(help_line[k]);
960 nlen += 2; // for blank line separator: "\r\n"
962 nlen += stringlength(265);
963 nlen += stringlength(266);
964 nlen += stringlength(267);
966 nlen += stringlength(268);
967 if (deletions_allowed)
968 nlen += stringlength(269);
969 nlen += stringlength(270);
971 helpstring = (char *) malloc(nlen + 1); // +1 = '\0'
973 for (k = nhelplines-1; k >= 0; k--) {
974 s = add_string(s, help_line[k]);
979 s = add_string(s, "Type <return> to proceed, S to scroll future error messages,");
980 s = add_string(s, "R to run without stopping, Q to run quietly,");
981 s = add_string(s, "I to insert something, ");
983 s = add_string(s, "E to edit your file, ");
984 if (deletions_allowed)
985 s = add_string(s, "1 or ... or 9 to ignore the next 1 to 9 tokens of input,");
986 s = add_string(s, "H for help, X to quit.");
991 char * make_up_query_string (int promptstr)
994 int nstart, nnext, n;
996 nstart = str_start[ promptstr];
997 nnext = str_start[ promptstr + 1];
999 querystr = (char *) malloc(n + 1);
1001 memcpy(s, &str_pool[nstart], n);
1007 // abort_flag set if input_line / ConsoleInput returns non-zero
1008 // should set interrupt instead ???
1009 // called from tex0.c, tex2.c, tex3.c
1011 // void term_input(void)
1012 void term_input (char * term_str, int term_help_lines)
1016 char * helpstring = NULL;
1017 char * querystring = NULL;
1018 // if (nhelplines != 0) {
1019 // helpstring = make_up_help_string (nhelplines);
1020 // printf(helpstring);
1021 // free(helpstring);
1023 show_line("\n", 0); // force it to show what may be buffered up ???
1026 if (term_str != NULL) querystring = term_str;
1027 if (term_help_lines != NULL) helpstring = make_up_help_string(term_help_lines);
1028 if (helpstring == NULL && querystring != NULL)
1030 if (strcmp(querystring, ": ") == 0)
1031 helpstring = xstrdup("Please type another file name (or ^z to exit):");
1032 else if (strcmp(querystring, "=>") == 0) // from firm_up_the_line
1033 helpstring = xstrdup("Please type <enter> to accept this line\r\nor type a replacement line");
1034 else if (strcmp(querystring, "insert>") == 0) // from error() after "I"
1035 helpstring = xstrdup("Please type something to insert here");
1036 else if (strcmp(querystring, "") == 0) // from read_toks
1037 helpstring = xstrdup("Please type a control sequence");
1038 else if (strcmp(querystring, "= ") == 0) // from read_toks
1039 helpstring = xstrdup("Please type a token");
1040 else if (strcmp(querystring, "*") == 0) // get_next
1041 helpstring = xstrdup("Please type a control sequence\r\n(or ^z to exit)");
1043 flag = ConsoleInput(querystring, helpstring, (char *) &buffer[first]); // ???
1044 // flag == 0 means trouble --- EOF on terminal
1045 if (querystring != NULL) free(querystring);
1046 if (helpstring != NULL) free(helpstring);
1047 helpstring = querystring = NULL;
1049 last = first + strlen((char *) &buffer[first]); /* -1 ? */
1050 // flag = (last > first);
1051 // may need to be more elaborate see input_line in texmf.c ???
1052 // sprintf(log_line, "first %d last %d flag %d - %s",
1053 // first, last, flag, (char *) &buffer[first]);
1054 // winerror(log_line);
1057 flag = input_ln(stdin, true);
1061 fatal_error("End of file on the terminal!");
1062 return; // abort_flag set
1066 // echo what was typed into Console buffer also
1068 for (k = first; k <= last - 1; k++)
1072 decr(selector); // shut off echo
1074 for (k = first; k <= last - 1; k++)
1077 incr(selector); // reset selector again
1081 void int_error_ (integer n)
1089 void normalize_selector (void)
1092 selector = term_and_log;
1094 selector = term_only;
1099 if (interaction == batch_mode)
1103 void pause_for_instructions (void)
1105 if (OK_to_interrupt)
1107 interaction = error_stop_mode;
1108 if ((selector == log_only) || (selector == no_print))
1110 print_err("Interruption");
1112 "Try to insert some instructions for me (e.g.,`I\\showlists'),",
1113 "unless you just want to quit by typing `X'.");
1114 deletions_allowed = false;
1116 deletions_allowed = true;
1121 integer half_(integer x)
1123 register integer Result;
1125 Result =(x + 1) / 2;
1131 scaled round_decimals_(small_number k)
1133 register scaled Result;
1138 a = (a + dig[k] * 131072L) / 10; /* 2^17 */
1140 Result =(a + 1) / 2;
1144 /* This has some minor speedup changes - no real advantage probably ... */
1145 void print_scaled_(scaled s)
1154 print_int(s / 65536L);
1156 s = 10 * (s % 65536L) + 5;
1160 s = s - 17232; /* 2^15 - 50000 - rounding */
1161 print_char('0' + (s / 65536L));
1162 s = 10 * (s % 65536L);
1164 } while (!(s <= delta));
1167 scaled mult_and_add_(integer n, scaled x, scaled y, scaled maxanswer)
1169 register scaled Result;
1178 else if (((x <= (maxanswer - y) / n) && (- (integer) x <= (maxanswer + y) / n)))
1188 scaled x_over_n_(scaled x, integer n)
1190 register scaled Result;
1211 tex_remainder = x % n;
1215 Result = - (integer) ((- (integer) x)/ n);
1216 tex_remainder = - (integer) ((- (integer) x)% n);
1221 tex_remainder = - (integer) tex_remainder;
1226 scaled xn_over_d_(scaled x, integer n, integer d)
1228 register scaled Result;
1230 nonnegative_integer t, u, v;
1237 /* t =(x % 32768L)* n; */
1238 t =(x & 32767L) * n;
1239 /* u =(x / 32768L)* n +(t / 32768L); */
1240 u =(x >> 15) * n + (t >> 15);
1241 /* v =(u % d)* 32768L +(t % 32768L); */
1242 v =((u % d) << 15) + (t & 32767L);
1243 if (u / d >= 32768L)
1245 /* else u = 32768L *(u / d)+(v / d); */
1246 else u =((u / d) << 15) + (v / d);
1251 tex_remainder = v % d;
1255 Result = - (integer) u;
1256 tex_remainder = - (integer)(v % d);
1262 halfword badness_(scaled t, scaled s)
1264 register halfword Result;
1273 else if (s >= 1663497L)
1279 /* safe to assume that r is positive ? */
1280 /* else Result =(r * r * r + 131072L)/ 262144L; */
1282 Result = (r * r * r + 131072L) >> 18; /* 2^17 */
1288 void print_word_(memory_word w)
1292 print_scaled(w.cint);
1294 print_scaled(round(65536L * w.gr));
1296 print_int(w.hh.v.LH);
1302 print_int(w.hh.v.RH);
1304 print_int(w.qqqq.b0);
1306 print_int(w.qqqq.b1);
1308 print_int(w.qqqq.b2);
1310 print_int(w.qqqq.b3);
1312 /* need this version only if SHORTFONTINFO defined */
1313 void zprintfword(fmemoryword w)
1317 print_scaled(w.cint);
1319 print_scaled(round(65536L * w.gr));
1321 print_int(w.hh.v.LH);
1325 print_int(w .hh.b1);
1327 print_int(w.hh.v.RH);
1329 print_int(w.qqqq.b0);
1331 print_int(w.qqqq.b1);
1333 print_int(w.qqqq.b2);
1335 print_int(w.qqqq.b3);
1339 void show_token_list_(integer p, integer q, integer l)
1342 ASCII_code match_chr;
1347 /* while (p<>null) and (tally<l) do l.6239 */
1348 while ((p != 0) && (tally < l)) {
1351 first_count = tally;
1352 trick_count = tally + 1 + error_line - half_error_line;
1354 if (trick_count < error_line)
1355 trick_count = error_line;
1358 if ((p < hi_mem_min) || (p > mem_end))
1360 print_esc("CLOBBERED.");
1364 if (info(p) >= 4095)
1365 print_cs(info(p) - 4095);
1392 print_char(c + '0');
1400 match_chr = (ASCII_code) c;
1425 if (scanner_status > 1)
1427 print_nl("Runaway ");
1428 switch (scanner_status)
1431 print_string("definition");
1435 print_string("argument");
1439 print_string("preamble");
1443 print_string("text");
1449 show_token_list(link(p), 0, error_line - 10);
1453 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1454 /* first try list of available nodes (avail != NULL) */
1455 /* then see if can go upwards (mem_end < mem_max) */
1456 /* then see if can go downwards (hi_mem_min > lo_mem_max) */
1457 /* if not, extend memory at the top and grab from there --- new */
1458 /* else fail ! paragraph 120 */
1459 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1460 halfword get_avail (void)
1462 register halfword Result;
1465 if (p != 0) /* while p<>null do */
1466 avail = link(avail);
1467 else if (mem_end < mem_max) /* mem_end + 1 < mem_max ? NO */
1476 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1477 if (hi_mem_min <= lo_mem_max) /* have we run out in middle ? */
1479 incr(hi_mem_min); /* undo the change */
1480 /* realloc_main (0, mem_top/2); */ /* extend main memory at hi end */
1481 mem = realloc_main (0, mem_top / 2); /* zzzaa = zmem = mem */
1484 /* presumably now mem_end < mem_max - but need test in case allocation fails */
1485 if (mem_end >= mem_max)
1488 overflow("main memory size", mem_max + 1 - mem_min); /* main memory size */
1489 return 0; // abort_flag set
1491 incr(mem_end); /* then grab from new area */
1492 p = mem_end; /* 1993/Dec/14 */
1494 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1496 link(p) = 0; /* link(p) = null !!! */
1505 void flush_list_(halfword p) /* paragraph 123 */
1508 if (p != 0) /* null !!! */
1518 } while (!(r == 0)); /* r != null */
1524 halfword get_node_(integer s)
1526 register halfword Result;
1534 q = p + mem[p].hh.v.LH;
1535 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1536 while ((mem[q].hh.v.RH == empty_flag)) {
1537 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1539 /* should never happen, since this field is reference count for zeroglue */
1540 } /* debugging code 93/DEC/15 */ /* eventually remove */
1541 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1542 t = mem[q + 1].hh.v.RH;
1545 mem[t + 1].hh.v.LH = mem[q + 1].hh.v.LH;
1546 mem[mem[q + 1].hh.v.LH + 1].hh.v.RH = t;
1547 q = q + mem[q].hh.v.LH;
1550 if (r > toint(p + 1))
1552 mem[p].hh.v.LH = r - p;
1557 if (mem[p + 1].hh.v.RH != p)
1559 rover = mem[p + 1].hh.v.RH;
1560 t = mem[p + 1].hh.v.LH;
1561 mem[rover + 1].hh.v.LH = t;
1562 mem[t + 1].hh.v.RH = rover;
1565 mem[p].hh.v.LH = q - p;
1566 p = mem[p + 1].hh.v.RH;
1567 } while (!(p == rover));
1568 if (s == 1073741824L) /* 2^30 - special case - merge adjacent */
1570 Result = empty_flag;
1571 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1573 show_line("Merged adjacent multi-word nodes\n", 0);
1574 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1577 /* maybe try downward epxansion first instead ? */
1578 if (lo_mem_max + 2 < hi_mem_min)
1579 /* if (lo_mem_max + 2 <= 262143L) */ /* NO! */
1580 if (lo_mem_max + 2 <= mem_bot + max_halfword) /* silly ? flush 93/Dec/16 */
1582 /* if (hi_mem_min - lo_mem_max >= 1998) */
1583 if (hi_mem_min - lo_mem_max >= (block_size + block_size - 2))
1584 /* t = lo_mem_max + 1000; */
1585 t = lo_mem_max + block_size;
1587 t = lo_mem_max + 1 +(hi_mem_min - lo_mem_max) / 2;
1588 p = mem[rover + 1].hh.v.LH;
1590 mem[p + 1].hh.v.RH = q;
1591 mem[rover + 1].hh.v.LH = q;
1592 /* if (t > 262143L) t = 262143L; */ /* NO! */
1593 if (t > mem_bot + max_halfword)
1594 t = mem_bot + max_halfword; /* silly ? flush 93/Dec/16 */
1595 mem[q + 1].hh.v.RH = rover;
1596 mem[q + 1].hh.v.LH = p;
1597 mem[q].hh.v.RH = empty_flag;
1598 mem[q].hh.v.LH = t - lo_mem_max; /* block size */
1600 mem[lo_mem_max].hh.v.RH = 0;
1601 mem[lo_mem_max].hh.v.LH = 0;
1605 /* overflow("main memory size", mem_max + 1 - mem_min); */ /* what used to happen! */
1606 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1607 /* we've run out of space in the middle for variable length blocks */
1608 /* try and add new block from below mem_bot *//* first check if space ! */
1609 if (mem_min - (block_size + 1) <= mem_start) {/* extend lower memory downwards */
1610 /* realloc_main (mem_top/2, 0); */
1611 mem = realloc_main (mem_top/2 + block_size, 0); /* zzzaa = zmem = mem */
1616 /* if (trace_flag) show_line("Extending downwards by %d\n", block_size, 0); */
1617 if (mem_min - (block_size + 1) <= mem_start) { /* check again */
1619 sprintf(log_line, "mem_min %d, mem_start %d, block_size %d\n", mem_min, mem_start, block_size);
1620 show_line(log_line, 0);
1622 overflow("main memory size", mem_max + 1 - mem_min); /* darn: allocation failed ! */
1623 return 0; // abort_flag set
1625 /* avoid function call in following ? */
1626 add_variable_space (block_size); /* now to be found in itex.c */
1627 goto lab20; /* go try get_node again */
1628 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
1630 lab40: mem[r].hh.v.RH = 0;
1633 var_used = var_used + s;
1636 /* if (trace_flag) {
1637 if (r == 0) show_line("r IS ZERO in ZGETNODE!\n", 0);
1638 } */ /* debugging code 93/dec/15 */
1644 void free_node_(halfword p, halfword s)
1648 link(p) = empty_flag;
1655 var_used = var_used - s;
1659 halfword new_null_box (void)
1662 p = get_node(box_node_size);
1663 type(p) = hlist_node;
1664 subtype(p) = min_quarterword;
1668 shift_amount(p) = 0;
1670 glue_sign(p) = normal;
1671 glue_order(p) = normal;
1676 halfword new_rule (void)
1679 p = get_node(rule_node_size);
1680 type(p) = rule_node;
1682 width(p) = null_flag;
1683 depth(p) = null_flag;
1684 height(p) = null_flag;
1688 halfword new_ligature_(quarterword f, quarterword c, halfword q)
1691 p = get_node(small_node_size);
1692 type(p) = ligature_node;
1693 font(lig_char(p)) = f;
1694 character(lig_char(p)) = c;
1700 halfword new_lig_item_(quarterword c)
1703 p = get_node(small_node_size);
1709 halfword new_disc (void)
1712 p = get_node(small_node_size);
1713 type(p) = disc_node;
1714 replace_count(p) = 0;
1720 halfword new_math_(scaled w, small_number s)
1723 p = get_node(small_node_size);
1724 type(p) = math_node;
1730 halfword new_spec_(halfword p)
1733 q = get_node(glue_spec_size);
1735 glue_ref_count(q) = 0;
1736 width(q) = width(p);
1737 stretch(q) = stretch(p);
1738 shrink(q) = shrink(p);
1742 halfword new_param_glue_(small_number n)
1746 p = get_node(small_node_size);
1747 type(p) = glue_node;
1752 incr(glue_ref_count(q));
1756 halfword new_glue_(halfword q)
1759 p = get_node(small_node_size);
1760 type(p) = glue_node;
1761 subtype(p) = normal;
1764 incr(glue_ref_count(q));
1768 halfword new_skip_param_(small_number n)
1771 temp_ptr = new_spec(glue_par(n));
1772 p = new_glue(temp_ptr);
1773 glue_ref_count(temp_ptr) = 0;
1778 halfword new_kern_(scaled w)
1781 p = get_node(small_node_size);
1782 type(p) = kern_node;
1783 subtype(p) = normal;
1788 halfword new_penalty_(integer m)
1791 p = get_node(small_node_size);
1792 type(p) = penalty_node;
1800 void check_mem_(bool printlocs)
1805 for (p = mem_min; p <= lo_mem_max; p++) freearr[p] = false;
1806 for (p = hi_mem_min; p <= mem_end; p++) freearr[p] = false;
1811 if ((p > mem_end) || (p < hi_mem_min))
1813 else if (freearr[p])
1818 print_nl("AVAIL list clobbered at ");
1831 if ((p >= lo_mem_max) || (p < mem_min))
1833 else if ((rlink(p) >= lo_mem_max) || (rlink(p) < mem_min))
1835 else if (!(is_empty(p)) || (node_size(p) < 2) ||
1836 (p + node_size(p) > lo_mem_max) || (llink(rlink(p)) != p))
1841 print_nl("Double-AVAIL list clobbered at ");
1846 for (q = p; q <= p + node_size(p) - 1; q++)
1850 print_nl("Doubly free location at ");
1858 } while (!(p == rover));
1861 while (p <= lo_mem_max) {
1864 print_nl("Bad flag at ");
1867 while ((p <= lo_mem_max) && !freearr[p]) incr(p);
1868 while ((p <= lo_mem_max) && freearr[p]) incr(p);
1873 print_nl("New busy locs:");
1875 for (p = mem_min; p <= lo_mem_max; p++)
1876 if (!freearr[p] && ((p > was_lo_max) || wasfree[p]))
1882 for (p = hi_mem_min; p <= mem_end; p++)
1883 if (!freearr[p] && ((p < was_hi_min) || (p > was_mem_end) || wasfree[p]))
1890 for (p = mem_min; p <= lo_mem_max; p++) wasfree[p] = freearr[p];
1891 for (p = hi_mem_min; p <= mem_end; p++) wasfree[p] = freearr[p];
1893 was_mem_end = mem_end;
1894 was_lo_max = lo_mem_max;
1895 was_hi_min = hi_mem_min;
1901 void search_mem_(halfword p)
1905 for (q = mem_min; q <= lo_mem_max; q++)
1921 for (q = hi_mem_min; q <= mem_end; q++)
1937 for (q = active_base; q <= box_base + 255; q++)
1946 for (q = 0; q <= save_ptr - 1; q++)
1948 if (equiv_field(save_stack[q]) == p)
1956 for (q = 0; q <= hyphen_prime; q++)
1957 if (hyph_list[q] == p)
1966 void short_display_(integer p)
1969 /* while(p > mem_min){ */
1970 while (p != 0) { /* want p != null here bkph 93/Dec/15 !!! NOTE: still not fixed in 3.14159 ! */
1971 if (is_char_node(p))
1975 if (font(p) != font_in_short_display)
1977 if ((font(p) > font_max))
1982 print(hash[(hash_size + hash_extra + 524) + mem[p].hh.b0].v.RH);
1985 font_in_short_display = font(p);
1987 print(character(p));
1990 else switch (mem[p].hh.b0)
2005 if (glue_ptr(p) != 0)
2012 short_display(lig_ptr(p));
2015 short_display(pre_break(p));
2016 short_display(post_break(p));
2017 n = replace_count(p);
2019 if (link(p) != 0) /* if link(p)<>null then */
2031 void print_font_and_char_ (integer p)
2034 print_esc("CLOBBERED.");
2036 if ((font(p) > font_max))
2041 print(hash[(hash_size + hash_extra + 524) + mem[p].hh.b0].v.RH);
2044 print(character(p));
2048 void print_mark_ (integer p)
2051 if ((p < hi_mem_min)||(p > mem_end))
2052 print_esc("CLOBBERED.");
2054 show_token_list(link(p), 0, max_print_line - 10);
2058 void print_rule_dimen_ (scaled d)
2060 if ((d == -1073741824L)) /* - 2^30 */
2066 void print_glue_(scaled d, integer order, char * s)
2069 if ((order < normal) || (order > filll))
2070 print_string("foul");
2073 print_string("fil");
2078 } else if (*s != '\0')
2082 void print_spec_(integer p, char * s)
2084 if ((p < mem_min)||(p >= lo_mem_max))
2087 print_scaled(mem[p + 1].cint);
2092 if (stretch(p) != 0)
2094 print_string("plus");
2095 print_glue(stretch(p), stretch_order(p), s);
2100 print_string("minus");
2101 print_glue(shrink(p), shrink_order(p), s);
2106 void print_fam_and_char_(halfword p)
2109 print_int(mem[p].hh.b0);
2111 print(mem[p].hh.b1);
2114 void print_delimiter_(halfword p)
2117 a = mem[p].qqqq.b0 * 256 + mem[p].qqqq.b1;
2118 a = a * 4096 + mem[p].qqqq.b2 * 256 + mem[p].qqqq.b3;
2125 void print_subsidiary_data_(halfword p, ASCII_code c)
2127 if ((pool_ptr - str_start[str_ptr]) >= depth_threshold)
2129 if (mem[p].hh.v.RH != 0)
2136 switch (mem[p].hh.v.RH)
2140 print_current_string();
2141 print_fam_and_char(p);
2150 print_current_string();
2163 void print_style_(integer c)
2168 print_esc("displaystyle");
2171 print_esc("textstyle");
2174 print_esc("scriptstyle");
2177 print_esc("scriptscriptstyle");
2180 print_string("Unknown style!");
2185 void print_skip_param_(integer n)
2189 case line_skip_code:
2190 print_esc("lineskip");
2192 case baseline_skip_code:
2193 print_esc("baselineskip");
2196 print_esc("parskip");
2198 case above_display_skip_code:
2199 print_esc("abovedisplayskip");
2201 case below_display_skip_code:
2202 print_esc("belowdisplayskip");
2204 case above_display_short_skip_code:
2205 print_esc("abovedisplayshortskip");
2207 case below_display_short_skip_code:
2208 print_esc("belowdisplayshortskip");
2210 case left_skip_code:
2211 print_esc("leftskip");
2213 case right_skip_code:
2214 print_esc("rightskip");
2217 print_esc("topskip");
2219 case split_top_skip_code:
2220 print_esc("splittopskip");
2223 print_esc("tabskip");
2225 case space_skip_code:
2226 print_esc("spaceskip");
2228 case xspace_skip_code:
2229 print_esc("xspaceskip");
2231 case par_fill_skip_code:
2232 print_esc("parfillskip");
2234 case thin_mu_skip_code:
2235 print_esc("thinmuskip");
2237 case med_mu_skip_code:
2238 print_esc("medmuskip");
2240 case thick_mu_skip_code:
2241 print_esc("thickmuskip");
2244 print_string("[unknown glue parameter!]");
2249 void show_node_list_(integer p)
2254 if (cur_length > depth_threshold)
2256 /* if (p > 0) */ /* was p>null !!! line 3662 in tex.web */
2257 if (p != 0) /* fixed 94/Mar/23 BUG FIX NOTE: still not fixed in 3.14159 ! */
2262 /* while(p > mem_min){ */ /* was p>mem_min !!! line 3667 in tex.web */
2263 while (p != 0) { /* want p != null - bkph 93/Dec/15 NOTE: still not fixed in 3.14159 ! */
2265 print_current_string();
2268 print_string("Bad link, display aborted.");
2272 if (n > breadth_max)
2274 print_string("etc.");
2277 if ((p >= hi_mem_min))
2278 print_font_and_char(p);
2279 else switch (mem[p].hh.b0)
2285 if (mem[p].hh.b0 == 0)
2287 else if (mem[p].hh.b0 == 1)
2289 else print_esc("unset");
2290 print_string("box(");
2291 print_scaled(mem[p + 3].cint);
2293 print_scaled(mem[p + 2].cint);
2294 print_string(", shifted ");
2295 print_scaled(mem[p + 1].cint);
2296 if (mem[p].hh.b0 == 13)
2298 if (mem[p].hh.b1 != 0)
2301 print_int(mem[p].hh.b1 + 1);
2302 print_string(" columns)");
2304 if (mem[p + 6].cint != 0)
2306 print_string(", stretch");
2307 print_glue(mem[p + 6].cint, mem[p + 5].hh.b1, "");
2309 if (mem[p + 4].cint != 0)
2311 print_string(", shrink");
2312 print_glue(mem[p + 4].cint, mem[p + 5].hh.b0, "");
2316 if ((g != 0.0)&&(mem[p + 5].hh.b0 != 0))
2318 print_string(", glue set");
2319 if (mem[p + 5].hh.b0 == 2)
2321 if (fabs(g)> 20000.0)
2326 print_string("< -");
2327 print_glue(20000 * 65536L, mem[p + 5].hh.b1, "");
2328 } else print_glue(round(65536L * g), mem[p + 5].hh.b1, "");
2330 if (mem[p + 4].cint != 0)
2332 print_string("shifted");
2333 print_scaled(mem[p + 4].cint);
2338 str_pool[pool_ptr]= 46;
2341 show_node_list(mem[p + 5].hh.v.RH);
2349 print_rule_dimen(mem[p + 3].cint);
2351 print_rule_dimen(mem[p + 2].cint);
2353 print_rule_dimen(mem[p + 1].cint);
2358 print_esc("insert");
2359 print_int(mem[p].hh.b1);
2360 print_string(", natural size ");
2361 print_scaled(mem[p + 3].cint);
2362 print_string("; split(");
2363 print_spec(mem[p + 4].hh.v.RH, "");
2365 print_scaled(mem[p + 2].cint);
2366 print_string("(; float cost");
2367 print_int(mem[p + 1].cint);
2370 str_pool[pool_ptr]= 46;
2373 show_node_list(mem[p + 4].hh.v.LH);
2379 switch (mem[p].hh.b1)
2383 print_write_whatsit(1279, p); /* debug # (-1 to exit): */
2385 print_file_name(mem[p + 1].hh.v.RH, mem[p + 2].hh.v.LH, mem[p + 2].hh.v.RH);
2390 print_write_whatsit(591, p); /* write */
2391 print_mark(mem[p + 1].hh.v.RH);
2395 print_write_whatsit(1280, p); /* closeout */
2399 print_esc("special");
2400 print_mark(mem[p + 1].hh.v.RH);
2405 print_esc("setlanguage");
2406 print_int(mem[p + 1].hh.v.RH);
2407 print_string(" (hyphenmin");
2408 print_int(mem[p + 1].hh.b0);
2410 print_int(mem[p + 1].hh.b1);
2415 print_string("whatsit");
2420 if (mem[p].hh.b1 >= 100)
2423 if (mem[p].hh.b1 == 101)
2425 else if (mem[p].hh.b1 == 102)
2427 print_string("leaders ");
2428 print_spec(mem[p + 1].hh.v.LH, "");
2431 str_pool[pool_ptr]= 46;
2434 show_node_list(mem[p + 1].hh.v.RH);
2439 if (mem[p].hh.b1 != 0)
2442 if (mem[p].hh.b1 < 98)
2443 print_skip_param(mem[p].hh.b1 - 1);
2444 else if (mem[p].hh.b1 == 98)
2445 print_esc("nonscript");
2446 else print_esc("mskip");
2449 if (mem[p].hh.b1 != 98)
2452 if (mem[p].hh.b1 < 98)
2453 print_spec(mem[p + 1].hh.v.LH, "");
2455 print_spec(mem[p + 1].hh.v.LH, "mu");
2460 if (mem[p].hh.b1 != 99)
2463 if (mem[p].hh.b1 != 0)
2465 print_scaled(mem[p + 1].cint);
2466 if (mem[p].hh.b1 == 2)
2467 print_string(" (for accent)");
2470 print_scaled(mem[p + 1].cint);
2477 if (mem[p].hh.b1 == 0)
2479 else print_string("off");
2480 if (mem[p + 1].cint != 0)
2482 print_string(", surrounded");
2483 print_scaled(mem[p + 1].cint);
2489 print_font_and_char(p + 1);
2490 print_string("(ligature");
2491 if (mem[p].hh.b1 > 1)
2493 font_in_short_display = mem[p + 1].hh.b0;
2494 short_display(mem[p + 1].hh.v.RH);
2495 if (odd(mem[p].hh.b1))
2502 print_esc("penalty ");
2503 print_int(mem[p + 1].cint);
2508 print_esc("discretionary");
2509 if (mem[p].hh.b1 > 0)
2511 print_string(" replacing ");
2512 print_int(mem[p].hh.b1);
2516 str_pool[pool_ptr]= 46;
2519 show_node_list(mem[p + 1].hh.v.LH);
2523 str_pool[pool_ptr]= 124;
2526 show_node_list(mem[p + 1].hh.v.RH);
2533 print_mark(mem[p + 1].cint);
2538 print_esc("vadjust");
2541 str_pool[pool_ptr]= 46;
2544 show_node_list(mem[p + 1].cint);
2550 print_style(mem[p].hh.b1);
2554 print_esc("mathchoice");
2556 str_pool[pool_ptr]= 68;
2559 show_node_list(mem[p + 1].hh.v.LH);
2562 str_pool[pool_ptr]= 84;
2565 show_node_list(mem[p + 1].hh.v.RH);
2568 str_pool[pool_ptr]= 83;
2571 show_node_list(mem[p + 2].hh.v.LH);
2574 str_pool[pool_ptr]= 115;
2577 show_node_list(mem[p + 2].hh.v.RH);
2597 switch (mem[p].hh.b0)
2600 print_esc("mathord");
2603 print_esc("mathop");
2606 print_esc("mathbin");
2609 print_esc("mathrel");
2612 print_esc("mathopen");
2615 print_esc("mathclose");
2618 print_esc("mathpunct");
2621 print_esc("mathinner");
2624 print_esc("overline");
2627 print_esc("underline");
2630 print_esc("vcenter");
2634 print_esc("radical");
2635 print_delimiter(p + 4);
2640 print_esc("accent");
2641 print_fam_and_char(p + 4);
2647 print_delimiter(p + 1);
2653 print_delimiter(p + 1);
2657 if (mem[p].hh.b1 != 0)
2658 if (mem[p].hh.b1 == 1)
2659 print_esc("limits");
2660 else print_esc("nolimits");
2661 if (mem[p].hh.b0 < 30)
2662 print_subsidiary_data(p + 1, 46);
2663 print_subsidiary_data(p + 2, 94);
2664 print_subsidiary_data(p + 3, 95);
2669 print_esc("fraction");
2670 if (mem[p + 1].cint == 1073741824L) /* 2^30 */
2671 print_string("= default");
2672 else print_scaled(mem[p + 1].cint);
2673 if ((mem[p + 4].qqqq.b0 != 0) || (mem[p + 4].qqqq.b1 != 0) ||
2674 (mem[p + 4].qqqq.b2 != 0) || (mem[p + 4].qqqq.b3 != 0))
2676 print_string(", left");
2677 print_delimiter(p + 4);
2679 if ((mem[p + 5].qqqq.b0 != 0) || (mem[p + 5].qqqq.b1 != 0) ||
2680 (mem[p + 5].qqqq.b2 != 0)||(mem[p + 5].qqqq.b3 != 0))
2682 print_string(", right");
2683 print_delimiter(p + 5);
2685 print_subsidiary_data(p + 2, 92);
2686 print_subsidiary_data(p + 3, 47);
2690 print_string("Unknown node type!");
2696 /* NOTE: 262143L should be empty_flag */