1 /* Copyright 2007 TeX Users Group
2 Copyright 2014 Clerk Ma
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 #pragma warning(disable:4115) // kill rpcasync.h complaint
26 #define MYLIBAPI __declspec(dllexport)
31 #pragma warning(disable:4996)
32 #pragma warning(disable:4131) // old style declarator
33 #pragma warning(disable:4135) // conversion between different integral types
34 #pragma warning(disable:4127) // conditional expression is constant
42 /* Most Y & Y changes are localized here -- init() */
44 /* Note int main (int ac, char *av[]) is in texmf.c */
45 /* and that calls main_program = texbody in itex.c => initialize */
46 /* which in turn calls init here in local.c */
47 /* which then calls initcommands here in local.c */
49 #define USEOUREALLOC /* 96/Jan/20 */
51 #define USEMEMSET /* 98/Jan/23 */
53 /* #define PREALLOCHOLE */ /* make hole in heap at bottom debugging */
55 /* #define CHECKALIGNMENT */ /* reactivated 95/Jan/7 */
57 /* #define HEAPSHOW */ /* debugging 96/Jan/20 */
59 /* #ifdef TRYANDOPEN */ /* debugging only */
61 /* #define SHOWHEAPERROR */ /* debugging 96/Jan/10 */
63 #define ALLOWDEMO /* demo model - limited lifetime - DANGER ! */
66 /* #define HEAPWALK */ /* debugging 96/Oct/22 */
70 #define REALLOC ourrealloc
72 #define REALLOC realloc
76 #include <time.h> // needed for clock_t etc.
77 /* #include <string.h> */ /* for islower ? */
78 // #include <process.h>
79 #include <malloc.h> /* _msize, _expand, HEAPOK et.c */
80 // #include <share.h> /* SH_DENYNO */
81 #include <direct.h> /* for _getcwd() */
83 #pragma warning(disable:4032) // different type when promoted
85 #include <conio.h> /* for _getch() */
87 #pragma warning(default:4032) // different type when promoted`
89 // #include "getopt.h"
93 /* Argument handling, etc. */ /* from common.h - setup `main' in texmf.c */
94 /* extern int gargc; */
95 /* extern char **gargv; */
99 /* appears in reverse order in EXE file */
101 char *compiletime = __TIME__;
102 char *compiledate = __DATE__;
103 char *www = "http://www.tug.org/yandy"; /* not used ? */
104 char *rights = "All Rights Reserved."; /* not used ? */
105 char *copyright = "Copyright (C) 2007--2014 TeX Users Group.";
106 char *yandyversion = "2.2.3"; /* 00/Jun/18 */
107 char *application = "Y & Y TeX"; /* 96/Jan/17 */
108 char *tex_version = "This is TeX, Version 3.14159265"; /* change with upgrade */
110 /* #define COPYHASH 1890382 */
111 /* #define COPYHASH 13862905 */
112 /* #define COPYHASH 10558802 */
113 /* #define COPYHASH 7254699 */
114 /* #define COPYHASH 3950596 */
115 /* #define COPYHASH 646493 */
116 #define COPYHASH 12905299
118 clock_t start_time, main_time, finish_time;
120 char *dvi_directory = ""; /* user specified directory for dvi file */
121 char *log_directory = ""; /* user specified directory for log file */
122 char *aux_directory = ""; /* user specified directory for aux file */
124 char *texpath = ""; /* path to executable - used if env vars not set */
126 // #define MAXLINE 256
128 char log_line[MAXLINE]; // used also in tex9.c
130 int mem_spec_flag=0; /* non-zero if `-m=...' was used */
131 int format_spec=0; /* non-zero if a format specified on command line */
133 int closed_already=0; // make sure we don't try this more than once
135 bool reorder_arg_flag = true; /* put command line flags/arguments first */
137 /* Mapping from Windows ANSI to DOS code page 850 96/Jan/20 */
138 /* Used in tex0.c with wintodos[c-128] */
140 unsigned char wintodos[128] = {
141 0, 0, 0, 159, 0, 0, 0, 0,
142 94, 0, 0, 0, 0, 0, 0, 0,
143 0, 96, 39, 0, 0, 7, 0, 0,
144 126, 0, 0, 0, 0, 0, 0, 0,
145 32, 173, 189, 156, 207, 190, 221, 21,
146 0, 184, 166, 174, 170, 45, 169, 0,
147 248, 241, 253, 252, 0, 230, 20, 250,
148 0, 251, 167, 175, 172, 171, 243, 168,
149 183, 181, 182, 199, 142, 143, 146, 128,
150 212, 144, 210, 211, 222, 214, 215, 216,
151 209, 165, 227, 224, 226, 229, 153, 158,
152 157, 235, 233, 234, 154, 237, 232, 225,
153 133, 160, 131, 198, 132, 134, 145, 135,
154 138, 130, 136, 137, 141, 161, 140, 139,
155 208, 164, 149, 162, 147, 228, 148, 246,
156 155, 151, 163, 150, 129, 236, 231, 152
159 void show_usage (char *program) {
162 %s [-?ivnwdrzpK] [-m=ini_mem] [-e=hyph_size] [-h=trie_size]\n\
163 \t[-x=xchr_file] [-k=key_file] [-o=dvi_dir] [-l=log_dir] [-a=aux_dir]\n\
164 \t\t[&format_file] [tex_file]\n\
168 -? show this usage summary\n\
169 -i start up as iniTeX (create format file)\n\
170 -v be verbose (show implementation version number)\n\
171 -n do not allow `non ASCII' characters in input files (complain instead)\n\
172 -w do not show `non ASCII' characters in hexadecimal (show as is)\n\
173 -d do not allow DOS style file names - i.e. do not convert \\ to /\n\
174 -r do not allow Mac style termination - i.e. do not convert \\r to \\n\n\
175 -p allow use of \\patterns after loading format (iniTeX only)\n\
176 -K disable all extensions to basic TeX\n\
177 -m initial main memory size in kilo words (iniTeX only)\n\
178 -e hyphenation exception dictionary size (iniTeX only)\n\
179 -h hyphenation pattern trie size (iniTeX only)\n\
180 -x use `non ASCII' character mapping (xchr[]) defined in file\n\
181 -k use `key replacement' defined in file\n\
182 -o write DVI file in specified directory (default current directory)\n\
183 -l write LOG file in specified directory (default current directory)\n\
184 -a write AUX file in specified directory (default current directory)\n\
189 uexit(1); // has this been setup yet ???
193 /* -z do not discard control-Z at end of input file (treat as character)\n\ */
195 /* -c prepend current directory (.) to TFM directory list\n\ */
196 /* -b check that files with read access are not actually directories\n\ */
198 /* \t-d\tallow DOS style file names - i.e. convert \\ to / \n\ */
199 /* \t\t(applies to file name and format file name, if present)\n\ */
200 /* \t-r\tallow Mac style line termination - i.e. convert \\r to \\n \n\ */
202 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
204 /* Sep 27 1990 => 1990 Sep 27 */
206 void scivilize (char *date)
210 strcpy (year, date + 7);
211 for (k = 5; k >= 0; k--) date[k+5] = date[k];
212 for (k = 0; k < 4; k++) date[k] = year[k];
217 /* Thu Sep 27 06:26:35 1990 => 1990 Sep 27 06:26:35 */
219 void lcivilize (char *date)
224 strcpy (year, date + 20);
225 for (k = 18; k >= 0; k--) date[k+1] = date[k];
226 /* date[20] = '\n'; */
227 /* date[21] = '\0'; */
229 for (k = 0; k < 4; k++) date[k] = year[k];
234 // void stamp_it (FILE *outfile)
235 // now writes result into given buffer
236 void stamp_it (char *s)
240 strcpy(date, compiledate);
242 sprintf(s, "%s %s ", application, yandyversion);
245 sprintf(s, "(compiled time: %s %s)", date, compiletime);
249 void stampcopy (char *s)
252 sprintf(s, "%s %s", copyright, www); /* 99/Oct/25 */
256 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
261 void read_xchr_sub (FILE *input)
263 char buffer[PATH_MAX];
264 int k, from, to, count = 0;
268 memset (xchr, NOTDEF, MAXCHRS); /* mark unused */
270 for (k = 0; k < MAXCHRS; k++) xchr[k]= -1; */ /* mark unused */
273 memset (xord, NOTDEF, MAXCHRS); /* mark unused */
275 for (k = 0; k < MAXCHRS; k++) xord[k]= -1; */ /* mark unused */
278 #ifdef ALLOCATEBUFFER
279 while (fgets(buffer, current_buf_size, input) != NULL)
281 while (fgets(buffer, sizeof(buffer), input) != NULL)
284 if (*buffer == '%' || *buffer == ';' || *buffer == '\n') continue;
285 /* if (sscanf (buffer, "%d %d", &from, &to) < 2)
286 sprintf(log_line, "Do not understand: %s", buffer); */
287 from = (int) strtol (buffer, &s, 0);
288 to = (int) strtol (s, NULL, 0);
289 /* what if line is bad ? do we just get from = 0 and to = 0 ? */
290 if (from >= 0 && from < MAXCHRS && to >= 0 && to < MAXCHRS) {
291 if (xchr[from]== (unsigned char) NOTDEF)
292 xchr[from]= (unsigned char) to;
294 sprintf(log_line, "NOTE: %s collision: %d => %d, %d\n",
295 "xchr", from, xchr[from], to);
296 show_line(log_line, 0);
298 if (xord[to]== NOTDEF)
299 xord[to]= (unsigned char) from;
301 sprintf(log_line, "NOTE: %s collision: %d => %d, %d\n",
302 "xord", to, xord[to], from);
303 show_line(log_line, 0);
308 /* now fill in the gaps */ /* not clear this is a good idea ... */
309 for (k = 0; k < MAXCHRS; k++) {
310 if (xchr[k]== NOTDEF) { /* if it has not been filled */
311 if (xord[k]== NOTDEF) { /* see whether used already */
312 xchr[k]= (unsigned char) k; /* no, so make identity */
313 xord[k]= (unsigned char) k; /* no, so make identity */
317 xchr[NOTDEF]= NOTDEF; /* fixed point of mapping */
319 sprintf(log_line, "Read %d xchr[] pairs:\n", count);
320 show_line(log_line, 0);
321 for (k = 0; k < MAXCHRS; k++) {
322 if (xchr[k]!= NOTDEF) {
323 sprintf(log_line, "%d => %d\n", k, xchr[k]);
324 show_line(log_line, 0);
330 char *replacement[MAXCHRS]; /* pointers to replacement strings */
332 void read_repl_sub (FILE *input)
335 char buffer[PATH_MAX];
341 memset(replacement, 0, MAXCHRS * sizeof(replacement[ 0]));
343 for (k = 0; k < MAXCHRS; k++) replacement[k] = NULL;
346 while (fgets(buffer, PATH_MAX, input) != NULL) {
347 if (*buffer == '%' || *buffer == ';' || *buffer == '\n') continue;
348 if ((m = sscanf (buffer, "%d%n %s", &chrs, &n, &charname)) == 0)
351 if (*charname == '"') { /* deal with quoted string "..." */
354 while (*s != '"' && *s != '\0') s++; /* step up to " */
355 if (*s++ == '\0') continue; /* sanity check */
358 s++; /* is it "" perhaps ? */
359 if (*s != '"') break; /* no, end of string */
361 *t++ = *s++; /* copy over */
363 *t = '\0'; /* and terminate */
365 if (chrs >= 0 && chrs < MAXCHRS)
366 replacement[chrs] = xstrdup(charname);
368 /* presently the following can never get triggered */
369 /* which is good, because it is perhaps not right ... */
370 else if ((m = sscanf (buffer, "%d %d %d %d %d %d %d %d %d %d %d",
371 &chrs, charnum, charnum+1, charnum+2, charnum+3, charnum+4,
372 charnum+5, charnum+6, charnum+7, charnum+8, charnum+9)) > 1) {
373 /* for (k = 0; k < n-1; k++) charname[k] = (char) charnum; */
374 for (k = 0; k < n-1; k++) charname[k] = (char) charnum[k];
376 if (chrs >= 0 && chrs < MAXCHRS)
377 replacement[chrs] = xstrdup(charname);
380 sprintf(log_line, "ERROR: don't understand %s", buffer);
381 show_line(log_line, 1);
384 if (trace_flag) { /* debugging output */
385 show_line("Key replacement table\n", 0);
386 for (k = 0; k < MAXCHRS; k++) {
387 if (replacement[k] != NULL) {
388 sprintf(log_line, "%d\t%s\n", k, replacement[k]);
389 show_line(log_line, 0);
395 /* Following used both to read xchr[] file and key replacement file */
396 /* the flag is 0 for -x=... and the flag is 1 for -k=... */
398 int read_xchr_file (char *filename, int flag, char *argv[])
401 char infile[PATH_MAX];
404 if (filename == NULL) return -1;
406 sprintf(log_line, "Reading xchr/repl %s\n", filename);
407 show_line(log_line, 0);
410 /* first try using file as specified */
411 strcpy(infile, filename);
413 sprintf(log_line, "Trying %s\n", infile);
414 show_line(log_line, 0);
416 if (share_flag == 0) input = fopen (infile, "r");
417 else input = _fsopen (infile, "r", share_flag); /* 94/July/12 */
419 if (strrchr(infile, '.') == NULL) {
420 if (flag == 0) strcat(infile, ".map");
421 else strcat(infile, ".key");
423 sprintf(log_line, "Trying %s\n", infile);
424 show_line(log_line, 0);
426 if (share_flag == 0) input = fopen (infile, "r");
427 else input = _fsopen (infile, "r", share_flag); /* 94/July/12 */
431 /* strcpy (infile, gargv[0]); */ /* try TeX program path */
432 strcpy (infile, argv[0]); /* try TeX program path */
433 if ((s = strrchr (infile, '\\')) != NULL) *(s+1) = '\0';
434 else if ((s = strrchr (infile, '/')) != NULL) *(s+1) = '\0';
435 else if ((s = strrchr (infile, ':')) != NULL) *(s+1) = '\0';
436 strcat (infile, filename);
438 sprintf(log_line, "Trying %s\n", infile);
439 show_line(log_line, 0);
441 if (share_flag == 0) input = fopen (infile, "r");
442 else input = _fsopen (infile, "r", share_flag); /* 94/July/12 */
444 if (strchr(infile, '.') == NULL) {
445 if (flag == 0) strcat(infile, ".map");
446 else strcat(infile, ".key");
448 sprintf(log_line, "Trying %s\n", infile);
449 show_line(log_line, 0);
451 if (share_flag == 0) input = fopen (infile, "r");
452 else input = _fsopen (infile, "r", share_flag); /* 94/July/12 */
456 if (input == NULL) { /* 97/July/31 */
457 /* strcpy (infile, gargv[0]); */ /* try TeX program path\keyboard */
458 strcpy (infile, argv[0]); /* try TeX program path */
459 if ((s = strrchr (infile, '\\')) != NULL) *(s+1) = '\0';
460 else if ((s = strrchr (infile, '/')) != NULL) *(s+1) = '\0';
461 else if ((s = strrchr (infile, ':')) != NULL) *(s+1) = '\0';
462 strcat (infile, "keyboard\\");
463 strcat (infile, filename);
465 sprintf(log_line, "Trying %s\n", infile);
466 show_line(log_line, 0);
468 if (share_flag == 0) input = fopen (infile, "r");
469 else input = _fsopen (infile, "r", share_flag);
471 if (strchr(infile, '.') == NULL) {
472 if (flag == 0) strcat(infile, ".map");
473 else strcat(infile, ".key");
475 sprintf(log_line, "Trying %s\n", infile);
476 show_line(log_line, 0);
478 if (share_flag == 0) input = fopen (infile, "r");
479 else input = _fsopen (infile, "r", share_flag);
483 /* Note: can't look in TeX source file dir, since that is not known yet */
485 sprintf(log_line, "ERROR: Sorry, cannot find %s file %s",
486 flag ? " xchr[]" : "key mapping", filename);
487 show_line(log_line, 1);
488 perrormod (filename);
493 read_xchr_sub (input);
495 read_repl_sub (input);
497 (void) fclose (input);
501 /* need to also set `key_replace' here based on command line */
502 /* need to also allocate `buffercopy' here and free at end */
503 /* need to call `readreplace' in appropriate place */
505 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
507 /* Following may be useful if link without floating point emulation */
510 void testfloating (void) {
511 /* double x = 1.0; */
512 /* double dx = DBL_EPSILON; */
516 /* while (x + dx != 1.0) { */
517 while (1.0 + dx != 1.0) {
522 sprintf(log_line, "Floating test: dx = %lg (k = %d)\n", dxold, k - 1);
523 show_line(log_line, 0);
527 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
529 char *debugfile; /* NULL or name of file to try and open */
532 char *heapstrings[] = {
533 "", "Empty", "OK", "Bad Begin", "Bad Node", "End", "Bad Pointer"
537 /* Attempt to get at problem with eqtb ... temporarily abandoned */
540 void check_eqtb (char *act) {
542 memory_word *eqtb = zeqtb;
543 /* for (k = 10280 + hash_extra; k < 10280 + eqtb_extra; k++) { */
544 for (k = hash_size + 780 + hash_extra; k < hash_size + 780 + eqtb_extra; k++) {
545 if (eqtb[k].cint != 0) {
548 show_line("EQTB ", 0);
550 sprintf(log_line, "%d ", k);
551 show_line(log_line, 0);
552 if (count++ > 256) break;
555 if (count != 0) show_char('\n');
559 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
563 /* ad hoc default minimum growth in memory realloc is 62% */
564 /* golden ratio (1 + \sqrt{5}) / 2 = 1.618033989... */
565 int percent_grow = 62; /* default minimum growth in memory realloc is 62% */
566 int total_allocated = 0; /* total memory allocated so far */
567 int ini_max_address = 0; /* maximum address when starting */
568 int max_address = 0; /* maximum address seen in allocated memory */
572 // DON'T USE THIS in DLL VERSION
576 unsigned int heapthreshold=0; /* smallest size block interested in ... */
578 unsigned int heap_dump (FILE *output, int verbose)
580 unsigned int total=0;
581 struct _heapinfo hinfo;
586 if (verbose) fprintf(output, "HEAP DUMP:\n");
588 /* if ((n = _heapchk ()) != _HEAPOK) { */
594 fprintf(stderr, "WARNING: Heap corrupted (%d)\n", n);
596 fprintf(stderr, "HEAP %s (%s)\n", heapstrings[-n], "heap_dump");
599 hinfo._pentry = NULL;
600 while ((heapstatus = _heapwalk(&hinfo)) == _HEAPOK) {
601 if (end_block > 0 && (int) hinfo._pentry > end_block + 1024) {
602 // if (verbose) printf("GAP of %d bytes!\n", (int) hinfo._pentry - end_block);
604 end_block = (int) hinfo._pentry + hinfo._size;
605 if (hinfo._useflag == _USEDENTRY) total += hinfo._size;
606 if (hinfo._size >= heapthreshold && verbose)
607 fprintf(output, "%6s block at %p (%7d) of size %6X (%7d) => (%7d)\n",
608 (hinfo._useflag == _USEDENTRY ? "USED" : "...."),
609 hinfo._pentry, hinfo._pentry, hinfo._size, hinfo._size,
612 switch (heapstatus) {
614 if (verbose) fprintf(output, "OK - empty heap\n");
617 if (verbose) fprintf(output, "OK - end of heap (%u bytes used)\n", total);
620 fprintf(output, "ERROR - %s\n", "bad pointer to heap");
623 fprintf(output, "ERROR - %s\n", "bad start of heap");
626 fprintf(output, "ERROR - %s\n", "bad node in heap");
634 void show_maximums (FILE *output)
637 unsigned heaptotal=0; /* no longer used */
638 heaptotal = heap_dump(stdout, 0); /* 94/Apr/3 */
641 "Max allocated %d --- max address %d\n",
642 total_allocated, max_address);
643 // if (output != NULL) fputs(log_line, output); // log file
644 // else if (flag == 0) show_line(log_line, 0); // informative
645 // else if (flag == 1) show_line(log_line, 1); // error
646 if (output == stderr) show_line(log_line, 1);
647 else if (output == stdout) show_line(log_line, 0);
648 else fputs(log_line, output);
651 /* our own version of realloc --- avoid supposed MicroSoft version bug */
652 /* also tries _expand first, which can avoid address growth ... */
655 void *ourrealloc (void *old, size_t new_size)
658 size_t old_size, overlap;
660 /* round up to nearest multiple of four bytes *//* avoid unlikely alignment */
661 if ((new_size % 4) != 0) new_size = ((new_size / 4) + 1) * 4;
663 if (old == NULL) return malloc (new_size); /* no old block - use malloc */
665 old_size = _msize (old);
666 if (old_size >= new_size && old_size < new_size + 4) return old;
667 /* _heapmin(); */ /* release unused heap space to the system - no op ? */
670 show_line("BEFORE REALLOC: \n", 0);
672 (void) heap_dump(stdout, 1); /* debugging 96/Jan/18 */
676 new = _expand (old, new_size); /* first try and expand in place */
679 sprintf(log_line, "EXPANDED! %d (%d) == %d (%d)\n",
680 new, new_size, old, old_size);
681 show_line(log_line, 0);
685 /* *********************************************************************** */
686 /* do this if you want to call the real realloc next - */
687 new = realloc (old, new_size);
690 show_line("AFTER REALLOC: \n", 0);
692 (void) heap_dump(stdout, 1); /* debugging 96/Jan/18 */
696 if (new != NULL) return new;
697 /* we are screwed typically if we ever drop through here - no more space */
698 /* *********************************************************************** */
699 new = malloc (new_size); /* otherwise find new space */
700 if (new == NULL) return new; /* if unable to allocate */
701 if (old_size < new_size) overlap = old_size;
702 else overlap = new_size;
703 memcpy (new, old, overlap); /* copy old data to new area */
704 free(old); /* free the old area */
709 void memory_error (char *s, int n)
713 "\n! Unable to allocate %d bytes for %s\n", n, s);
714 show_maximums(log_file);
716 if (heap_flag) (void) heap_dump(log_file, 1);
719 sprintf(log_line, "\n! Unable to allocate %d bytes for %s\n", n, s);
720 show_line(log_line, 1);
721 show_maximums(stderr);
723 if (heap_flag) (void) heap_dump(stderr, 1);
725 /* exit (1); */ /* 94/Jan/22 */
726 /* return to let TeX do its thing (such as complain about runaway) */
727 /* don't set abort_flag here */
730 void trace_memory (char *s, int n)
732 sprintf(log_line, "Allocating %d bytes for %s\n", n, s);
733 show_line(log_line, 0);
736 void update_statistics (int address, int size, int oldsize)
738 if (address + size > max_address) max_address = address + size;
739 total_allocated = total_allocated + size - oldsize;
742 void probe_memory (void)
745 s = (char *) malloc (4); /* get current top address */
747 update_statistics ((int) s, 0, 0); /* show where we are */
750 void probe_show (void)
753 show_maximums(stdout);
755 if (heap_flag) (void) heap_dump(stdout, 1);
759 size_t roundup (size_t n)
761 if ((n % 4) == 0) return n;
762 else return ((n / 4) + 1) * 4;
766 /* using allocating hyphenation trie slows things down maybe 1% */
767 /* but saves typically (270k - 55k) = 215k of memory */
768 /* NOTE: it's safe to allocate based on the trie_max read from fmt file */
769 /* since hyphenation trie cannot be extended (after iniTeX) */
770 /* for iniTeX, however, we need to allocate the full trie_size ahead of time */
772 /* NOTE: we don't ever reallocate these */
773 /* returns -1 if it fails */
775 int allocate_tries (int trie_max)
778 /* if (trie_max > trie_size) {
779 sprintf(log_line, "ERROR: invalid trie size (%d > %d)\n",
780 trie_max, trie_size);
781 show_line(log_line, 1);
783 } */ /* ??? removed 1993/dec/17 */
784 if (trie_max > 1000000) trie_max = 1000000; /* some sort of sanity limit */
785 /* important + 1 because original was halfword trietrl[trie_size + 1] etc. */
786 nl = (trie_max + 1) * sizeof(halfword); /* trietrl[trie_size + 1] */
787 no = (trie_max + 1) * sizeof(halfword); /* trietro[trie_size + 1] */
788 nc = (trie_max + 1) * sizeof(quarterword); /* trietrc[trie_size + 1] */
790 if (trace_flag) trace_memory("hyphen trie", n);
791 trietrl = (halfword *) malloc (roundup(nl));
792 trietro = (halfword *) malloc (roundup(no));
793 trietrc = (quarterword *) malloc (roundup(nc));
794 if (trietrl == NULL || trietro == NULL || trietrc == NULL) {
795 memory_error("hyphen trie", n);
797 // exit (1); /* serious error */
800 sprintf(log_line, "Addresses trietrl %d trietro %d trietrc %d\n",
801 trietrl, trietro, trietrc);
802 show_line(log_line, 0);
804 update_statistics ((int) trietrl, nl, 0);
805 update_statistics ((int) trietro, no, 0);
806 update_statistics ((int) trietrc, nc, 0);
807 /* sprintf(log_line, "trie_size %d trie_max %d\n", trie_size, trie_max); */ /* debug */
808 trie_size = trie_max; /* BUG FIX 98/Jan/5 */
809 if (trace_flag) probe_show (); /* 94/Mar/25 */
814 #ifdef ALLOCATEHYPHEN
815 bool prime (int); /* test function later in this file */
817 int currentprime = 0; /* remember in case reallocated later */
819 /* we don't return an address here, since TWO memory regions allocated */
820 /* plus, we don't really reallocate, we FLUSH the old information totally */
821 /* returns -1 if it fails */
823 int realloc_hyphen (int hyphen_prime)
826 if (!prime(hyphen_prime)) {
827 sprintf(log_line, "ERROR: non-prime hyphen exception number (%d)\n",
829 show_line(log_line, 1);
833 /* need not/cannot preserve old contents when hyphen prime is changed */
834 /* if (hyph_list != NULL) free(hyph_list); */
835 /* if (hyph_word != NULL) free(hyph_word); */
836 /* important + 1 since str_number hyph_word[hyphen_prime + 1] in original etc. */
837 nw = (hyphen_prime + 1) * sizeof(str_number);
838 nl = (hyphen_prime + 1) * sizeof(halfword);
840 if (trace_flag) trace_memory("hyphen exception", n);
841 /* initially hyph_word will be NULL so this acts like malloc */
842 /* hyph_word = (str_number *) malloc (nw); */
843 hyph_word = (str_number *) REALLOC (hyph_word, nw); /* 94/Mar/24 */
844 /* initially hyph_list will be NULL so this acts like malloc */
845 /* hyph_list = (halfword *) malloc (nl); */
846 hyph_list = (halfword *) REALLOC (hyph_list, nl); /* 94/Mar/24 */
847 if (hyph_word == NULL || hyph_list == NULL) {
848 memory_error("hyphen exception", n);
849 // exit (1); /* serious error */
853 sprintf(log_line, "Addresses hyph_word %d hyph_list %d\n",
854 hyph_word, hyph_list);
855 show_line(log_line, 0);
857 /* cannot preserve old contents when hyphen prime is changed */
859 memset(hyph_word, 0, (hyphen_prime + 1) * sizeof (hyph_word[0]));
861 for (k = 0; k <= hyphen_prime; k++) hyph_word[k]= 0;
864 memset(hyph_list, 0, (hyphen_prime + 1) * sizeof (hyph_list[0]));
866 for (k = 0; k <= hyphen_prime; k++) hyph_list[k]= 0;
868 hyph_count = 0; /* or use reset_hyphen() in itex.c */
869 if (currentprime != 0) {
870 update_statistics ((int) hyph_word, nw,
871 (currentprime + 1) * sizeof(str_number));
872 update_statistics ((int) hyph_list, nl,
873 (currentprime + 1) * sizeof(halfword));
876 update_statistics ((int) hyph_word, nw, 0);
877 update_statistics ((int) hyph_list, nl, 0);
879 currentprime = hyphen_prime;
880 if (trace_flag) probe_show (); /* 94/Mar/25 */
885 int current_mem_size=0; /* current total words in main mem allocated -1 */
887 /* this gets called from itex.c when it figures out what mem_top is */
888 /* or gets called from here when in ini_TeX mode */ /* and nowhere else */
889 /* initial allocation only, may get expanded later */
890 /* NOTE: we DON't use ALLOCATEHIGH & ALLOCATELOW anymore */
891 /* returns NULL if it fails */
894 /* void allocate_main_memory (int size) { */ /* initial main memory alloc - mem_top */
895 memory_word *allocate_main_memory (int size)
896 { /* initial main memory alloc - mem_top */
899 /* Using -i *and* pre-loading format */ /* in this case get called twice */
900 /* Get rid of initial blank memory again */ /* or use realloc ... */
901 /* Could we avoid this by detecting presence of & before allocating ? */
902 /* Also, if its already large enough, maybe we can avoid this ? */
903 /* don't bother if current_mem_size == mem_max - mem_start ? */
904 if (mainmemory != NULL) {
905 /* free(mainmemory); */
906 /* mainmemory = NULL; */
907 if (trace_flag) show_line("Reallocating initial memory allocation\n", 1);
908 /* if (mem_spec_flag)
909 show_line("Cannot change initial main memory size when format is read\n", 1);*/
912 mem_top = mem_bot + size;
913 #ifdef ALLOCATEHIGH /* NOT USED ANYMORE */
914 if (mem_extra_high != 0 && !is_initex) mem_max = mem_top + mem_extra_high;
917 #ifdef ALLOCATELOW /* NOT USED ANYMORE */
918 if (mem_extra_low != 0 && !is_initex)
919 mem_start = mem_bot - mem_extra_low; /* increase main memory */
921 mem_start = 0; /* bottom of memory allocated by system */
922 /* mem_min = mem_start; */ /* bottom of area made available to TeX */
923 mem_min = 0; /* bottom of area made available to TeX */
924 n = (mem_max - mem_start + 1) * sizeof (memory_word); /* 256k * 8 = 2000 k */
925 if (trace_flag) trace_memory("main memory", n);
926 /* mainmemory = (memory_word *) malloc (n); */ /* 94/March/24 */
927 /* normally mainmemory == NULL here so acts like malloc ... */
928 mainmemory = (memory_word *) REALLOC (mainmemory, n);
929 if (mainmemory == NULL) {
930 memory_error("initial main memory", n);
931 // exit (1); /* serious error */
935 sprintf(log_line, "Address main memory == %d\n", mainmemory);
936 show_line(log_line, 0);
939 if (mem_start != 0 && !is_initex) zzzaa = mainmemory - mem_start;
941 sprintf(log_line, "Offset address main memory == %d\n", zzzaa);
942 show_line(log_line, 0);
944 update_statistics ((int) mainmemory, n,
945 (current_mem_size + 1) * sizeof (memory_word));
946 /* current_mem_size = (mem_max - mem_start + 1); */
947 current_mem_size = mem_max - mem_start; /* total number of words - 1 */
948 if (trace_flag) probe_show (); /* 94/Mar/25 */
949 return zzzaa; /* same as zmem, mem 94/Jan/24 */
951 #endif /* end of ALLOCATEMAIN */
954 /* int firstallocation = 1; */
956 /* increase main memory allocation at low end and high end */
957 /* called only from tex0.c *//* called with one of losize or hisize == 0 */
958 /* returns NULL if it fails */
960 memory_word *realloc_main (int losize, int hisize)
963 int newsize=0; /* to quieten compiler */
964 int n=0; /* to quieten compiler */
965 memory_word *newmemory=NULL; /* to quieten compiler */
967 /* if (losize == 0 && hisize > 0) runawayflag = 1;
968 else runawayflag = 0; */ /* 94/Jan/22 */
971 sprintf(log_line, "WARNING: Entering realloc_main lo %d hi %d\n",
973 show_line(log_line, 0);
976 show_line("ERROR: Cannot extent main memory in iniTeX\n", 1);
978 show_line("Please use `-m=...' on command line\n", 0);
980 // abort_flag++; // ???
984 sprintf(log_line, "Old Address %s == %d\n", "main memory", mainmemory);
985 show_line(log_line, 0);
987 if (current_mem_size + 1 == max_mem_size) {/* if we REALLY run up to limit ! */
988 memory_error("main memory", (max_mem_size + 1) * sizeof(memory_word));
989 // exit (1); /* serious error */
990 // abort_flag++; // ???
993 /* first allocation should expand *both* lo and hi */
994 if (hisize == 0 && mem_end == mem_max) hisize = losize;
995 if (losize == 0 && mem_start == mem_min) losize = hisize;
996 /* try and prevent excessive frequent reallocations */
997 /* while avoiding over allocation by too much */
998 minsize = current_mem_size / 100 * percent_grow;
999 if (losize + hisize < minsize) {
1000 if (losize > 0 && hisize > 0) {
1001 losize = minsize / 2;
1002 hisize = minsize / 2;
1004 else if (losize > 0) losize = minsize;
1005 else if (hisize > 0) hisize = minsize;
1007 if (losize > 0 && losize < mem_top / 2) losize = mem_top / 2;
1008 if (hisize > 0 && hisize < mem_top / 2) hisize = mem_top / 2;
1010 for (k = 0; k < MAXSPLITS; k++) {
1011 newsize = current_mem_size + losize + hisize;
1012 if (newsize >= max_mem_size) { /* bump against limit - ha ha ha */
1013 while (newsize >= max_mem_size) {
1014 losize = losize / 2; hisize = hisize / 2;
1015 newsize = current_mem_size + losize + hisize;
1018 n = (newsize + 1) * sizeof (memory_word);
1019 if (trace_flag) trace_memory("main memory", n);
1020 newmemory = (memory_word *) REALLOC (mainmemory, n);
1021 if (newmemory != NULL) break; /* did we get it ? */
1022 if (current_mem_size == 0) break; /* in case we ever use for initial */
1023 losize = losize / 2; hisize = hisize / 2;
1026 if (newmemory == NULL) {
1027 memory_error("main memory", n);
1028 return zzzaa; /* try and continue with TeX !!! */
1031 sprintf(log_line, "New Address %s == %d\n", "main memory", newmemory);
1032 show_line(log_line, 0);
1035 /* shift everything upward to make space for new low area */
1037 sprintf(log_line, "memmove %d %d %d \n", newmemory + losize,
1038 newmemory, (current_mem_size + 1) * sizeof(memory_word));
1039 show_line(log_line, 0);
1041 memmove (newmemory + losize, newmemory,
1042 /* current_mem_size * sizeof(memory_word)); */
1043 (current_mem_size + 1) * sizeof(memory_word));
1044 /* could reduce words moved by (mem_max - mem_end) */
1046 mainmemory = newmemory; /* remember for free later */
1047 if (losize > 0) mem_start = mem_start - losize; /* update lower limit */
1048 if (hisize > 0) mem_max = mem_max + hisize; /* update upper limit */
1049 update_statistics ((int) mainmemory, n,
1050 (current_mem_size + 1) * sizeof (memory_word));
1051 current_mem_size = newsize;
1052 if (current_mem_size != mem_max - mem_start) {
1053 show_line("ERROR: Impossible Memory Error\n", 1);
1055 if (mem_start != 0) zzzaa = mainmemory - mem_start; /* ??? sign ??? */
1056 else zzzaa = mainmemory;
1057 if (trace_flag) probe_show (); /* 94/Mar/25 */
1063 /* font_mem_size = 10000L ==> font_info array 100k * 8 = 800 kilobytes */
1065 int current_font_mem_size=0;
1067 /* fmemoryword can be either halfword or memory_word */
1069 fmemoryword *realloc_font_info (int size)
1070 { /* number of memorywords */
1071 fmemoryword *newfontinfo=NULL;
1073 int newsize=0; /* to quieten compiler */
1074 int n=0; /* to quieten compiler */
1077 sprintf(log_line, "Old Address %s == %d\n", "font_info", font_info);
1078 show_line(log_line, 0);
1080 /* during initial allocation, font_info == NULL - realloc acts like malloc */
1081 /* during initial allocation current_font_mem_size == 0 */
1082 if (current_font_mem_size == font_mem_size) { /* if we REALLY run up to limit */
1083 /* memory_error("font", (font_mem_size + 1) * sizeof(memory_word)); */
1085 return font_info; /* pass it back to TeX 99/Fabe/4 */
1087 /* try and prevent excessive frequent reallocations */
1088 /* while avoiding over allocation by too much */
1089 /* minsize = current_font_mem_size / 2; */
1090 minsize = current_font_mem_size / 100 * percent_grow;
1091 if (size < minsize) size = minsize;
1092 if (size < initial_font_mem_size) size = initial_font_mem_size;
1094 for (k=0; k < MAXSPLITS; k++) {
1095 newsize = current_font_mem_size + size;
1096 if (newsize > font_mem_size) newsize = font_mem_size; /* bump against limit */
1097 /* important + 1 since fmemoryword font_info[font_mem_size + 1] original */
1098 n = (newsize + 1) * sizeof (fmemoryword);
1099 if (trace_flag) trace_memory("font_info", n);
1100 newfontinfo = (fmemoryword *) REALLOC (font_info, n);
1101 if (newfontinfo != NULL) break; /* did we get it ? */
1102 if (current_font_mem_size == 0) break; /* initial allocation must work */
1106 if (newfontinfo == NULL) {
1107 memory_error("font", n);
1108 return font_info; /* try and continue !!! */
1110 font_info = newfontinfo;
1112 sprintf(log_line, "New Address %s == %d\n", "font_info", font_info);
1113 show_line(log_line, 0);
1115 update_statistics ((int) font_info, n, current_font_mem_size * sizeof(fmemoryword));
1116 current_font_mem_size = newsize;
1117 if (trace_flag) probe_show (); /* 94/Mar/25 */
1122 #ifdef ALLOCATESTRING
1123 int current_pool_size=0;
1125 packed_ASCII_code *realloc_str_pool (int size)
1130 packed_ASCII_code *newstrpool=NULL;
1133 sprintf(log_line, "Old Address %s == %d\n", "string pool", str_pool);
1134 show_line(log_line, 0);
1136 if (current_pool_size == pool_size) {
1137 /* memory_error ("string pool", (pool_size + 1) * sizeof(packed_ASCII_code)); */
1139 return str_pool; /* pass it back to TeX 99/Fabe/4 */
1141 /* minsize = current_pool_size / 2; */
1142 minsize = current_pool_size / 100 * percent_grow;
1143 if (size < minsize) size = minsize;
1144 if (size < initial_pool_size) size = initial_pool_size;
1146 for (k = 0; k < MAXSPLITS; k++) {
1147 newsize = current_pool_size + size;
1148 if (newsize > pool_size) newsize = pool_size;
1149 /* important + 1 since packed_ASCII_code str_pool[pool_size + 1]; in original */
1150 n = (newsize + 1) * sizeof (packed_ASCII_code);
1151 if (trace_flag) trace_memory("str_pool", n);
1152 newstrpool = (packed_ASCII_code *) REALLOC (str_pool, n); /* 95/Sep/24 */
1153 if (newstrpool != NULL) break; /* did we get it ? */
1154 if (current_pool_size == 0) break; /* initial allocation must work */
1155 size = size / 2; /* else can retry smaller */
1158 if (newstrpool == NULL) {
1159 memory_error("string pool", n);
1160 return str_pool; /* try and continue !!! */
1162 str_pool = newstrpool;
1163 update_statistics ((int) str_pool, n, current_pool_size);
1164 current_pool_size = newsize;
1166 sprintf(log_line, "New Address %s == %d\n", "string pool", str_pool);
1167 show_line(log_line, 0);
1169 if (trace_flag) probe_show (); /* 94/Mar/25 */
1174 #ifdef ALLOCATESTRING
1175 int current_max_strings=0;
1177 pool_pointer *realloc_str_start (int size)
1182 pool_pointer *newstrstart=NULL;
1185 sprintf(log_line, "Old Address %s == %d\n", "string start", str_start);
1186 show_line(log_line, 0);
1188 if (current_max_strings == max_strings) {
1189 /* memory_error ("string pointer", (max_strings + 1) * sizeof(pool_pointer)); */
1191 return str_start; /* pass it back to TeX 99/Fabe/4 */
1193 /* minsize = current_max_strings / 2; */
1194 minsize = current_max_strings / 100 * percent_grow;
1195 if (size < minsize) size = minsize;
1196 if (size < initial_max_strings) size = initial_max_strings;
1198 for (k = 0; k < MAXSPLITS; k++) {
1199 newsize = current_max_strings + size;
1200 if (newsize > max_strings) newsize = max_strings;
1201 /* important + 1 since str_start[maxstring + 1] originally */
1202 n = (newsize + 1) * sizeof (pool_pointer);
1203 if (trace_flag) trace_memory("str_start", n);
1204 newstrstart = (pool_pointer *) REALLOC (str_start, n);
1205 if (newstrstart != NULL) break; /* did we get it ? */
1206 if (current_max_strings == 0) break; /* initial allocation must work */
1207 size = size / 2; /* otherwise can try smaller */
1210 if (newstrstart == NULL) {
1211 memory_error("string pointer", n);
1212 return str_start; /* try and continue */
1214 str_start = newstrstart;
1215 update_statistics((int) str_start, n, current_max_strings * sizeof (pool_pointer));
1216 current_max_strings = newsize;
1218 sprintf(log_line, "New Address %s == %d\n", "string start", str_start);
1219 show_line(log_line, 0);
1221 if (trace_flag) probe_show (); /* 94/Mar/25 */
1228 /* returns -1 if it fails */
1230 int allocate_ini (int size)
1231 { /* size == trie_size */
1232 int n, nl, no, nc, nr, nh, nt;
1233 nh = nr = nl = (size + 1) * sizeof(trie_pointer);
1234 no = (size + 1) * sizeof(trie_op_code);
1235 nc = (size + 1) * sizeof(packed_ASCII_code);
1236 /* nt = (size + 1) * sizeof(bool); */
1237 nt = (size + 1) * sizeof(char);
1238 n = nl + no + nc + nr + nh + nt;
1239 /* n = (size + 1) * (sizeof(packed_ASCII_code) + sizeof(trie_op_code) +
1240 3 * sizeof(trie_pointer) + sizeof (char)); */
1241 if (trace_flag) trace_memory ("iniTeX hyphen trie", n);
1242 trie_l = (trie_pointer *) malloc (roundup(nl));
1243 trie_o = (trie_op_code *) malloc (roundup(no));
1244 trie_c = (packed_ASCII_code *) malloc (roundup(nc));
1245 trie_r = (trie_pointer *) malloc (roundup(nr));
1246 trie_hash = (trie_pointer *) malloc (roundup(nh));
1247 /* trie_taken = (bool *) malloc (nt); */
1248 trie_taken = (char *) malloc (roundup(nt));
1249 if (trie_c == NULL || trie_o == NULL || trie_l == NULL || trie_r == NULL ||
1250 trie_hash == NULL || trie_taken == NULL) {
1251 memory_error("iniTeX hyphen trie", n);
1252 // exit (1); /* serious error */
1256 sprintf(log_line, "Addresses trie_l %d trie_o %d trie_c %d\n",
1257 trie_l, trie_o, trie_c);
1258 show_line(log_line, 0);
1259 sprintf(log_line, "Addresses trie_r %d trie_hash %d trie_taken %d\n",
1260 trie_r, trie_hash, trie_taken);
1261 show_line(log_line, 0);
1263 update_statistics ((int) trie_l, nl, 0);
1264 update_statistics ((int) trie_o, no, 0);
1265 update_statistics ((int) trie_c, nc, 0);
1266 update_statistics ((int) trie_r, nr, 0);
1267 update_statistics ((int) trie_hash, nh, 0);
1268 update_statistics ((int) trie_taken, nt, 0);
1269 /* trie_size = size; */ /* ??? */
1270 if (trace_flag) probe_show (); /* 94/Mar/25 */
1271 return 0; // success
1275 #ifdef ALLOCATESAVESTACK
1276 int current_save_size=0;
1278 memory_word *realloc_save_stack (int size)
1282 memory_word *newsave_stack=NULL;
1285 sprintf(log_line, "Old Address %s == %d\n", "save stack", save_stack);
1286 show_line(log_line, 0);
1288 if (current_save_size == save_size) { /* arbitrary limit */
1289 /* memory_error ("save stack", (save_size + 1) * sizeof(memory_word)); */
1291 return save_stack; /* let TeX handle the error */
1293 minsize = current_save_size / 100 * percent_grow;
1294 if (size < minsize) size = minsize;
1295 if (size < initial_save_size) size = initial_save_size;
1297 for (k = 0; k < MAXSPLITS; k++) {
1298 newsize = current_save_size + size;
1299 if (newsize > save_size) newsize = save_size;
1300 n = (newsize + 1) * sizeof (memory_word); /* save_stack[save_size + 1] */
1301 if (trace_flag) trace_memory("save_stack", n);
1302 newsave_stack = (memory_word *) REALLOC (save_stack, n);
1303 if (newsave_stack != NULL) break; /* did we get it ? */
1304 if (current_save_size == 0) break; /* initial allocation must work */
1305 size = size / 2; /* else can retry smaller */
1308 if (newsave_stack == NULL) {
1309 memory_error("save stack", n);
1310 return save_stack; /* try and continue !!! */
1312 save_stack = newsave_stack;
1313 update_statistics ((int) save_stack, n, current_save_size);
1314 current_save_size = newsize;
1316 sprintf(log_line, "Current%s %d\n", "save_size", current_save_size);
1317 show_line(log_line, 0);
1318 sprintf(log_line, "New Address %s == %d\n", "save stack", save_stack);
1319 show_line(log_line, 0);
1321 if (trace_flag) probe_show (); /* 94/Mar/25 */
1326 #ifdef ALLOCATEINPUTSTACK
1327 int current_stack_size=0; /* input stack size */
1329 in_state_record *realloc_input_stack (int size)
1333 in_state_record *newinputstack=NULL;
1336 sprintf(log_line, "Old Address %s == %d\n", "input stack", input_stack);
1337 show_line(log_line, 0);
1339 if (current_stack_size == stack_size) { /* arbitrary limit */
1340 /* memory_error ("input stack", (stack_size + 1) * sizeof(in_state_record)); */
1344 minsize = current_stack_size / 100 * percent_grow;
1345 if (size < minsize) size = minsize;
1346 if (size < initial_stack_size) size = initial_stack_size;
1348 for (k = 0; k < MAXSPLITS; k++) {
1349 newsize = current_stack_size + size;
1350 if (newsize > stack_size) newsize = stack_size;
1351 n = (newsize + 1) * sizeof (in_state_record); /* input_stack[stack_size + 1] */
1352 if (trace_flag) trace_memory("input_stack", n);
1353 newinputstack = (in_state_record *) REALLOC (input_stack, n);
1354 if (newinputstack != NULL) break; /* did we get it ? */
1355 if (current_stack_size == 0) break; /* initial allocation must work */
1356 size = size / 2; /* else can retry smaller */
1359 if (newinputstack == NULL) {
1360 memory_error("input stack", n);
1361 return input_stack; /* try and continue !!! */
1363 input_stack = newinputstack;
1364 update_statistics ((int) input_stack, n, current_stack_size);
1365 current_stack_size = newsize;
1367 sprintf(log_line, "Current%s %d\n", "stack_size", current_stack_size);
1368 show_line(log_line, 0);
1369 sprintf(log_line, "New Address %s == %d\n", "input stack", input_stack);
1370 show_line(log_line, 0);
1372 if (trace_flag) probe_show (); /* 94/Mar/25 */
1377 #ifdef ALLOCATENESTSTACK
1378 int current_nest_size=0; /* current nest size */
1380 list_state_record *realloc_nest_stack (int size)
1384 list_state_record *newnest=NULL;
1387 sprintf(log_line, "Old Address %s == %d\n", "nest stack", nest);
1388 show_line(log_line, 0);
1390 if (current_nest_size == nest_size) { /* arbitrary limit */
1391 /* memory_error ("nest stack", (nest_size + 1) * sizeof(list_state_record)); */
1393 return nest; /* let TeX handle the error */
1395 minsize = current_nest_size / 100 * percent_grow;
1396 if (size < minsize) size = minsize;
1397 if (size < initial_nest_size) size = initial_nest_size;
1399 for (k = 0; k < MAXSPLITS; k++) {
1400 newsize = current_nest_size + size;
1401 if (newsize > nest_size) newsize = nest_size;
1402 n = (newsize + 1) * sizeof (list_state_record); /* nest[nest_size + 1] */
1403 if (trace_flag) trace_memory("nest stack", n);
1404 newnest = (list_state_record *) REALLOC (nest, n);
1405 if (newnest != NULL) break; /* did we get it ? */
1406 if (current_nest_size == 0) break; /* initial allocation must work */
1407 size = size / 2; /* else can retry smaller */
1410 if (newnest == NULL) {
1411 memory_error("nest stack", n);
1412 return nest; /* try and continue !!! */
1415 update_statistics ((int) nest, n, current_nest_size);
1416 current_nest_size = newsize;
1418 sprintf(log_line, "Current%s %d\n", "nest_size", current_nest_size);
1419 show_line(log_line, 0);
1420 sprintf(log_line, "New Address %s == %d\n", "nest stack", nest);
1421 show_line(log_line, 0);
1423 if (trace_flag) probe_show (); /* 94/Mar/25 */
1428 #ifdef ALLOCATEPARAMSTACK
1429 int current_param_size=0; /* current param size */
1431 halfword *realloc_param_stack (int size)
1435 halfword *newparam=NULL;
1438 sprintf(log_line, "Old Address %s == %d\n", "param stack", param_stack);
1439 show_line(log_line, 0);
1441 if (current_param_size == param_size) { /* arbitrary limit */
1442 /* memory_error ("param stack", (param_size + 1) * sizeof(halfword)); */
1444 return param_stack; /* let TeX handle the error */
1446 minsize = current_param_size / 100 * percent_grow;
1447 if (size < minsize) size = minsize;
1448 if (size < initial_param_size) size = initial_param_size;
1450 for (k = 0; k < MAXSPLITS; k++) {
1451 newsize = current_param_size + size;
1452 if (newsize > param_size) newsize = param_size;
1453 n = (newsize + 1) * sizeof (halfword); /* param_stack[param_size + 1] */
1454 if (trace_flag) trace_memory("param stack", n);
1455 newparam = (halfword *) REALLOC (param_stack, n);
1456 if (newparam != NULL) break; /* did we get it ? */
1457 if (current_param_size == 0) break; /* initial allocation must work */
1458 size = size / 2; /* else can retry smaller */
1461 if (newparam == NULL) {
1462 memory_error("param stack", n);
1463 return param_stack; /* try and continue !!! */
1465 param_stack = newparam;
1466 update_statistics ((int) param_stack, n, current_param_size);
1467 current_param_size = newsize;
1469 sprintf(log_line, "Current%s %d\n", "param_size", current_param_size);
1470 show_line(log_line, 0);
1471 sprintf(log_line, "New Address %s == %d\n", "param stack", param_stack);
1472 show_line(log_line, 0);
1474 if (trace_flag) probe_show (); /* 94/Mar/25 */
1479 #ifdef ALLOCATEBUFFER
1480 int current_buf_size=0;
1482 ASCII_code *realloc_buffer (int size)
1486 ASCII_code *newbuffer=NULL;
1489 sprintf(log_line, "Old Address %s == %d\n", "buffer", buffer);
1490 show_line(log_line, 0);
1492 if (current_buf_size == buf_size) { /* arbitrary limit */
1493 /* memory_error ("buffer", buf_size); */
1495 return buffer; /* pass it back to TeX 99/Fabe/4 */
1497 minsize = current_buf_size / 100 * percent_grow;
1498 if (size < minsize) size = minsize;
1499 if (size < initial_buf_size) size = initial_buf_size;
1501 for (k = 0; k < MAXSPLITS; k++) {
1502 newsize = current_buf_size + size;
1503 if (newsize > buf_size) newsize = buf_size;
1504 n = (newsize + 1) * sizeof(ASCII_code); /* buffer[buf_size + 1] */
1505 if (trace_flag) trace_memory("buffer", n);
1506 newbuffer = (ASCII_code *) REALLOC (buffer, n);
1507 if (newbuffer != NULL) break; /* did we get it ? */
1508 if (current_buf_size == 0) break; /* initial allocation must work */
1509 size = size / 2; /* else can retry smaller */
1512 if (newbuffer == NULL) {
1513 memory_error("buffer", n);
1514 return buffer; /* try and continue !!! */
1517 update_statistics ((int) buffer, n, current_buf_size);
1519 memset(buffer + current_buf_size, 0, newsize - current_buf_size);
1521 for (k = current_buf_size; k < newsize; k++) buffer[k]= 0;
1523 current_buf_size = newsize;
1525 sprintf(log_line, "Current%s %d\n", "buffer", current_buf_size);
1526 show_line(log_line, 0);
1527 sprintf(log_line, "New Address %s == %d\n", "buffer", buffer);
1528 show_line(log_line, 0);
1530 if (trace_flag) probe_show (); /* 94/Mar/25 */
1535 /* we used to allocate this one only to reduce the size of the PE file */
1536 /* not used anymore - NO advantage */
1538 #ifdef ALLOCATEDVIBUF
1539 eight_bits *allocatedvibuf (int size)
1541 eight_bits *dvi_buf;
1544 n = (size + 1) * sizeof(eight_bits);
1545 if (trace_flag) trace_memory("dvi_buf", n);
1546 dvi_buf = (eight_bits *) malloc (roundup(n));
1547 if (dvi_buf == NULL) {
1548 memory_error("dvi_buf", n);
1552 sprintf(log_line, "Address dvi_buf %d\n", dvi_buf);
1553 show_line(log_line, 0);
1555 update_statistics ((int) dvi_buf, n, 0);
1556 if (trace_flag) probe_show (); /* 94/Mar/25 */
1561 /* we used to allocate this one only to reduce the size of the PE file */
1562 /* it can be done without loss in performance, since register eqtb = zeqtb */
1563 #ifdef ALLOCATEZEQTB
1564 memory_word *allocatezeqtb (int k)
1569 n = k * sizeof (memory_word); /* 13507 * 8 = 108 kilobytes */
1570 if (trace_flag) trace_memory("eqtb", n);
1571 zeqtb = (memory_word *) malloc (roundup(n));
1572 if (zeqtb == NULL) {
1573 memory_error("eqtb", n);
1574 // exit (1); /* serious error */
1578 sprintf(log_line, "Address zeqtb %d\n", zeqtb);
1579 show_line(log_line, 0);
1581 update_statistics ((int) zeqtb, n, 0);
1582 if (trace_flag) probe_show (); /* 94/Mar/25 */
1587 /* here is the main memory allocation routine -- calls the above */
1588 /* returns -1 if it fails */
1590 int allocate_memory (void)
1591 { /* allocate rather than static 93/Nov/26 */
1594 char *holeadr = malloc (300000); /* testing - preallocate 95/Jan/20 */
1598 #error ERROR: Not ready for ALLOCATEHASH...
1601 /* probably not worth while/not a good idea allocating following */
1602 /* they are all rather small, and typically don't need expansion */
1603 /* WE ASSUME THIS DOESN'T HAPPEN, SO WON'T BOTHER WITH UPDATESTATISTICS */
1605 /* n = 9767 * sizeof (twohalves); *//* 60 kilo bytes */
1606 /* n = (hash_size + 267) * sizeof (twohalves); */ /* 60 kilo bytes */
1607 /* n = (9767 + eqtb_extra) * sizeof (twohalves); */
1609 n = (hash_size + 267 + eqtb_extra) * sizeof (htwohalves); /* 95/Feb/19 */
1611 n = (hash_size + 267 + eqtb_extra) * sizeof (twohalves); /* 95/Feb/19 */
1613 if (trace_flag) trace_memory("hash table", n);
1615 zzzae = (htwohalves *) malloc (roundup(n));
1617 zzzae = (twohalves *) malloc (roundup(n));
1619 /* zzzae = (twohalves *) malloc ((hash_size + 267) * sizeof (twohalves)); */
1620 if (zzzae == NULL) {
1621 memory_error("hash table", n);
1622 // exit (1); /* serious error */
1623 return -1; /* serious error */
1626 n = (inputsize + 1) * sizeof(memory_word);
1627 if (trace_flag) trace_memory("input_stack", n);
1628 /* input_stack = (memory_word *) malloc ((inputsize + 1) * sizeof (memory_word)); */
1629 input_stack = (memory_word *) malloc (roundup(n));
1630 if (input_stack == NULL) {
1631 memory_error("input_stack", n);
1632 // exit (1); /* serious error */
1633 return -1; /* serious error */
1637 /* no real reason to allocate dvi_buf - no need to ever grow it */
1638 #ifdef ALLOCATEDVIBUF
1639 /* zdvibuf = NULL; */
1640 zdvibuf = allocatedvibuf (dvi_buf_size);
1641 if (zdvibuf == NULL) return -1;
1644 #ifdef ALLOCATEZEQTB
1646 #ifdef INCREASEFONTS
1647 /* zeqtb = allocatezeqtb (13507 + eqtb_extra); */ /* 94/Mar/29 */
1648 zeqtb = allocatezeqtb (hash_size + 4007 + eqtb_extra); /* 94/Mar/29 */
1650 /* zeqtb = allocatezeqtb (13507); */
1651 zeqtb = allocatezeqtb (hash_size + 4007);
1655 #ifdef ALLOCATEINPUTSTACK
1656 input_stack = NULL; /* new 1999/Jan/21 */
1657 current_stack_size = 0;
1658 input_stack = realloc_input_stack (initial_stack_size); /* + 1 */
1661 #ifdef ALLOCATENESTSTACK
1662 nest = NULL; /* new 1999/Jan/21 */
1663 current_nest_size = 0;
1664 nest = realloc_nest_stack (initial_nest_size); /* + 1 */
1667 #ifdef ALLOCATEPARAMSTACK
1668 param_stack = NULL; /* new 1999/Jan/21 */
1669 current_param_size = 0;
1670 param_stack = realloc_param_stack (initial_param_size); /* + 1 */
1673 #ifdef ALLOCATESAVESTACK
1674 save_stack = NULL; /* new 1999/Jan/7 */
1675 current_save_size = 0;
1676 save_stack = realloc_save_stack (initial_save_size);
1680 buffer = NULL; /* need to do earlier */
1681 current_buf_size = 0;
1682 buffer = realloc_buffer (initial_buf_size);
1685 #ifdef ALLOCATESTRING
1687 current_pool_size = 0;
1689 current_max_strings = 0;
1690 /* need to create space because iniTeX writes in before reading pool file */
1691 /* for a start, puts in strings for 256 characters */
1692 /* maybe taylor allocations to actual pool file 1300 strings 27000 bytes ? */
1694 if (trace_flag) show_line("ini TeX pool and string allocation\n", 0);
1695 str_pool = realloc_str_pool (initial_pool_size);
1696 str_start = realloc_str_start (initial_max_strings);
1700 /* the following can save a lot of the usual 800k fixed allocation */
1703 current_font_mem_size = 0;
1704 /* if not iniTeX, then do initial allocation on fmt file read in itex.c */
1705 /* if ini-TeX we need to do it here - no format file read later */
1706 if (is_initex) font_info = realloc_font_info (initial_font_mem_size);
1712 mem_min = mem_bot; /* just to avoid complaints in texbody */
1713 mem_top = mem_initex;
1715 /* allocate main memory here if this is iniTeX */
1716 /* otherwise wait for format undumping in itex.c ... */
1718 /* avoid this if format specified on command line ??? */
1719 /* allocate_main_memory(mem_initex); */ /* made variable ! */
1720 mem = allocate_main_memory(mem_initex); /* made variable ! */
1723 return -1; /* serious error */
1727 /* now for the hyphenation exception stuff */
1728 #ifdef ALLOCATEHYPHEN
1731 /* this will be overridden later by what is in format file */
1732 hyphen_prime = default_hyphen_prime;
1733 /* non ini-TeX use assumes format will be read and that specifies size */
1735 if (new_hyphen_prime) hyphen_prime = new_hyphen_prime;
1736 if (realloc_hyphen (hyphen_prime)) /* allocate just in case no format */
1741 /* now for memory for the part of the hyphenation stuff that always needed */
1742 /* if iniTeX, need to allocate pre-determined fixed amount - trie_size */
1743 /* if iniTeX not selected, allocate only enough later - undump in itex.c ! */
1744 #ifdef ALLOCATETRIES
1746 if (allocate_tries (trie_size)) return -1;
1750 /* now for memory for hyphenation stuff needed only when running iniTeX */
1753 if (allocate_ini(trie_size)) return -1;
1756 trie_l = trie_r = trie_o = trie_hash = NULL; /* (trie_size + 1) * integer */
1757 trie_c = NULL; /* (trie_size + 1) * char */
1758 trie_taken = NULL; /* (trie_size + 1) * bool */
1762 free(holeadr); /* create the hole */
1764 return 0; // success
1767 /* returns non-zero if error - done to test integrity of stack mostly */
1769 int free_memory (void)
1770 { /* free in reverse order 93/Nov/26 */
1772 unsigned heaptotal=0;
1773 /* unsigned total; */
1775 if (trace_flag) show_line("free_memory ", 0);
1778 if (debug_flag) check_eqtb("free_memory");
1780 if (verbose_flag || trace_flag) show_maximums(stdout);
1782 if (heap_flag) (void) heap_dump(stdout, 1);
1786 heaptotal = (void) heap_dump(stdout, 0);
1788 sprintf(log_line, "Heap total: %u bytes --- max address %u\n",
1789 heaptotal, max_address);
1790 show_line(log_line, 0);
1793 sprintf(log_line, "Main Memory: variable node %d (%d - %d) one word %d (%d - %d)\n",
1794 lo_mem_max - mem_min, mem_min, lo_mem_max, mem_end - hi_mem_min, hi_mem_min, mem_end);
1795 show_line(log_line, 0);
1797 /* following only needed to check consistency of heap ... useful debugging */
1798 if (trace_flag) show_line("Freeing memory again\n", 0);
1801 show_line(log_line, "Zero Glue Reference Count %d\n", mem[0].hh.v.RH); */
1803 /* the following checks the heap integrity */
1805 /* if ((n = _heapchk ()) != _HEAPOK) { */ /* 94/Feb/18 */
1807 #ifdef SHOWHEAPERROR
1809 if (n != _HEAPOK) { /* 94/Feb/18 */
1810 sprintf(log_line, "WARNING: Heap corrupted (%d)\n", n);
1811 show_line(log_line, 1);
1812 sprintf(log_line, "HEAP %s (%s)\n", heapstrings[-n], "free_memory");
1813 show_line(log_line, 0);
1814 return n; /* non-zero and negative */ /* unreachable ??? */
1817 /* only free memory if safe ... additional check */
1820 if (trie_taken != NULL) free(trie_taken);
1821 if (trie_hash != NULL) free(trie_hash);
1822 if (trie_r != NULL) free(trie_r);
1823 if (trie_c != NULL) free(trie_c);
1824 if (trie_o != NULL) free(trie_o);
1825 if (trie_l != NULL) free(trie_l);
1827 trie_hash = trie_l = trie_r = NULL;
1832 #ifdef ALLOCATETRIES
1833 if (trietrc != NULL) free (trietrc);
1834 if (trietro != NULL) free (trietro);
1835 if (trietrl != NULL) free (trietrl);
1837 trietro = trietrl = NULL;
1839 #ifdef ALLOCATEHYPHEN
1840 if (hyph_list != NULL) free(hyph_list);
1841 if (hyph_word != NULL) free(hyph_word);
1846 /* if (zzzaa != NULL) free(zzzaa); */ /* NO: zzzaa may be offset ! */
1847 if (mainmemory != NULL) free(mainmemory);
1851 if (font_info != NULL) free(font_info);
1854 #ifdef ALLOCATESTRING
1855 if (str_start != NULL) free(str_start);
1856 if (str_pool != NULL) free(str_pool);
1862 if (zzzae != NULL) free(zzzae);
1866 #ifdef ALLOCATEDVIBUF
1867 if (zdvibuf != NULL) free(zdvibuf);
1870 #ifdef ALLOCATEZEQTB
1871 if (zeqtb != NULL) free(zeqtb);
1875 #ifdef ALLOCATEPARAMSTACK
1876 if (param_stack != NULL) free(param_stack);
1879 #ifdef ALLOCATENESTSTACK
1880 if (nest != NULL) free(nest);
1883 #ifdef ALLOCATEINPUTSTACK
1884 if (input_stack != NULL) free(input_stack);
1887 #ifdef ALLOCATESAVESTACK
1888 if (save_stack != NULL) free(save_stack);
1891 /* if (buffercopy != NULL) free (buffercopy); */ /* 94/Jun/27 */
1892 if (format_file != NULL) free(format_file); /* 96/Jan/16 */
1893 if (string_file != NULL) free(string_file); /* 96/Jan/16 */
1894 if (source_direct != NULL) free(source_direct); /* 98/Sep/29 */
1895 format_file = string_file = source_direct = NULL;
1896 if (dvi_file_name != NULL) free(dvi_file_name);
1897 if (log_file_name != NULL) free(log_file_name);
1898 log_file_name = dvi_file_name = NULL; /* 00/Jun/18 */
1905 int sum = 1; /* 1 + 3 + 5 + k = (k + 1) * (k + 1) / 4 */
1906 if (x % 2 == 0) return false;
1907 for (k = 3; k < x; k = k + 2) {
1908 if (x % k == 0) return false;
1909 /* if (k * k > x) return true; */
1910 if (sum * 4 > x) return true;
1917 bool show_use=false;
1918 bool floating=false;
1920 void complainarg (int c, char *s)
1922 sprintf(log_line, "ERROR: Do not understand `%c' argument value `%s'\n", c, s);
1923 show_line(log_line, 1);
1924 show_use = 1; // 2000 June 21
1927 /* following is list of allowed command line flags and args */
1929 /* char *allowedargs="+vitrdcyzpsqnwbfXABCDFGKLMNOQRSTYWZ?g=m=u=e=o=a=x=k=h=l=u=E=H="; */
1931 /* only 01234567.9 still left to take ... maybe recycle u */
1933 char *allowedargs="+bcdfijnpqrstvwyzABCDFGIJKLMNOPQRSTVWXYZ23456789?a=e=g=h=k=l=m=o=u=x=E=H=P=U=";
1935 /* char takeargs="gmueoazhluEH"; */ /* subset that takes args! needed here */
1937 void reorderargs (int ac, char **av)
1938 { /* put in 1993/Dec/28 */
1941 // char takeargs[128]; /* large enough for all command line arg chars */
1942 char takeargs[256]; /* large enough for all command line arg chars */
1944 /* assumes arg pointers av[] are writeable */
1945 /* for (n = 1; n < ac; n++) sprintf(log_line, "%s ", av[n]); */
1947 if (ac < 3) { /* need more than one arg to reorder anything 94/Feb/25 */
1948 /* show_line("No arguments?\n", 0); */ /* debugging */
1949 return; /* no args ! */
1953 t = takeargs; /* list of those that take args */
1954 while (*s != '\0' && *(s+1) != '\0') {
1955 if (*(s+1) == '=') *t++ = *s++; /* copy over --- without the = */
1960 show_line(takeargs, 0);
1965 for (;;) { /* scan to end of command line args */
1966 if (*av[n] != '-') break;
1967 /* does it take an argument ? and is this argument next ? */
1969 *(av[n]+2) == '\0' &&
1970 /* strchr("gmuhleoxE", *(av[n]+1)) != NULL) */
1971 strchr(takeargs, *(av[n]+1)) != NULL)
1972 n += 2; /* step over it */
1977 for (;;) { /* look for more command line args */
1980 /* while (*av[m] != '-' && m < ac) m++; */ /* first command */
1981 while (m < ac && *av[m] != '-') m++; /* first command */
1983 /* does it take an argument ? and is this argument next ? */
1984 /* check first whether the `-x' is isolated, or arg follows directly */
1985 /* then check whether this is one of those that takes an argument */
1987 *(av[m]+2) == '\0' &&
1988 strchr(takeargs, *(av[m]+1)) != NULL) {
1989 s = av[m]; /* move command down before non-command */
1991 for (; m > n; m--) av[m+1] = av[m-1];
1994 n += 2; /* step over moved args */
1997 s = av[m]; /* move command down before non-command */
1998 for (; m > n; m--) av[m] = av[m-1];
2000 n++; /* step over moved args */
2005 int testalign (int address, int size, char *name)
2008 if (size > 4) n = address % 4;
2009 else n = address % size;
2011 sprintf(log_line, "OFFSET %d (ELEMENT %d) in %s\n", n, size, name);
2012 show_line(log_line, 0);
2017 /* activate detailed checking of alignment when trace_flag is set */
2019 void check_fixed_align (int flag)
2021 if (testalign ((int) &mem_top, 4, "FIXED ALIGNMENT")) {
2022 show_line("PLEASE RECOMPILE ME!\n", 1);
2024 #ifdef CHECKALIGNMENT
2026 testalign ((int) &mem_top, 4, "mem_top");
2027 testalign ((int) &mem_max, 4, "mem_max");
2028 testalign ((int) &mem_min, 4, "mem_min");
2029 testalign ((int) &bad, 4, "bad");
2030 testalign ((int) &trie_size, 4, "trie_size");
2031 testalign ((int) &xord, sizeof(xord[0]), "xord"); /* no op */
2032 testalign ((int) &xchr, sizeof(xchr[0]), "xchr"); /* no op */
2033 testalign ((int) &name_length, 4, "name_length");
2034 testalign ((int) &first, 4, "first");
2035 testalign ((int) &last, 4, "last");
2036 testalign ((int) &max_buf_stack, 4, "max_buf_stack");
2037 testalign ((int) &pool_ptr, 4, "pool_ptr");
2038 testalign ((int) &str_ptr, 4, "str_ptr");
2039 testalign ((int) &init_pool_ptr, 4, "init_pool_ptr");
2040 testalign ((int) &init_str_ptr, 4, "init_str_ptr");
2041 testalign ((int) &log_file, 4, "log_file");
2042 testalign ((int) &tally, 4, "tally");
2043 testalign ((int) &term_offset, 4, "term_offset");
2044 testalign ((int) &file_offset, 4, "file_offset");
2045 testalign ((int) &trick_count, 4, "trick_count");
2046 testalign ((int) &first_count, 4, "first_count");
2047 testalign ((int) &deletions_allowed, 4, "deletions_allowed");
2048 testalign ((int) &set_box_allowed, 4, "set_box_allowed");
2049 testalign ((int) &help_line, sizeof(help_line[0]), "help_line");
2050 testalign ((int) &use_err_help, 4, "use_err_help");
2051 testalign ((int) &interrupt, 4, "interrupt");
2052 testalign ((int) &OK_to_interrupt, 4, "OK_to_interrupt");
2053 testalign ((int) &arith_error, 4, "arith_error");
2054 testalign ((int) &tex_remainder, 4, "tex_remainder");
2055 testalign ((int) &temp_ptr, 4, "temp_ptr");
2056 testalign ((int) &lo_mem_max, 4, "lo_mem_max");
2057 testalign ((int) &hi_mem_min, 4, "hi_mem_min");
2058 testalign ((int) &var_used, 4, "var_used");
2059 testalign ((int) &dyn_used, 4, "dyn_used");
2060 testalign ((int) &avail, 4, "avail");
2061 testalign ((int) &mem_end, 4, "mem_end");
2062 testalign ((int) &mem_start, 4, "mem_start");
2063 testalign ((int) &rover, 4, "rover");
2064 testalign ((int) &font_in_short_display, 4, "font_in_short_display");
2065 testalign ((int) &depth_threshold, 4, "depth_threshold");
2066 testalign ((int) &breadth_max, 4, "breadth_max");
2067 testalign ((int) &nest, sizeof(nest[0]), "nest");
2070 testalign ((int) &zeqtb, sizeof(zeqtb[0]), "zeqtb"); /* not any more ? */
2072 /* testalign ((int) &xeq_level, sizeof(xeq_level[0]), "xeq_level"); */
2073 testalign ((int) &zzzad, sizeof(zzzad[0]), "zzzad");
2074 /* testalign ((int) &hash, sizeof(hash[0]), "hash"); */
2075 testalign ((int) &zzzae, sizeof(zzzae[0]), "zzzae");
2077 testalign ((int) &save_stack, sizeof(save_stack[0]), "save_stack");
2078 testalign ((int) &input_stack, sizeof(input_stack[0]), "input_stack");
2079 testalign ((int) &input_file, sizeof(input_file[0]), "input_file");
2080 testalign ((int) &line_stack, sizeof(line_stack[0]), "line_stack");
2081 testalign ((int) ¶m_stack, sizeof(param_stack[0]), "param_stack");
2082 testalign ((int) &cur_mark, sizeof(cur_mark[0]), "cur_mark");
2083 testalign ((int) &pstack, sizeof(pstack[0]), "pstack");
2084 testalign ((int) &read_file, sizeof(read_file[0]), "read_file");
2086 testalign ((int) &font_check, sizeof(font_check[0]), "font_check");
2087 testalign ((int) &font_size, sizeof(font_size[0]), "font_size");
2088 testalign ((int) &font_dsize, sizeof(font_dsize[0]), "font_dsize");
2089 testalign ((int) &font_params, sizeof(font_params[0]), "font_params");
2090 testalign ((int) &font_name, sizeof(font_name[0]), "font_name");
2091 testalign ((int) &font_area, sizeof(font_area[0]), "font_area");
2092 testalign ((int) &font_bc, sizeof(font_bc[0]), "font_bc");
2093 testalign ((int) &font_ec, sizeof(font_ec[0]), "font_ec");
2094 testalign ((int) &font_glue, sizeof(font_glue[0]), "font_glue");
2095 testalign ((int) &font_used, sizeof(font_used[0]), "font_used");
2096 testalign ((int) &hyphen_char, sizeof(hyphen_char[0]), "hyphen_char");
2097 testalign ((int) &skew_char, sizeof(skew_char[0]), "skew_char");
2098 testalign ((int) &bchar_label, sizeof(bchar_label[0]), "bchar_label");
2099 testalign ((int) &font_bchar, sizeof(font_bchar[0]), "font_bchar");
2100 testalign ((int) &font_false_bchar, sizeof(font_false_bchar[0]), "font_false_bchar");
2101 testalign ((int) &char_base, sizeof(char_base[0]), "char_base");
2102 testalign ((int) &width_base, sizeof(width_base[0]), "width_base");
2103 testalign ((int) &height_base, sizeof(height_base[0]), "height_base");
2104 testalign ((int) &depth_base, sizeof(depth_base[0]), "depth_base");
2105 testalign ((int) &italic_base, sizeof(italic_base[0]), "italic_base");
2106 testalign ((int) &lig_kern_base, sizeof(lig_kern_base[0]), "lig_kern_base");
2107 testalign ((int) &kern_base, sizeof(kern_base[0]), "kern_base");
2108 testalign ((int) &exten_base, sizeof(exten_base[0]), "exten_base");
2109 testalign ((int) ¶m_base, sizeof(param_base[0]), "param_base");
2111 #ifdef ALLOCATEDVIBUF
2112 testalign ((int) &zdvibuf, sizeof(zdvibuf[0]), "zdvibuf"); /* no op */
2114 testalign ((int) &totalstretch, sizeof(totalstretch[0]), "totalstretch");
2115 testalign ((int) &totalshrink, sizeof(totalshrink[0]), "totalshrink");
2116 testalign ((int) &active_width, sizeof(active_width[0]), "active_width");
2117 testalign ((int) &cur_active_width, sizeof(cur_active_width[0]), "cur_active_width");
2118 testalign ((int) &background, sizeof(background[0]), "background");
2119 testalign ((int) &break_width, sizeof(break_width[0]), "break_width");
2120 testalign ((int) &minimal_demerits, sizeof(minimal_demerits[0]), "minimal_demerits");
2121 testalign ((int) &best_place, sizeof(best_place[0]), "best_place");
2122 testalign ((int) &best_pl_line, sizeof(best_pl_line[0]), "best_pl_line");
2123 testalign ((int) &hc, sizeof(hc[0]), "hc");
2124 testalign ((int) &hu, sizeof(hu[0]), "hu");
2125 testalign ((int) &hyf, sizeof(hyf[0]), "hyf");
2126 /* testalign ((int) &x, sizeof(x[0]), "x"); */
2128 testalign ((int) &hyf_distance, sizeof(hyf_distance[0]), "hyf_distance");
2129 testalign ((int) &hyf_num, sizeof(hyf_num[0]), "hyf_num");
2130 testalign ((int) &hyf_next, sizeof(hyf_next[0]), "hyf_next");
2131 testalign ((int) &op_start, sizeof(op_start[0]), "op_start");
2133 /* testalign ((int) &trieophash, sizeof(trieophash[0]), "trieophash"); */
2134 testalign ((int) &zzzaf, sizeof(zzzaf[0]), "zzzaf");
2135 testalign ((int) &trie_used, sizeof(trie_used[0]), "trie_used");
2136 /* testalign ((int) &trie_op_lang, sizeof(trie_op_lang[0]), "trie_op_lang");*/
2137 testalign ((int) &trie_op_val, sizeof(trie_op_val[0]), "trie_op_val");
2139 testalign ((int) &trie_min, sizeof(trie_min[0]), "trie_min");
2140 testalign ((int) &page_so_far, sizeof(page_so_far[0]), "page_so_far");
2141 testalign ((int) &write_file, sizeof(write_file[0]), "write_file");
2142 testalign ((int) &write_open, sizeof(write_open[0]), "write_open");
2146 void check_alloc_align (int flag) {
2147 if (testalign ((int) zeqtb, sizeof(zeqtb[0]), "ALLOCATED ALIGNMENT"))
2148 show_line("PLEASE RECOMPILE ME!\n", 1);
2149 #ifdef CHECKALIGNMENT
2152 testalign ((int) zeqtb, sizeof(zeqtb[0]), "zeqtb");
2154 #ifndef ALLOCATEDVIBUF
2155 testalign ((int) &zdvibuf, sizeof(zdvibuf[0]), "zdvibuf"); /* no op */
2157 testalign ((int) str_pool, sizeof(str_pool[0]), "str_pool"); /* no op */
2158 testalign ((int) str_start, sizeof(str_start[0]), "str_start");
2159 testalign ((int) zmem, sizeof(zmem[0]), "main memory");
2160 testalign ((int) font_info, sizeof(font_info[0]), "font memory");
2161 testalign ((int) trietrl, sizeof(trietrl[0]), "trietrl");
2162 testalign ((int) trietro, sizeof(trietro[0]), "trietro");
2163 testalign ((int) trietrc, sizeof(trietrc[0]), "trietrc");
2164 testalign ((int) hyph_word, sizeof(hyph_word[0]), "hyph_word");
2165 testalign ((int) hyph_list, sizeof(hyph_list[0]), "hyph_list");
2166 /* testalign ((int) trie_c, sizeof(trie_c[0]), "trie_c"); *//* no op */
2167 testalign ((int) trie_o, sizeof(trie_o[0]), "trie_o");
2168 testalign ((int) trie_l, sizeof(trie_l[0]), "trie_l");
2169 testalign ((int) trie_r, sizeof(trie_r[0]), "trie_r");
2170 testalign ((int) trie_hash, sizeof(trie_hash[0]), "trie_hash");
2171 testalign ((int) trie_taken, sizeof(trie_taken[0]), "trie_taken");
2176 void showaddresses (void)
2180 sprintf(log_line, "STACK %d %d (grows %s) ", &c, &d, (&d > &c) ? "upward" : "downward");
2181 show_line(log_line, 0);
2182 sprintf(log_line, "eqtb %d hash %d ", zeqtb, zzzae);
2183 show_line(log_line, 0);
2184 sprintf(log_line, "dvi_buf %d xchr %d xord %d nest %d\n",
2185 zdvibuf, xchr, xord, nest);
2186 show_line(log_line, 0);
2187 sprintf(log_line, "save_stack %d input_stack %d line_stack %d param_stack %d\n",
2188 save_stack, input_stack, line_stack, param_stack);
2189 show_line(log_line, 0);
2190 sprintf(log_line, "font_check %d font_size %d font_dsize %d font_params %d font_name %d\n",
2191 font_check, font_size, font_dsize, font_params, font_name);
2192 show_line(log_line, 0);
2193 sprintf(log_line, "main %d font_info %d str_pool %d str_start %d hyph_word %d hyph_list %d\n",
2194 zmem, font_info, str_pool, str_start, hyph_word, hyph_list);
2195 show_line(log_line, 0);
2199 /* *** *** *** *** *** *** *** NEW APPROACH TO `ENV VARS' *** *** *** *** */
2201 /* grab `env var' from `dviwindo.ini' - or from DOS environment 94/May/19 */
2202 /* controlled by USEDVIWINDOINI environment variable 94/June/19 */
2204 bool usedviwindo = true; /* use [Environment] section in `dviwindo.ini' */
2206 bool backwardflag = false; /* don't cripple all advanced features */
2208 bool shortenfilename = false; /* don't shorten file names to 8+3 for DOS */
2210 char *inifilename = "dviwindo.ini"; /* name of ini file we look for */
2212 char *dviwindo = ""; /* full file name for dviwindo.ini with path */
2214 char *envsection = "[Environment]"; /* Env var section in `dviwindo.ini' */
2216 char *wndsection = "[Window]"; /* Window section in `dviwindo.ini' */
2218 char *workdirect = "WorkingDirectory"; /* key in [Window] section */
2220 bool usesourcedirectory = true; /* use source file directory as local */
2221 /* when WorkingDirectory is set */
2223 bool workingdirectory = false; /* if working directory set in ini */
2225 /* set up full file name for dviwindo.ini and check for [Environment] */
2227 bool setupdviwindo (void)
2228 { /* set up full file name for dviwindo.ini */
2229 char dviwindoini[PATH_MAX];
2230 char line[PATH_MAX];
2233 int em = strlen(envsection);
2234 int wm = strlen(wndsection);
2235 int dm = strlen(workdirect);
2239 /* Easy to find Windows directory if Windows runs */
2240 /* Or if user kindly set WINDIR environment variable */
2241 /* Or if running in Windows NT */
2242 if ((windir = getenv("windir")) != NULL || /* 94/Jan/22 */
2243 (windir = getenv("WINDIR")) != NULL ||
2244 (windir = getenv("winbootdir")) != NULL || /* 95/Aug/14 */
2245 (windir = getenv("SystemRoot")) != NULL || /* 95/Jun/23 */
2246 (windir = getenv("SYSTEMROOT")) != NULL) { /* 95/Jun/23 */
2247 strcpy(dviwindoini, windir);
2248 strcat(dviwindoini, "\\");
2249 strcat(dviwindoini, inifilename);
2250 /* sprintf(log_line, "Using WINDIR %s\n", dviwindoini); */
2253 _searchenv (inifilename, "PATH", dviwindoini);
2254 /* sprintf(log_line, "Using SEARCHENV %s\n", dviwindoini); */
2257 wndflag = envflag = 0;
2258 /* workingdirectory = false; */
2259 if (*dviwindoini != '\0') {
2260 dviwindo = xstrdup(dviwindoini); /* avoid PATH_MAX string */
2261 /* check whether dviwindo.ini actually has [Environment] section */
2262 if (share_flag == 0) input = fopen(dviwindo, "r");
2263 else input = _fsopen(dviwindo, "r", share_flag);
2264 if (input != NULL) {
2265 while (fgets (line, sizeof(line), input) != NULL) {
2266 if (*line == ';') continue;
2267 if (*line == '\n') continue;
2269 if (wndflag && envflag) break; /* escape early */
2271 if (_strnicmp(line, wndsection, wm) == 0) {
2273 sprintf(log_line, "Found %s", line); /* DEBUGGING */
2274 show_line(log_line, 0);
2278 else if (_strnicmp(line, envsection, em) == 0) {
2280 sprintf(log_line, "Found %s", line); /* DEBUGGING */
2281 show_line(log_line, 0);
2283 /* fclose(input); */
2287 else if (wndflag && _strnicmp(line, workdirect, dm) == 0) {
2289 sprintf(log_line, "Found %s", line); /* DEBUGGING */
2290 show_line(log_line, 0);
2292 workingdirectory = true;
2296 (void) fclose(input);
2300 show_line("Failed to find [Environment]", 1); /* DEBUGGING */
2301 (void) fclose(input);
2303 else if (trace_flag) perrormod(dviwindo); /* DEBUGGING */
2304 strcpy(dviwindo, ""); /* failed, for one reason or another */
2309 /* cache to prevent allocating twice in a row */
2311 char *lastname=NULL, *lastvalue=NULL;
2313 /* get value of env var - try first in dviwindo.ini then DOS env */
2314 /* returns allocated string -- these strings are not freed again */
2315 /* is it safe to do that now ? 98/Jan/31 */
2317 char *grabenv (char *varname)
2319 char line[PATH_MAX];
2323 /* int m = strlen(envsection); */
2324 /* int n = strlen(varname); */
2326 if (varname == NULL) return NULL; /* sanity check */
2327 if (*varname == '\0') return NULL; /* sanity check */
2328 /* speedup to avoid double lookup when called from set_paths in ourpaths.c */
2329 /* if (lastname != NULL && strcmp(lastname, varname) == 0) { */
2330 if (lastname != NULL && _strcmpi(lastname, varname) == 0) {
2332 sprintf(log_line, "Cache hit: %s=%s\n", lastname, lastvalue);
2333 show_line(log_line, 0);
2335 /* return lastvalue; */ /* save some time here */
2336 return xstrdup(lastvalue);
2337 /* duplicate so can free safely 98/Jan/31 */
2340 /* hmm, following was not xstrdup(...) */ /* not cached */
2341 if (usedviwindo == 0 || *dviwindo == '\0') {
2342 /* return getenv(varname); */
2343 s = getenv(varname);
2344 if (s == NULL) return NULL;
2345 else return xstrdup(s); /* make safe 98/Jan/31 */
2348 if (share_flag == 0) input = fopen(dviwindo, "r");
2349 else input = _fsopen(dviwindo, "r", share_flag);
2351 if (input != NULL) {
2352 m = strlen(envsection);
2353 /* search for [Environment] section */ /* should be case insensitive */
2354 while (fgets (line, sizeof(line), input) != NULL) {
2355 if (*line == ';') continue;
2356 if (*line == '\n') continue;
2357 if (_strnicmp(line, envsection, m) == 0) { /* 98/Jan/31 */
2358 /* search for varname=... */ /* should be case sensitive ? */
2359 n = strlen(varname);
2360 while (fgets (line, sizeof(line), input) != NULL) {
2361 if (*line == ';') continue;
2362 if (*line == '[') break;
2363 /* if (*line == '\n') break; */ /* ??? */
2364 if (*line <= ' ') continue; /* 95/June/23 */
2365 /* if (strncmp(line, varname, n) == 0 && */
2366 if (_strnicmp(line, varname, n) == 0 &&
2367 *(line+n) == '=') { /* found it ? */
2368 (void) fclose (input);
2369 /* flush trailing white space */
2370 s = line + strlen(line) - 1;
2371 while (*s <= ' ' && s > line) *s-- = '\0';
2372 if (trace_flag) { /* DEBUGGING ONLY */
2373 sprintf(log_line, "%s=%s\n", varname, line+n+1);
2374 show_line(log_line, 0);
2377 if (lastname != NULL) free(lastname);
2378 lastname = xstrdup (varname);
2379 if (lastvalue != NULL) free(lastvalue);
2380 lastvalue = xstrdup(s);
2381 return xstrdup(s); /* 98/Jan/31 */
2382 } /* end of matching varname */
2383 } /* end of while fgets */
2384 /* break; */ /* ? not found in designated section */
2385 } /* end of search for [Environment] section */
2387 (void) fclose (input);
2388 } /* end of if fopen */
2389 s = getenv(varname); /* failed, so try and get from environment */
2390 /* if (s != NULL) return s; */
2392 /* sdup = xstrdup(s); */ /* just to be safe --- 1995/Jan/31 */
2393 if (lastname != NULL) free(lastname);
2394 lastname = xstrdup (varname);
2395 if (lastvalue != NULL) free(lastvalue);
2396 lastvalue = xstrdup(s); /* remember in case asked again ... */
2398 return xstrdup(s); /* 98/Jan/31 */
2400 else return NULL; /* return NULL if not found anywhere */
2403 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2405 void flushtrailingslash (char *directory){
2407 /* flush trailing \ or / in directory, if any 1993/Dec/12 */
2408 if (strcmp(directory, "") != 0) {
2409 s = directory + strlen(directory) - 1;
2410 if (*s == '\\' || *s == '/') *s = '\0';
2414 void knuthify (void)
2416 /* show_current = false; */ /* show ultimate limits */
2417 /* reorder_arg_flag = false; */ /* don't reorder command line */
2418 /* deslash = false; */ /* don't unixify file names */
2419 /* return_flag = false; */ /* don't allow just ^^M termination */
2420 /* trimeof = false; */ /* don't trim ^^Z Ctrl-Z at end of file */
2421 restrict_to_ascii = false; /* don't complain non ASCII */
2422 allow_patterns = false; /* don't allow pattern redefinition */
2423 show_in_hex = true; /* show character code in hex */
2424 show_in_dos = false; /* redundant with previous */
2425 show_numeric = false; /* don't show character code decimal */
2426 show_missing = false; /* don't show missing characters */
2427 civilize_flag = false; /* don't reorder date fields */
2428 c_style_flag = false; /* don't add file name to error msg */
2429 show_fmt_flag = false; /* don't show format file in log */
2430 show_tfm_flag = false; /* don't show metric file in log */
2431 /* font_max = 255; */ /* revert to TeX 82 limit */
2432 /* if you want this, change in tex.h definition of font_max to `int' */
2433 /* and add define FONTMAX 511, and in local.c add font_max = FONTMAX; */
2435 show_line_break_stats = false; /* do not show line break stats */
2436 show_fonts_used = false;
2437 default_rule = 26214; /* revert to default rule thickness */
2438 pseudo_tilde = false;
2439 pseudo_space = false;
2440 show_texinput_flag = false;
2441 truncate_long_lines = false;
2442 allow_quoted_names = false;
2443 show_cs_names = false;
2444 font_dimen_zero = false; /* 98/Oct/5 */
2445 ignore_frozen = false; /* 98/Oct/5 */
2446 suppress_f_ligs = false; /* 99/Jan/5 */
2447 full_file_name_flag = false; // 00 Jun 18
2448 save_strings_flag = false; // 00 Aug 15
2449 knuth_flag = true; /* so other code can know about this */
2450 } /* end of knuthify */
2452 /* following have already been used up */
2454 /* abcdefghijklmnopqrstuvwxyz */
2456 /* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
2460 int nohandler=0; /* experiment to avoid Ctrl-C interrupt handler */
2462 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2464 /* following made global so analyze_flag can be made separate procedure */
2466 // char *xchrfile=""; /* save space use xstrdup */
2467 char *xchrfile = NULL; /* save space use xstrdup */
2468 // char *replfile="";/* save space use xstrdup */
2469 char *replfile = NULL;/* save space use xstrdup */
2471 /* abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ */
2473 /* analyze command line flag or argument */
2474 /* c is the flag letter itself, while optarg is start of arg if any */
2476 /* when making changes, revise allowedargs */
2479 int analyze_flag (int c, char *optarg)
2482 case 'v': want_version = true;
2483 verbose_flag = true;
2485 case 'i': is_initex = true;
2487 case 'Q': interaction = 0; /* quiet mode */
2489 case 'R': interaction = 1; /* run mode */
2491 case 'S': interaction = 2; /* scroll mode */
2493 case 'T': interaction = 3; /* tex mode */
2495 case 'K': backwardflag = true; /* 94/Jun/15 */
2496 knuthify (); /* revert to `standard' Knuth TeX */
2498 case 'L': c_style_flag = true; /* C style error msg 94/Mar/21 */
2500 case 'Z': show_tfm_flag = true; /* show TFM in log file 94/Jun/21 */
2502 case 'c': current_tfm = false; /* not look current dir for TFM */
2504 case 'C': current_flag = false; /* not look current dir for files */
2506 case 'M': show_missing = false; /* do not show missing 94/June/10 */
2508 case 'd': deslash = false; /* flipped 93/Nov/18 */
2509 /* pseudo_tilde = 0; */ /* new 95/Sep/26 */
2511 case 'p': allow_patterns = true; /* 93/Nov/26 */
2512 /* reset_exceptions = true; */ /* 93/Dec/23 */
2514 /* case 'w': show_in_hex = false; */ /* 94/Jan/26 */
2515 case 'w': show_in_hex = true; /* flipped 00/Jun/18 */
2517 case 'j': show_in_dos = true; /* 96/Jan/26 */
2519 case 'n': restrict_to_ascii = true; /* 0 - 127 1994/Jan/21 */
2521 case '6': workingdirectory = true; /* use source dir 98/Sep/29 */
2523 case '7': usesourcedirectory = false; /* use working dir 98/Sep/29 */
2525 case 'f': show_fonts_used = false; /* 97/Dec/24 */
2527 case '8': shortenfilename = true; /* 95/Feb/20 */
2529 case '9': show_cs_names = true; /* 98/Mar/31 */
2531 case '4': ignore_frozen = true; /* 98/Oct/5 */
2533 case '5': font_dimen_zero = false; /* 98/Oct/5 */
2535 case 'F': show_texinput_flag = false; /* 98/Jan/28 */
2537 /* case 'X': truncate_long_lines = false; */ /* 98/Feb/2 */
2539 case 'W': usedviwindo = false; /* 94/May/19 */
2541 case 'J': show_line_break_stats = false; /* 96/Feb/8 */
2543 case 'O': show_fmt_flag = false; /* 94/Jun/21 */
2545 case 'I': format_specific = false; /* 95/Jan/7 */
2547 case '3': encoding_specific = false; /* 98/Oct/5 */
2549 case '2': suppress_f_ligs = true; /* 99/Jan/5 f-lig */
2551 /* following are pretty obscure */
2552 /* case 'y': cache_file_flag = false; */ /* 96/Nov/16 */
2554 /* case 'r': return_flag = false; */ /* flipped 93/Nov/18 */
2556 /* case 'z': trimeof = false; */ /* 93/Nov/24 */
2558 case 'z': full_file_name_flag = false; // 00 Jun 18
2560 case 'X': save_strings_flag = false; // 00 Aug 15
2562 /* following are unannounced options */ /* some may be recycled ... */
2563 case 't': trace_flag = true;
2565 case 'q': quitflag++; /* 93/Dec/16 */
2567 /* The following are really obscure and should not be advertized */
2568 case 's': show_current = false; /* tex8 93/Dec/14 */
2570 case 'N': show_numeric = false; /* 93/Dec/21 */
2572 case 'A': civilize_flag = false; /* 93/Dec/16 */
2574 case 'B': open_trace_flag = true; /* openinou 1994/Jan/8 */
2576 case 'Y': reorder_arg_flag = false; /* local */
2578 case 'b': test_dir_access = false; /* 94/Feb/10 */
2580 case 'D': dir_method = false; /* 94/Feb/10 */
2582 case 'G': file_method = false; /* 94/Feb/13 */
2584 // case 'V': share_flag = _SH_DENYNO; break; /* 0x40 - deny none mode */
2585 /* case 'X': nohandler++; break; */
2586 /* case 'f': waitflush = false; break; */
2587 /* case 'F': floating = true; break; */
2588 /* *********** following command line options take arguments ************** */
2589 case 'm': if (optarg == 0) mem_initex = mem_top; else mem_initex = atoi(optarg) * 1024; /* 93 Dec/1 */
2590 if (mem_initex == 0) complainarg(c, optarg);
2593 #ifdef VARIABLETRIESIZE
2594 case 'h': if (optarg == 0) trie_size = default_trie_size; else trie_size = atoi(optarg); /* 93 Dec/1 */
2595 if (trie_size == 0) complainarg(c, optarg);
2598 #ifdef ALLOCATEHYPHEN
2599 case 'e': if (optarg == 0) new_hyphen_prime = hyphen_prime * 2; else new_hyphen_prime = atoi(optarg); /* 93/Nov/26 */
2600 if (new_hyphen_prime == 0) complainarg(c, optarg);
2603 #ifdef ALLOCATEDVIBUF
2604 case 'u': if (optarg == 0) dvi_buf_size = default_dvi_buf_size; else dvi_buf_size = atoi(optarg); /* 94/Mar/24 */
2605 if (dvi_buf_size == 0) complainarg(c, optarg);
2608 case 'g': if (optarg == 0) percent_grow = 62; else percent_grow = atoi(optarg); /* 93/Dec/11 */
2609 if (percent_grow == 0) complainarg(c, optarg);
2611 case 'U': if (optarg == 0) pseudo_tilde = 0; else pseudo_tilde = atoi(optarg); /* 95/Sep/26 */
2612 if (pseudo_tilde > 255) pseudo_tilde = 255; else if (pseudo_tilde < 128) pseudo_tilde = 128;
2614 /* case 'H': if (optarg == 0) heapthreshold = 1024; else heapthreshold = atoi(optarg);
2615 * if (heapthreshold == 0) complainarg(c, optarg); else heap_flag = 1;
2617 case 'H': if (optarg == 0) tab_step = 8; else tab_step = atoi(optarg); /* 94/July/3 */
2618 if (tab_step == 0) complainarg(c, optarg);
2620 case 'x': if (optarg == 0) xchrfile=xstrdup("xchr.map"); else xchrfile = xstrdup(optarg);
2621 if (xchrfile == NULL || *xchrfile == '\0') complainarg(c, optarg);
2623 case 'k': if (optarg == 0) replfile =xstrdup("repl.key"); else replfile = xstrdup(optarg);
2624 if (replfile == NULL || *replfile == '\0')
2625 complainarg(c, optarg);
2627 /* more obscure stuff - ppssibly recycle */
2628 case 'P': if (optarg == 0) default_rule = 26214; /* 95/Oct/9 */
2629 else default_rule = atoi(optarg); /* 95/Oct/9 */
2630 if (default_rule == 0) complainarg(c, optarg);
2632 case 'E': if (optarg != 0) putenv(optarg); else complainarg(c, optarg);
2634 case 'o': if (optarg == 0) dvi_directory = ""; else dvi_directory = xstrdup(optarg);
2635 if (strcmp(dvi_directory, "") == 0) complainarg(c, optarg);
2637 case 'l': if (optarg == 0) log_directory = ""; else log_directory = xstrdup(optarg);
2638 if (strcmp(log_directory, "") == 0) complainarg(c, optarg);
2640 case 'a': if (optarg == 0) aux_directory = ""; else aux_directory = xstrdup(optarg);
2641 if (strcmp(aux_directory, "") == 0) complainarg(c, optarg);
2644 default : show_use = true;
2645 return -1; // failed to recognize
2651 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2653 /* char *yytexcmd="Y&YTEX.CMD"; */ /* name of command line file */
2655 char *yytexcmd="YANDYTEX.CMD"; /* name of command line file */
2657 /* Try and read default command file - YANDYTEX.CMD */
2658 /* in current directory and then in directory of YANDYTEX */
2659 /* (does not make sense in TeX file directory) */
2660 /* since we don't yet know where that is ! */
2661 /* can't conveniently include this in output file either - not open yet */
2663 /* used both for yytex.cmd and @ indirect command line files */
2664 /* can this be reentered ? */
2666 void extension (char *fname, char *ext)
2667 { /* supply extension if none */
2669 if ((s = strrchr(fname, '.')) == NULL ||
2670 ((t = strrchr(fname, '\\')) != NULL && s < t)) {
2676 /* remove file name - keep only path - inserts '\0' to terminate */
2678 void stripname (char *pathname)
2681 if ((s=strrchr(pathname, '\\')) != NULL);
2682 else if ((s=strrchr(pathname, '/')) != NULL);
2683 else if ((s=strrchr(pathname, ':')) != NULL) s++;
2688 /* char commandfile[PATH_MAX]; */ /* keep around so can open later */
2690 char *programpath=""; /* pathname of program */
2691 /* redundant with texpath ? */
2693 /* The following does not deslashify arguments ? Do we need to ? */
2695 int read_commands (char *filename)
2697 char commandfile[PATH_MAX];
2699 char line[PATH_MAX];
2700 char *linedup; /* need to copy line to preserve args */
2706 /* Try first in current directory (or use full name as specified) */
2707 strcpy(commandfile, filename);
2708 extension(commandfile, "cmd");
2709 if (share_flag == 0) command = fopen(commandfile, "r");
2710 else command = _fsopen(commandfile, "r", share_flag);
2711 if (command == NULL) {
2712 /* If that fails, try in YANDYTeX program directory */
2713 strcpy(commandfile, programpath);
2714 /* don't need fancy footwork, since programpath non-empty */
2715 strcat(commandfile, "\\");
2716 strcat(commandfile, filename);
2717 extension(commandfile, "cmd");
2718 if (share_flag == 0) command = fopen(commandfile, "r");
2719 else command = _fsopen(commandfile, "r", share_flag);
2720 if (command == NULL) {
2721 /* perrormod(commandfile); */ /* debugging only */
2722 /* strcpy(commandfile, ""); */ /* indicate failed */
2723 return 0; /* no command line file YYTEX.CMD */
2727 /* allow for multiple lines --- ignore args that don't start with `-' */
2728 while (fgets(line, PATH_MAX, command) != NULL) {
2729 /* sprintf(log_line, "From %s:\t%s", commandfile, line); */
2730 /* skip over comment lines and blank lines */
2731 if (*line == '%' || *line == ';' || *line == '\n') continue;
2732 if (strchr(line, '\n') == NULL) strcat(line, "\n");
2733 /* sfplogline, rintf("From %s:\t%s", commandfile, line); */
2734 linedup = xstrdup (line); /* 93/Nov/15 */
2735 if (linedup == NULL) {
2736 show_line("ERROR: out of memory\n", 1); /* read_commands */
2738 return -1; // failure
2740 s = strtok(linedup, " \t\n\r"); /* 93/Nov/15 */
2742 if (*s == '-' || *s == '/') {
2745 /* if (*optarg = '=') optarg++; */
2746 if (*optarg == '=') optarg++;
2747 if (analyze_flag(c, optarg) < 0) return -1; // failure ???
2749 /* else break; */ /* ignore non-flag items */
2750 s = strtok(NULL, " \t\n\r"); /* go to next token */
2752 /* If you want to see command lines in file - put -v in the file */
2753 /* if (verbose_flag != 0) sprintf(log_line, "From %s:\t%s", commandfile, line); */
2755 (void) fclose(command); /* no longer needed */
2756 return 1; // success
2759 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
2761 /* try and read commands on command line */
2763 int read_command_line (int ac, char **av)
2766 char *optargnew; /* equal to optarg, unless that starts with `=' */
2767 /* in which case it is optarg+1 to step over the `=' */
2768 /* if optarg = 0, then optargnew = 0 also */
2770 // show_line("read_command_line\n", 0);
2771 if (ac < 2) return 0; /* no args to analyze ? 94/Apr/10 */
2773 /* while ((c = getopt(ac, av, "+vitrdczp?m:h:x:E:")) != EOF) { */
2774 /* NOTE: keep `Y' in there for `do not reorder arguments ! */
2775 /* WARNING: if adding flags, change also `allowedargs' and `takeargs' !!!! */
2776 while ((c = getopt(ac, av, allowedargs)) != EOF) {
2777 if (optarg != 0 && *optarg == '=') optargnew = optarg+1;
2778 else optargnew = optarg;
2779 analyze_flag (c, optargnew);
2781 if (show_use || quitflag == 3) {
2782 // showversion (stdout);
2784 strcat(log_line, "\n");
2785 show_line(log_line, 0);
2786 stampcopy(log_line);
2787 strcat(log_line, "\n");
2788 show_line(log_line, 0);
2789 if (show_use) show_usage(av[0]);
2790 else if (quitflag == 3) {
2791 strcat(log_line, "\n");
2792 show_line(log_line, 0);
2795 return -1; // failure
2799 if (floating) testfloating(); /* debugging */
2802 if (replfile != NULL && *replfile != '\0') { /* read user defined replacement */
2803 if (read_xchr_file(replfile, 1, av)) {
2804 if (trace_flag) show_line("KEY REPLACE ON\n", 0);
2808 /* key_replace used in texmf.c (input_line) */
2810 if (xchrfile != NULL && *xchrfile != '\0') { /* read user defined xchr[] */
2811 if (read_xchr_file(xchrfile, 0, av)) {
2812 if (trace_flag) show_line("NON ASCII ON\n", 0);
2816 /* non_ascii used in texmf.c (t_open_in & input_line & call_edit) */
2817 /* see also xchr [] & xord [] use in tex3.c and itex.c */
2822 void uppercase (char *s) {
2824 while ((c = *s) != '\0') {
2825 /* if (islower(c)) *s = toupper (*s); */
2832 int initcommands (int ac, char **av)
2834 /* NOTE: some defaults changed 1993/Nov/18 */
2835 /* want_version = show_use = switchflag = return_flag = false;
2836 is_initex = trace_flag = deslash = non_ascii = false; */
2837 is_initex = false; /* check for dumping format file */
2838 allow_patterns = false; /* using \pattern after format file loaded */
2839 reset_exceptions = false; /* */
2840 non_ascii = key_replace = false;
2841 want_version = false;
2842 open_trace_flag = trace_flag = verbose_flag = heap_flag = false;
2843 restrict_to_ascii = false;
2844 // show_in_hex = true; /* default is to show as hex code ^^ */
2845 show_in_hex = false; /* default is not to show as hex code ^^ 00/Jun/18 */
2846 show_in_dos = false; /* default is not to translate to DOS 850 */
2847 return_flag = trimeof = true; // hard wired now
2849 pseudo_tilde = 254; /* default '~' replace 95/Sep/26 filledbox DOS 850 */
2850 pseudo_space = 255; /* default ' ' replace 97/June/5 nbspace DOS 850 */
2851 default_rule = 26214; /* default rule variable 95/Oct/9 */
2852 show_current = civilize_flag = show_numeric = show_missing = true;
2853 current_flag = true;
2854 current_tfm = true; /* search for TFMs in current dir as well */
2855 test_dir_access = true; /* test if readable item is perhaps a sub-dir */
2856 dir_method = true; /* in dir_p: _findfirst instead of use fopen (nul) */
2857 file_method = true; /* use file_p (_findfirst) not readable (access) */
2858 /* waitflush = true; */ /* flushed 97/Dec/24 */
2859 c_style_flag = false; /* use c-style error output */
2860 show_fmt_flag = true; /* show format file in log */
2861 show_tfm_flag = false; /* don't show metric file in log */
2862 shortenfilename = false; /* don't shorten file names to 8+3 */
2863 show_texinput_flag = true; /* show TEXINPUTS and TEXFONTS */
2864 truncate_long_lines = true; /* truncate long lines */
2865 tab_step = 0; /* do not replace tabs with spaces */
2866 format_specific = true; /* do format specific TEXINPUTS 95/Jan/7 */
2867 encoding_specific = true; /* do encoding specific TEXFONTS 98/Jan/31 */
2868 show_line_break_stats = true; /* show line break statistics 96/Feb/8 */
2869 show_fonts_used = true; /* show fonts used in LOG file 97/Dec/24 */
2870 allow_quoted_names = true; /* allow quoted names with spaces 98/Mar/15 */
2871 show_cs_names = false; /* don't show csnames on start 98/Mar/31 */
2872 knuth_flag = false; /* allow extensions to TeX */
2873 cache_file_flag = true; /* default is to cache full file names 96/Nov/16 */
2874 full_file_name_flag = true; /* new default 2000 June 18 */
2875 save_strings_flag = true; // 2000 Aug 15
2876 errout = stdout; /* as opposed to stderr say --- used ??? */
2877 abort_flag = 0; // not yet hooked up ???
2878 err_level = 0; // not yet hooked up ???
2880 new_hyphen_prime = 0;
2881 #ifdef VARIABLETRIESIZE
2882 /* trie_size = default_trie_size; */
2885 mem_extra_high = 0; mem_extra_low = 0; mem_initex = 0;
2886 #ifdef ALLOCATEDVIBUF
2889 /* share_flag = _SH_DENYNO; */ /* 0x40 - deny none mode */
2890 /* share_flag = _SH_COMPAT; */ /* 0x00 - compatability mode */
2891 share_flag = 0; /* revert to fopen for now */
2893 /* strncpy(programpath, argv[0], PATH_MAX); */ /* 94/July/12 */
2894 programpath = xstrdup(av[0]); /* extract path executable */
2895 stripname(programpath); /* strip off yandytex.exe */
2897 /* format_name = "PLAIN"; */ /* format name if specified on command line */
2898 format_name = "plain"; /* format name if specified on command line */
2902 if (read_commands(yytexcmd) < 0) /* read yandytex.cmd 1994/July/12 */
2903 return -1; // in case of error
2905 if (read_command_line(ac, av) < 0) /* move out to subr 94/Apr/10 */
2906 return -1; // in case of error
2908 if (optind == 0) optind = ac; /* no arg case paranoia 94/Apr/10 */
2910 /* Print version *after* banner ? */ /* does this get in log file ? */
2912 // showversion (stdout);
2913 // showversion (log_line);
2915 strcat(log_line, "\n");
2916 show_line(log_line, 0);
2917 stampcopy(log_line);
2918 strcat(log_line, "\n");
2919 show_line(log_line, 0);
2921 /* if (show_use) show_usage(av[0]); */ /* show usage and quit */
2923 /* if we aren't including current directory in any directory lists */
2924 /* then makes no sense to avoid them separately for TFM files ... */
2925 /* (that is, the ./ is already omitted from the dir list in that case */
2926 if (!current_flag && !current_tfm) current_tfm = true; /* 94/Jan/24 */
2927 return 0; // success
2930 /* E sets environment variable ? */
2932 void initialmemory (void)
2933 { /* set initial memory allocations */
2934 if (mem_extra_high < 0) mem_extra_high = 0;
2935 if (mem_extra_low < 0) mem_extra_low = 0;
2936 if (mem_initex < 0) mem_initex = 0;
2938 #if defined(ALLOCATEHIGH) || defined(ALLOCATELOW)
2939 if (mem_extra_high != 0 || mem_extra_low != 0) {
2940 show_line("ERROR: Cannot extend main memory in iniTeX\n", 1);
2941 mem_extra_high = 0; mem_extra_low = 0;
2946 if (mem_initex != 0) {
2947 show_line("ERROR: Can only set initial main memory size in iniTeX\n", 1);
2950 if (trie_size != 0) {
2951 show_line("ERROR: Need only set hyphenation trie size in iniTeX\n", 1);
2952 /* trie_size = 0; */
2955 if (mem_initex == 0) mem_initex = default_mem_top;
2956 if (trie_size == 0) trie_size = default_trie_size;
2957 /* Just in case user mistakenly specified words instead of kilo words */
2958 if (mem_extra_high > 10000L * 1024L) mem_extra_high = mem_extra_high / 1024;
2959 if (mem_extra_low > 10000L * 1024L) mem_extra_low = mem_extra_low / 1024;
2960 if (mem_initex > 10000L * 1024L) mem_initex = mem_initex / 1024;
2961 #ifdef ALLOCATEHIGH /* not used anymore */
2962 if (mem_extra_high > 2048L * 1024L) { /* extend SW area by 16 mega byte! */
2964 "WARNING: There may be no benefit to asking for so much memory\n", 0);
2965 mem_extra_high = 2048 * 1024; /* limit to SW to 4 x VLR */
2968 #ifdef ALLOCATELOW /* not used anymore */
2969 if (mem_extra_low > 2048L * 1024L) { /* extend VL area by 16 mega byte! */
2971 "WARNING: There may be no benefit to asking for so much memory\n", 0);
2972 mem_extra_low = 2048 * 1024; /* limit VLR to 4 x SW */
2975 if (mem_initex > 2048L * 1024L) { /* extend main memory by 16 mega byte! */
2977 "WARNING: There may be no benefit to asking for so much memory\n", 0);
2978 /* mem_initex = 2048 * 1024; */
2980 #ifdef ALLOCATEDVIBUF
2981 if (dvi_buf_size == 0) dvi_buf_size = default_dvi_buf_size;
2982 /* if less than 1024 assume user specified kilo-bytes, not bytes */
2983 if (dvi_buf_size < 1024) dvi_buf_size = dvi_buf_size * 1024;
2984 if (dvi_buf_size % 8 != 0) /* check multiple of eight */
2985 dvi_buf_size = (dvi_buf_size / 8 + 1) * 8;
2987 if (new_hyphen_prime < 0) new_hyphen_prime = 0;
2988 if (new_hyphen_prime > 0) {
2990 show_line("ERROR: Can only set hyphen prime in iniTeX\n", 1);
2992 if (new_hyphen_prime % 2 == 0) new_hyphen_prime++;
2993 while (!prime(new_hyphen_prime)) new_hyphen_prime = new_hyphen_prime+2;
2995 sprintf(log_line, "Using %d as hyphen prime\n", new_hyphen_prime);
2996 show_line(log_line, 0);
3001 if (percent_grow > 100) percent_grow = percent_grow - 100;
3002 if (percent_grow > 100) percent_grow = 100; /* upper limit - double */
3003 if (percent_grow < 10) percent_grow = 10; /* lower limit - 10% */
3006 /**********************************************************************/
3008 void perrormod (char *s)
3010 sprintf(log_line, "`%s': %s\n", s, strerror(errno));
3011 show_line(log_line, 1);
3017 fflush(stdout); /* ??? */
3018 fflush(stderr); /* ??? */
3019 (void) _getch(); /* ??? */
3023 void checkpause (int flag)
3027 /* don't stop if in Q (quiet) or R (run) mode */
3028 /* stop only in S (scroll) and T (TeX) mode */
3029 if (interaction >= 0 && interaction < 2) flag = 0; /* 98/Jun/30 */
3030 s = grabenv("DEBUGPAUSE");
3031 if (s != NULL) sscanf(s, "%d", &debugpause);
3032 if (flag < 0) return;
3034 // if ((debugpause > 1) || flag) {
3035 if (debugpause || flag > 0) {
3038 show_line("Press any key to continue . . .\n", 0);
3045 void checkenter (int argc, char *argv[])
3048 char current[FILENAME_MAX];
3049 if (grabenv ("DEBUGPAUSE") != NULL) {
3050 (void) _getcwd(current, sizeof(current));
3051 sprintf(log_line, "Current directory: `%s'\n", current);
3052 show_line(log_line, 0);
3053 for (m = 0; m < argc; m++) {
3054 // sprintf(log_line, "%2d:\t`%s'\n", m, argv[m]);
3055 sprintf(log_line, "%2d: `%s'\n", m, argv[m]);
3056 show_line(log_line, 0);
3064 void checkexit (int n) { /* 95/Oct/28 */
3070 /*************************************************************************/
3072 /* convert tilde to pseudo_tilde to hide it from TeX --- 95/Sep/26 */
3073 /* convert space to pseudo_space to hide it from TeX --- 97/Jun/5 */
3074 /* called only if pseudo_tilde != 0 or pseudo_space != 0 */
3075 /* this is then undone in tex3.c both for fopen input and output */
3076 /* not ideal, since pseudo name appears in log and in error messages ... */
3078 void hidetwiddle (char *name)
3083 sprintf(log_line, "Hidetwiddle %s", name);
3084 show_line(log_line, 0);
3087 /* while (*s != '\0' && *s != ' ') { */
3088 while (*s != '\0') {
3089 if (*s == '~' && pseudo_tilde != 0)
3090 *s = (char) pseudo_tilde; /* typically 254 */
3091 else if (*s == ' ' && pseudo_space != 0)
3092 *s = (char) pseudo_space; /* typically 255 */
3097 sprintf(log_line, "=> %s\n", name);
3098 show_line(log_line, 0);
3103 void deslashall (int ac, char **av)
3105 char buffer[PATH_MAX];
3108 if ((s = getenv("USEDVIWINDOINI")) != NULL)
3109 sscanf(s, "%d", &usedviwindo); /* 94/June/14 */
3111 if (usedviwindo) setupdviwindo(); // moved to yandytex ?
3113 checkenter(ac, av); /* 95/Oct/28 */
3115 /* environment variables for output directories (as in PC TeX) */
3117 /* if ((s = getenv("TEXDVI")) != NULL) dvi_directory = s; */
3118 if ((s = grabenv("TEXDVI")) != NULL) dvi_directory = s;
3119 /* if ((s = getenv("TEXLOG")) != NULL) log_directory = s; */
3120 if ((s = grabenv("TEXLOG")) != NULL) log_directory = s;
3121 /* if ((s = getenv("TEXAUX")) != NULL) aux_directory = s; */
3122 if ((s = grabenv("TEXAUX")) != NULL) aux_directory = s;
3124 strcpy(buffer, av[0]); /* get path to executable */
3125 if ((s = strrchr(buffer, '\\')) != NULL) *(s+1) = '\0';
3126 else if ((s = strrchr(buffer, '/')) != NULL) *(s+1) = '\0';
3127 else if ((s = strrchr(buffer, ':')) != NULL) *(s+1) = '\0';
3128 s = buffer + strlen(buffer) - 1;
3129 if (*s == '\\' || *s == '/') *s = '\0'; /* flush trailing PATH_SEP */
3130 texpath = xstrdup(buffer);
3132 /* Hmm, we may be operating on DOS environment variables here !!! */
3134 if (strcmp(dvi_directory, "") != 0) flushtrailingslash (dvi_directory);
3135 if (strcmp(log_directory, "") != 0) flushtrailingslash (log_directory);
3136 if (strcmp(aux_directory, "") != 0) flushtrailingslash (aux_directory);
3139 unixify (texpath); /* 94/Jan/25 */
3140 /* if output directories given, deslashify them also 1993/Dec/12 */
3141 if (strcmp(dvi_directory, "") != 0) unixify(dvi_directory);
3142 if (strcmp(log_directory, "") != 0) unixify(log_directory);
3143 if (strcmp(aux_directory, "") != 0) unixify(aux_directory);
3146 /* deslash TeX source file (and format, if format specified) */
3147 /* and check args to see whether format was specified */
3150 /* NOTE: assuming that command line arguments are in writable memory ! */
3151 /* if (trace_flag || debug_flag)
3152 sprintf(log_line, "optind %d ac %d\n", optind, ac); */ /* debugging */
3153 /* if (optind < ac) { */ /* bkph */
3154 if (optind < ac && optind > 0) { /* paranoia 94/Apr/10 */
3156 if (trace_flag || debug_flag) {
3157 sprintf(log_line, "deslash: k %d argv[k] %s (argc %d)\n",
3158 optind, av[optind], ac);
3159 show_line(log_line, 0);
3161 unixify(av[optind]);
3163 if (pseudo_tilde != 0 || pseudo_space != 0)
3164 hidetwiddle (av[optind]); /* 95/Sep/25 */
3165 /* if (*av[optind] == '&') { */ /* 95/Jan/22 */
3166 /* For Windows NT, lets allow + instead of & for format specification */
3167 if (*av[optind] == '&' || *av[optind] == '+') {
3168 format_spec = 1; /* format file specified */
3169 format_name = xstrdup(av[optind]+1); /* 94/Oct/25 */
3170 /* uppercase (format_name); */ /* why ? 98/Jan/31 */
3171 if (optind + 1 < ac) {
3173 if (trace_flag || debug_flag) {
3174 sprintf(log_line, "deslash: k %d argv[k] %s (argc %d)\n",
3175 optind+1, av[optind+1], ac);
3176 show_line(log_line, 0);
3178 unixify(av[optind+1]);
3180 if (pseudo_tilde != 0 || pseudo_space != 0)
3181 hidetwiddle (av[optind+1]); /* 95/Sep/25 */
3187 /* The above seems to assume that arguments that don't start with '-' */
3188 /* are file names or format names - what if type in control sequences? */
3190 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
3192 /* interaction == 0 => batch mode (omit all stops and omit terminal output) */
3193 /* interaction == 1 => nonstop mode (omit all stops) */
3194 /* interaction == 2 => scroll mode (omit error stops) */
3195 /* interaction == 3 => error_stop mode (stops at every opportunity) */
3197 /* main entry point follows */
3199 /* this gets called pretty much right away in `main' in texmf.c */
3201 /* note: those optarg == 0 test don't really work ... */
3202 /* note: optarg starts at = in case of x=... */
3204 int init (int ac, char **av)
3206 char initbuffer[PATH_MAX];
3209 debugfile = getenv("TEXDEBUG"); /* 94/March/28 */
3210 if (debugfile) debug_flag = 1;
3211 else debug_flag = 0;
3213 show_line("TEXDEBUG\n", 0);
3214 trace_flag = 1; /* 94/April/14 */
3217 if (sizeof(memory_word) != 8) { /* compile time test */
3218 sprintf(log_line, "ERROR: Bad word size %d!\n", sizeof(memory_word));
3219 show_line(log_line, 1);
3222 start_time = clock(); /* get time */
3223 main_time = start_time; /* fill in, in case file never opened */
3225 initbuffer[0] = '\0'; /* paranoia 94/Apr/10 */
3227 /* reset all allocatable memory pointers to NULL - in case we drop out */
3232 #ifdef ALLOCATEZEQTB
3238 #ifdef ALLOCATESAVESTACK
3241 #ifdef ALLOCATEDVIBUF
3244 #ifdef ALLOCATEBUFFER
3245 buffer = NULL; /* new 1999/Jan/7 need to do early */
3246 current_buf_size = 0;
3247 buffer = realloc_buffer (initial_buf_size);
3248 /* sprintf(log_line, "buffer %x, current_buf_size %d\n", buffer, current_buf_size); */
3250 hyph_list = NULL; hyph_word = NULL;
3251 trie_taken = NULL; trie_hash = NULL;
3252 trie_r = NULL; trie_c = NULL; trie_o = NULL; trie_l = NULL;
3253 trietrc = NULL; trietro = NULL; trietrl = NULL;
3255 log_opened = false; /* so can tell whether opened */
3256 interaction = -1; /* default state => 3 */
3257 missing_characters=0; /* none yet! */
3258 workingdirectory = false; /* set from dviwindo.ini & command line */
3259 font_dimen_zero = true; /* \fontdimen0 for checksum 98/Oct/5 */
3260 ignore_frozen = false; /* default is not to ignore 98/Oct/5 */
3261 suppress_f_ligs = false; /* default is not to ignore f-ligs */
3262 /* if (*av[1] == '-Y') reorder_arg_flag = false; */ /* 94/April/14 */
3263 if (ac > 1 && *av[1] == '-Y') reorder_arg_flag = false;
3265 if (reorder_arg_flag) reorderargs(ac, av);
3267 if (initcommands(ac, av))
3268 return -1; // failure
3270 check_fixed_align(trace_flag); /* sanity check 1994/Jan/8 */
3272 format_file = NULL; /* to be set in openinou.c 94/Jun/21 */
3273 string_file = NULL; /* to be set in openinou.c 96/Jan/15 */
3274 source_direct = NULL; /* to be set in openinou.c 98/Sep/29 */
3275 dvi_file_name = NULL; /* to be set in openinou.c 00/Jun/18 */
3276 log_file_name = NULL; /* to be set in openinou.c 00/Jun/18 */
3278 first_pass_count = second_pass_count = final_pass_count = 0; /* 96/Feb/9 */
3279 paragraph_failed = singleline = 0; /* 96/Feb/9 */
3280 overfull_hbox = underfull_hbox = overfull_vbox = underfull_vbox = 0;
3282 closed_already=0; // so can only do once
3284 if (trace_flag) show_line("Entering init (local)\n", 0);
3286 /* Print version *after* banner ? */ /* does this get in log file ? */
3288 probe_memory (); /* show top address */
3289 ini_max_address = max_address; /* initial max address */
3290 if (trace_flag) show_maximums(stdout);
3292 if (heap_flag) (void) heap_dump(stdout, 1);
3297 deslashall (ac, av); /* deslash and note if format specified */
3299 /* sprintf(log_line, "%s\n", initbuffer); */ /* debugging, remove later */
3303 if (format_spec && mem_spec_flag) {
3304 show_line("WARNING: Cannot change initial main memory size when format specified", 1);
3307 if (allocate_memory() != 0) /* NOW, try and ALLOCATE MEMORY if needed */
3308 return -1; // if failed to allocate
3310 /* following is more or less useless since most all things not yet alloc */
3311 check_alloc_align(trace_flag); /* sanity check 1994/Jan/8 */
3313 if (trace_flag) showaddresses(); /* debugging only 1996/Jan/20 */
3317 /* if (heap_flag) heap_dump(stdout, 1); */ /* redundant ? */
3320 if (trace_flag) show_line("Leaving init (local)\n", 0);
3321 return 0; // success
3324 /* #define CLOCKS_PER_SEC 1000 */ /* #define CLK_TCK CLOCKS_PER_SEC */
3326 /* void show_inter_val (clock_t start, clock_t end) { */
3327 void show_inter_val (clock_t interval)
3329 /* clock_t interval; */
3330 /* int seconds, tenths; */
3331 /* int seconds, tenths, hundredth; */
3332 int seconds, tenths, hundredth, thousands;
3333 /* interval = end - start; */
3334 /* sanity check whether positive ? */
3335 if (interval >= CLK_TCK * 10) {
3336 tenths = (interval * 10 + CLK_TCK / 2) / CLK_TCK;
3337 seconds = tenths / 10;
3338 tenths = tenths % 10;
3339 sprintf(log_line, "%d.%d", seconds, tenths);
3340 show_line(log_line, 0);
3342 else if (interval >= CLK_TCK) { /* 94/Feb/25 */
3343 hundredth = (interval * 100 + CLK_TCK / 2) / CLK_TCK;
3344 seconds = hundredth / 100;
3345 hundredth = hundredth % 100;
3346 sprintf(log_line, "%d.%02d", seconds, hundredth);
3347 show_line(log_line, 0);
3349 else if (interval > 0) { /* 94/Oct/4 */
3350 thousands = (interval * 1000 + CLK_TCK / 2) / CLK_TCK;
3351 seconds = thousands / 1000;
3352 thousands = thousands % 1000;
3353 sprintf(log_line, "%d.%03d", seconds, thousands);
3354 show_line(log_line, 0);
3356 else show_line("0", 0); /* 95/Mar/1 */
3359 /* final cleanup opportunity */ /* flag is non-zero if error exit */
3360 /* shows various times, warning about missing chars */
3362 int endit (int flag)
3365 finish_time = clock();
3366 if (missing_characters != 0) flag = 1;
3367 if (missing_characters) {
3369 "! There %s %d missing character%s --- see log file\n",
3370 (missing_characters == 1) ? "was" : "were", missing_characters,
3371 (missing_characters == 1) ? "" : "s");
3372 show_line(log_line, 0);
3374 if (free_memory() != 0) flag++;
3376 /* show per page time also ? */
3378 /* sprintf(log_line, "start %ld main %ld finish %ld\n",
3379 start_time, main_time, finish_time); */
3380 show_line("Total ", 0);
3381 /* show_inter_val(start_time, finish_time); */
3382 show_inter_val(finish_time - start_time);
3383 show_line(" sec (", 0);
3384 /* show_inter_val(start_time, main_time); */
3385 show_inter_val(main_time - start_time);
3386 show_line(" format load + ", 0);
3387 /* show_inter_val(main_time, finish_time); */
3388 show_inter_val(finish_time - main_time);
3389 show_line(" processing) ", 0);
3390 if (total_pages > 0) {
3391 /* msec = (finish_time - main_time) * 1000 / (CLK_TCK * total_pages); */
3392 /* sprintf(log_line, " %d.%d sec per page", msec / 1000, msec % 1000); */
3393 /* sprintf(log_line, " %d.%03d sec per page", msec / 1000, msec % 1000); */
3394 show_inter_val ((finish_time - main_time) / total_pages);
3395 show_line(" sec per page", 0);
3405 /********************************************************************************/
3407 /* addition 98/Mar/31 print_csnames Frank Mittelbach */
3411 #define MAXCOLUMN 78
3413 void print_cs_name (FILE *output, int h)
3418 textof = hash[h].v.RH;
3419 if (textof == 0) return; /* ignore if text() == 0 */
3420 n = str_start[textof+1] - str_start[textof];
3421 if (textcolumn != 0) {
3422 sprintf(log_line, ", ");
3423 if (output != NULL) fprintf(output, log_line);
3424 else show_line(log_line, 0);
3427 if (textcolumn + n + 2 >= MAXCOLUMN) {
3428 sprintf(log_line, "\n");
3429 if (output == stderr) show_line(log_line, 1);
3430 else if (output == stdout) show_line(log_line, 0);
3431 else fputs(log_line, output);
3435 for (c = str_start[textof]; c < str_start[textof+1]; c++) {
3438 if (output == stderr) show_line(log_line, 1);
3439 else if (output == stdout) show_line(log_line, 0);
3440 else fprintf(output, log_line);
3444 int comparestrn (int, int, int, int); /* in tex9.c */
3446 /* compare two csnames in qsort */
3448 int comparecs (const void *cp1, const void *cp2)
3450 int c1, c2, l1, l2, k1, k2, textof1, textof2;
3453 textof1 = hash[c1].v.RH;
3454 textof2 = hash[c2].v.RH;
3455 l1 =(str_start[textof1 + 1] - str_start[textof1]);
3456 l2 =(str_start[textof2 + 1] - str_start[textof2]);
3457 k1 = str_start[textof1];
3458 k2 = str_start[textof2];
3459 /* showstring (k1, l1); */
3460 /* showstring (k2, l2); */
3461 return comparestrn (k1, l1, k2, l2);
3466 /* Allocate table of indeces to allow sorting on csname */
3467 /* Allocate flags to remember which ones already listed at start */
3469 void print_cs_names (FILE *output, int pass)
3471 int h, k, ccount, repeatflag;
3473 int hash_base = 514; /* 1 act base + 256 act char + 256 single char + 1 */
3474 int nfcs = hash_base + hash_size + hash_extra; /* frozen_control_sequence */
3476 if (pass == 0 && csused == NULL) {
3477 csused = malloc (nfcs);
3478 if (csused == NULL) return;
3480 memset(csused, 0, nfcs);
3482 for (h = 0; h < (hash_size+780); h++) csused[h] = 0;
3487 for (h = hash_base+1; h < nfcs; h++) {
3488 if (pass == 1 && csused[ h]) continue;
3489 if(hash[h].v.RH != 0) {
3490 if (pass == 0) csused[ h] = 1;
3495 sprintf(log_line, "\n%d %s multiletter control sequences:\n\n",
3496 ccount, (pass == 1) ? "new" : "");
3497 if (output == stderr) show_line(log_line, 1);
3498 else if (output == stdout) show_line(log_line, 0);
3499 else fprintf(output, log_line);
3501 if (ccount > 0) { /* don't bother to get into trouble */
3503 cnumtable = (int *) malloc (ccount * sizeof(int));
3504 if (cnumtable == NULL) return;
3507 /* for (h = 515; h < (hash_size + 780); h++) { */
3508 for (h = hash_base+1; h < nfcs; h++) {
3509 if (pass == 1 && csused[ h]) continue;
3510 if(hash[h].v.RH != 0) cnumtable[ccount++] = h;
3513 qsort ((void *)cnumtable, ccount, sizeof (int), &comparecs);
3516 for (k = 0; k < ccount; k++) {
3518 if (pass == 1 && csused[ h]) continue;
3519 print_cs_name(output, h);
3521 sprintf(log_line, "\n");
3522 if (output == stderr) show_line(log_line, 1);
3523 else if (output == stdout) show_line(log_line, 0);
3524 else fprintf(output, log_line);
3525 free((void *)cnumtable);
3528 if (pass == 1 && csused != NULL) {
3534 /***************** font info listing moved from TEX9.C ******************/
3536 void showstring (int k, int l)
3539 while (l-- > 0) *s++ = str_pool[k++];
3542 show_line(log_line, 0);
3545 /* compare two strings in str_pool (not null terminated) */
3546 /* k1 and k2 are positions in string pool */
3547 /* l1 and l2 are lengths of strings */
3549 int comparestrn (int k1, int l1, int k2, int l2)
3552 /* while (l1-- > 0 && l2-- > 0) { */
3553 while (l1 > 0 && l2 > 0) {
3556 /* sprintf(log_line, "%c%d%c%d ", c1, l1, c2, l2); */
3557 if (c1 > c2) return 1;
3558 else if (c2 > c1) return -1;
3562 if (l1 > 0) return 1; /* first string longer */
3563 else if (l2 > 0) return -1; /* second string longer */
3564 return 0; /* strings match */
3567 /* compare two font names and their at sizes in qsort */
3569 int comparefnt (const void *fp1, const void *fp2)
3571 int f1, f2, l1, l2, k1, k2, s;
3574 l1 =(str_start[font_name[f1]+ 1]-
3575 str_start[font_name[f1]]);
3576 l2 =(str_start[font_name[f2]+ 1]-
3577 str_start[font_name[f2]]);
3578 k1 = str_start[font_name[f1]];
3579 k2 = str_start[font_name[f2]];
3580 /* showstring (k1, l1); */
3581 /* showstring (k2, l2); */
3582 s = comparestrn (k1, l1, k2, l2);
3583 /* sprintf(log_line, "%d\n", s); */
3584 if (s != 0) return s;
3585 if (font_size[f1]> font_size[f2]) return 1;
3586 else if (font_size[f1]< font_size[f2]) return -1;
3587 return 0; /* should not ever get here */
3590 /* compare two font names */
3592 int comparefntname (int f1, int f2)
3594 int l1, l2, k1, k2, s;
3595 l1 =(str_start[font_name[f1]+ 1]-
3596 str_start[font_name[f1]]);
3597 l2 =(str_start[font_name[f2]+ 1]-
3598 str_start[font_name[f2]]);
3599 k1 = str_start[font_name[f1]];
3600 k2 = str_start[font_name[f2]];
3601 /* showstring (k1, l1); */
3602 /* showstring (k2, l2); */
3603 s = comparestrn (k1, l1, k2, l2);
3604 /* sprintf(log_line, "%d\n", s); */
3608 /* decode checksum information */
3610 unsigned long checkdefault = 0x59265920; /* default signature */
3612 int decode_fourty (unsigned long checksum, char *codingvector)
3616 /* char codingvector[6+1]; */
3618 /* if (checksum == checkdefault) { */
3619 if (checksum == 0) {
3620 /* strcpy(codingvector, "unknown"); */
3621 strcpy(codingvector, "unknwn");
3624 else if ((checksum >> 8) == (checkdefault >> 8)) { /* last byte random */
3625 /* strcpy (codingvector, "native"); */ /* if not specified ... */
3626 strcpy (codingvector, "fixed "); /* if not specified ... */
3627 return 1; /* no info available */
3630 for (k = 0; k < 6; k++) {
3631 c = (int) (checksum % 40);
3632 checksum = checksum / 40;
3633 if (c <= 'z' - 'a')c = c + 'a';
3634 else if (c < 36) c = (c + '0') - ('z' - 'a') - 1;
3635 else if (c == 36) c = '-';
3636 else if (c == 37) c = '&';
3637 else if (c == 38) c = '_';
3638 else c = '.'; /* unknown */
3639 codingvector[5-k] = (char) c;
3641 codingvector[6] = '\0';
3643 /* sprintf(log_line, "Reconstructed vector %s\n", codingvector); */
3644 return 0; /* encoding info returned in codingvector */
3647 double sclpnt (long x)
3650 pt = (double) x / 65536.0;
3651 pt = (double) ((int) (pt * 1000.0 + 0.5)) / 1000.0;
3655 // Shows list of fonts in log file
3657 void dvi_font_show(internal_font_number f, int suppressname)
3659 int a, l, k, n, for_end;
3660 unsigned long checksum;
3661 char checksumvector[8];
3664 /* fprintf (log_file, "DAMN! %d ", suppressname); */
3665 /* fprintf (log_file, "%d ", suppressname); */
3666 /* suppressname = 0; */
3667 putc(' ', log_file);
3668 if (suppressname == 0) {
3669 a = (str_start[font_area[f]+ 1]- str_start[font_area[f]]);
3670 l = (str_start[font_name[f]+ 1]- str_start[font_name[f]]);
3671 k = str_start[font_area[f]];
3672 for_end = str_start[font_area[f]+ 1]- 1;
3673 if(k <= for_end) do {
3674 putc(str_pool[k], log_file);
3675 } while(k++ < for_end, stdout);
3676 k = str_start[font_name[f]];
3677 for_end = str_start[font_name[f]+ 1]- 1;
3678 if(k <= for_end) do {
3679 putc(str_pool[k], log_file);
3680 } while(k++ < for_end);
3683 for (k = a+l; k < 16; k++) putc(' ', log_file);
3684 sprintf(buffer, "at %lgpt ", sclpnt(font_size[f]));
3685 fputs(buffer, log_file);
3686 // fprintf(log_file, "at %lgpt ", sclpnt(font_size[f]));
3687 if (suppressname == 0) {
3689 // n = strlen(log_file);
3690 for (k = n; k < 16; k++) putc(' ', log_file);
3691 checksum = (((font_check[f].b0) << 8 | font_check[f].b1) << 8 |
3692 font_check[f].b2) << 8 | font_check[f].b3;
3693 decode_fourty(checksum, checksumvector);
3694 fprintf(log_file, "encoding: %s..", checksumvector);
3696 putc('\n', log_file);
3699 /* Allocate table of indeces to allow sorting on font name */
3701 void show_font_info (void)
3703 int k, m, fcount, repeatflag;
3707 for (k = 1; k <= font_ptr; k++)
3708 if(font_used[k])fcount++;
3710 if (fcount == 0) return; /* don't bother to get into trouble */
3712 fnumtable = (short *) malloc (fcount * sizeof(short));
3714 /* if (verbose_flag) sprintf(log_line, "\nUsed %d fonts:\n", fcount); */
3716 fprintf(log_file, "\nUsed %d font%s:\n",
3717 fcount, (fcount == 1) ? "" : "s");
3720 for (k = 1; k <= font_ptr; k++)
3721 if(font_used[k])fnumtable[fcount++] = (short) k;
3723 qsort ((void *)fnumtable, fcount, sizeof (short), &comparefnt);
3726 for (m = 0; m < fcount; m++) {
3728 if (comparefntname(fnumtable[m-1], fnumtable[m]) == 0)
3730 else repeatflag = 0;
3732 dvi_font_show(fnumtable[ m], repeatflag);
3735 free((void *)fnumtable);
3738 ////////////////////////////////////////////////////////////////////////////
3740 // Here follows the new stuff for the DLL version
3746 #define SHOWLINEBUFLEN 256
3748 char showlinebuf[SHOWLINEBUFLEN];
3750 // char log_line[MAXLINE];
3752 #define WHITESPACE " \t\n\r"
3754 HINSTANCE hInstanceDLL=NULL; /* remember for this DLL */
3756 /* This is the callback function for the EDITTEXT Control in CONSOLETEXT */
3758 #define GET_WM_COMMAND_CMD(wParam, lParam) (HIWORD(wParam))
3759 #define GET_WM_COMMAND_ID(wParam, lParam) (LOWORD(wParam))
3760 #define GET_WM_COMMAND_HWND(wParam, lParam) ((HWND)lParam)
3762 HWND hConsoleWnd=NULL; /* Console Text Window Handle passed from DVIWindo */
3764 void ClearShowBuffer (void)
3766 showlinebuf[showlineinx++] = '\0'; // clear out accumulated stuff
3767 if (hConsoleWnd != NULL)
3768 SendMessage(hConsoleWnd, ICN_ADDTEXT, (WPARAM) showlinebuf, 0L);
3772 // communicate with DVIWindo (for yandytex.dll)
3774 void show_line (char *line, int errflag) { /* 99/June/11 */
3777 if (IsWindow(hConsoleWnd) == 0) { // in case the other end died
3778 sprintf(line, "NO CONSOLE WINDOW? %08X %s", hConsoleWnd, line);
3779 ret = MessageBox(NULL, line, "YandYTeX", MB_ICONSTOP | MB_OKCANCEL | MB_TASKMODAL);
3781 // abort_flag++; // kill job in this case ???
3785 if (showlineinx > 0) ClearShowBuffer();
3787 if (hConsoleWnd != NULL)
3788 SendMessage(hConsoleWnd, ICN_ADDTEXT, (WPARAM) line, 0L);
3792 ret = MessageBox(NULL, line, "YandYTeX", MB_ICONSTOP | MB_OKCANCEL | MB_TASKMODAL);
3793 if (ret == IDCANCEL) {
3795 uexit(1); // dangerous reentry possibility ?
3800 // Provide means for buffering up individual characters
3802 void show_char (int chr) {
3803 if (showlineinx +2 >= SHOWLINEBUFLEN) ClearShowBuffer();
3804 showlinebuf[showlineinx++] = (char) chr;
3805 if (chr == '\n') ClearShowBuffer();
3808 void winshow(char *line) {
3809 (void) MessageBox(NULL, line, "YandYTeX", MB_ICONINFORMATION | MB_OK | MB_TASKMODAL);
3812 void winerror (char *line) {
3814 ret = MessageBox(NULL, line, "YandYTeX", MB_ICONSTOP | MB_OKCANCEL | MB_TASKMODAL);
3815 if (ret == IDCANCEL) abort_flag++;
3818 // argument info constructed from command line
3824 // need to be careful here because of quoted args with spaces in them
3825 // e.g. -d="G:\Program Files\Adobe\Acrobat\*.pdf"
3827 int makecommandargs (char *line)
3831 unsigned char *s, *t; // fix 2000 June 18
3833 if (line == NULL) return -1; /* sanity check */
3835 // winerror(line); // debugging only
3837 // s = strtok(line, WHITESPACE);
3838 // while (s != NULL) { /* count arguments */
3840 // s = strtok(NULL, WHITESPACE);
3845 while (*s != '\0') {
3846 while (*s <= 32 && *s > 0) s++;
3847 if (*s == '\0') break;
3849 while (*t > 32 && *t != '\"') t++;
3852 while (*t > 0 && *t != '\"') t++;
3853 if (*t == '\0') break;
3856 // xargv[xargc] = s;
3858 if (*t == '\0') break;
3863 if (xargc == 0) return -1; /* nothing to do */
3865 xargv = (char **) malloc(xargc * sizeof(char *));
3866 if (xargv == NULL) {
3867 sprintf(log_line, "ERROR: Unable to allocate memory for %s\n", "arguments");
3874 while (*s != '\0') {
3875 while (*s <= ' ' && *s > '\0') s++; /* eat white space */
3876 if (*s == '\0') break;
3878 while (*t > ' ' && *t != '\"') t++;
3881 while (*t > 0 && *t != '\"') t++;
3882 if (*t == '\0') break;
3885 // winerror(s); // debugging only
3888 if (*t == '\0') break;
3894 // for (k = 0; k < xargc; k++) { /* create pointers to args */
3895 // while (*s > '\0' && *s <= ' ') s++; /* eat white space */
3897 // s += strlen(s) +1;
3903 for (k = 0; k < xargc; k++) {
3904 sprintf(s, "%d\t%s\n", k, xargv[k]);
3912 // refers to TeXAsk in dviwindo.c
3914 // int (* AskUserCall) (char *, char *) = NULL; // callback for user questions
3915 int (* AskUserCall) (char *, char *, char *) = NULL; // callback for user questions
3917 // called from tex0.c only --- by initterm and term_input
3919 //int ConsoleInput (char *question, char *buffer)
3920 int ConsoleInput (char *question, char *help, char *buffer)
3924 if (AskUserCall == NULL) return 0;
3925 // sprintf(log_line, "str_start %x %x\n", str_start, str_start [831]);
3926 // show_line(log_line, 1);
3929 ret = AskUserCall (question, help, buffer); // value returned by dialogbox
3930 // strcpy(buffer, "x");
3931 // strcat(buffer, " "); // ???
3932 // sprintf(log_line, "str_start %x %x\n", str_start, str_start[831]);
3933 // show_line(log_line, 1);
3934 // input_line_finish(); // ???
3935 // s = buffer + strlen(buffer);
3936 // *s++ = ' '; // space terminate
3937 // *s++ = '\0'; // and null terminate
3938 // returning != 0 means EOF or ^Z
3942 // This is the new entry point of DLL called from DVIWindo
3943 // ARGS: console window to send messages to, command line, callback fun
3944 // no console window output if hConsole is NULL
3945 // returns -1 if it fails --- returns 0 if it succeeds
3947 // MYLIBAPI int yandytex (HWND hConsole, char *line, int (* AskUser) (char *, char *)) {
3948 MYLIBAPI int yandytex (HWND hConsole, char *line, int (* AskUser) (char *, char *, char *))
3952 abort_flag = 0; // redundant
3953 hConsoleWnd = NULL; // redundant
3955 AskUserCall = AskUser; // remember callback
3957 hConsoleWnd = hConsole; // remember console window handle
3959 // can't getenv("DEBUGPAUSE") cause setupdviwindo not called yet
3960 // if (grabenv("DEBUGPAUSE") != NULL) {
3961 // show_line(line, 0); // debugging - show command line
3962 // show_line("\n", 0);
3965 xargc = makecommandargs(line); // sets up global *xargv[]
3967 if (xargc < 0) return -1; // sanity check
3969 if (hConsoleWnd != NULL)
3970 SendMessage(hConsoleWnd, ICN_SETTITLE, (WPARAM) "YandYTeX", 0L);
3971 // SendMessage(hConsoleWnd, ICN_RESET, 0, 0L); // if want to clear window
3974 (void) main(xargc, xargv); // now run YandYTeX proper in texmf.c
3976 if (err_level > 0 || abort_flag > 0) {
3977 // sprintf(log_line, "ERRORS in Processing (err %d abort %d)\n",
3978 // err_level, abort_flag);
3979 // winerror(log_line);
3982 // if (psbufpos > 0) sendpsbuffer(output); // empty out PS buffer
3983 // if (psbufpos > 0) PSputs("", output); // output already closed
3985 if (hConsoleWnd != NULL) {
3986 if (err_level > 0 || abort_flag > 0) flag = 1;
3987 else flag = 0; // pass along error indication
3988 SendMessage(hConsoleWnd, ICN_DONE, flag, 0); // flush out console buffer
3990 // PScallback = NULL;
3993 if (xargv != NULL) free(xargv);
3994 if (abort_flag) return -1;
3998 BOOL WINAPI DllMain (HINSTANCE hInstDll, DWORD fdwReason, LPVOID fImpLoad)
4001 switch (fdwReason) {
4002 case DLL_PROCESS_ATTACH:
4003 // The DLL is being mapped into the process's address space
4004 // place to allocate memory ???
4005 // return FALSE if this fails
4006 hInstanceDLL = hInstDll; /* remember it */
4009 case DLL_THREAD_ATTACH:
4010 // A thread is being created
4013 case DLL_THREAD_DETACH:
4014 // A thread is exiting cleanly
4017 case DLL_PROCESS_DETACH:
4018 // The DLL is being unmapped from the process's address space
4019 // place to free any memory allocated
4020 // but make sure it in fact *was* allocated
4021 hInstanceDLL = NULL; /* forget it */
4024 return(TRUE); // used only for DLL_PROCESS_ATTACH
4026 #endif // end of new stuff for DLL version
4028 //////////////////////////////////////////////////////////////////////////////
4032 /* NOTE: current_tfm = false (-c)
4033 not checking for TFM in current directory saves 0.1 sec
4034 (0.2 if file_method = false (-G) */
4036 /* NOTE: test_dir_access = false (-b):
4037 not checking whether readable file is a directory saves maybe 0.5 sec
4038 BUT only if file_method = false (-G) - otherwise its irrelevant */
4040 /* NOTE: dir_method = false (-D) --- method for checking whether directory
4041 using fopen instead of _findfirst in dir_p slows job maybe 0.05 sec
4042 BUT not if current_tfm = false (-c) */
4044 /* NOTE: file_method = false (-G) --- method for checking file accessible
4045 using _access (readable) instead of _findfirst (file_p) costs 0.5 sec */
4047 /* Fast flag combinations: nothing, bG, bcG, bcDG */
4049 /* constants for _heapchk/_heapset/_heapwalk routines */
4050 /* #define _HEAPEMPTY (-1) */
4051 /* #define _HEAPOK (-2) */
4052 /* #define _HEAPBADBEGIN (-3) */
4053 /* #define _HEAPBADNODE (-4) */
4054 /* #define _HEAPEND (-5) */
4055 /* #define _HEAPBADPTR (-6) */
4057 /* new arg -H=8 for horizontal tab *//* tab_step = 0 means no tab replacement */
4059 /* buffercopy no longer used */
4061 /* To Knuthian reset right when command line interpreted */