1 /** @file structs.h
2  *
3  *  Contains definitions for global structs.
4  *
5  *  !!!CAUTION!!!
6  *  Changes in this file will most likely have consequences for the recovery
7  *  mechanism (see checkpoint.c). You need to care for the code in checkpoint.c
8  *  as well and modify the code there accordingly!
9  *
10  *  The marker [D] is used in comments in this file to mark pointers to which
11  *  dynamically allocated memory is assigned by a call to malloc() during
12  *  runtime (in contrast to pointers that point into already allocated memory).
13  *  This information is especially helpful if one needs to know which pointers
14  *  need to be freed (cf. checkpoint.c).
15  */
16 
17 /* #[ License : */
18 /*
19  *   Copyright (C) 1984-2017 J.A.M. Vermaseren
20  *   When using this file you are requested to refer to the publication
21  *   J.A.M.Vermaseren "New features of FORM" math-ph/0010025
22  *   This is considered a matter of courtesy as the development was paid
23  *   for by FOM the Dutch physics granting agency and we would like to
24  *   be able to track its scientific use to convince FOM of its value
25  *   for the community.
26  *
27  *   This file is part of FORM.
28  *
29  *   FORM is free software: you can redistribute it and/or modify it under the
30  *   terms of the GNU General Public License as published by the Free Software
31  *   Foundation, either version 3 of the License, or (at your option) any later
32  *   version.
33  *
34  *   FORM is distributed in the hope that it will be useful, but WITHOUT ANY
35  *   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
36  *   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
37  *   details.
38  *
39  *   You should have received a copy of the GNU General Public License along
40  *   with FORM.  If not, see <http://www.gnu.org/licenses/>.
41  */
42 /* #] License : */
43 
44 #ifndef __STRUCTS__
45 
46 #define __STRUCTS__
47 #ifdef _MSC_VER
48 #include <wchar.h>  /* off_t */
49 #endif
50 /*
51   	#[ sav&store :
52 */
53 
54 /**
55  *
56  */
57 
58 typedef struct PoSiTiOn {
59 	off_t p1;
60 } POSITION;
61 
62 /*	Next are the index structs for stored and saved expressions */
63 
64 /**
65  *  Defines the structure of the file header for store-files and save-files.
66  *
67  *  The first 8 bytes serve as a unique mark to identity save-files that
68  *  contain such a header. Older versions of FORM don't have this header and
69  *  will write the POSITION of the next file index (struct FiLeInDeX) here,
70  *  which is always different from this pattern.
71  *
72  *  It is always 512 bytes long.
73  */
74 typedef struct {
75 	UBYTE headermark[8];  /**< Pattern for header identification. Old versions
76 	                           of FORM have a maximum sizeof(POSITION) of 8 */
77 	UBYTE lenWORD;        /**< Number of bytes for WORD */
78 	UBYTE lenLONG;        /**< Number of bytes for LONG */
79 	UBYTE lenPOS;         /**< Number of bytes for POSITION */
80 	UBYTE lenPOINTER;     /**< Number of bytes for void * */
81 	UBYTE endianness[16]; /**< Used to determine endianness, sizeof(int) should be <= 16 */
82 	UBYTE sSym;           /**< sizeof(struct SyMbOl)   */
83 	UBYTE sInd;           /**< sizeof(struct InDeX)    */
84 	UBYTE sVec;           /**< sizeof(struct VeCtOr)   */
85 	UBYTE sFun;           /**< sizeof(struct FuNcTiOn) */
86 	UBYTE maxpower[16];   /**< Maximum power, see #MAXPOWER */
87 	UBYTE wildoffset[16]; /**< #WILDOFFSET macro         */
88 	UBYTE revision;       /**< Revision number of save-file system  */
89 	UBYTE reserved[512-8-4-16-4-16-16-1]; /**< Padding to 512 bytes */
90 } STOREHEADER;
91 
92 STATIC_ASSERT(sizeof(STOREHEADER) == 512);
93 
94 /**
95  *  Defines the structure of an entry in a file index (see struct FiLeInDeX).
96  *
97  *  It represents one expression in the file.
98  */
99 typedef struct InDeXeNtRy {
100 	POSITION	position;		/**< Position of the expression itself */
101 	POSITION	length;			/**< Length of the expression itself */
102 	POSITION	variables;		/**< Position of the list with variables */
103 	LONG	CompressSize;		/**< Size of buffer before compress */
104 	WORD	nsymbols;			/**< Number of symbols in the list */
105 	WORD	nindices;			/**< Number of indices in the list */
106 	WORD	nvectors;			/**< Number of vectors in the list */
107 	WORD	nfunctions;			/**< Number of functions in the list */
108 	WORD    size;				/**< Size of variables field */
109 	SBYTE	name[MAXENAME+1];	/**< Name of expression */
110 	PADPOSITION(0,1,0,5,MAXENAME+1);
111 } INDEXENTRY;
112 
113 /**
114  *  Maximum number of entries (struct InDeXeNtRy) in a file index (struct
115  *  FiLeInDeX). Number is calculated such that the size of a file index is no
116  *  more than 512 bytes.
117  */
118 #define INFILEINDEX ((512-2*sizeof(POSITION))/sizeof(INDEXENTRY))
119 /**
120  *  Number of empty filling bytes for a file index (struct FiLeInDeX). It is
121  *  calculated such that the size of a file index is always 512 bytes.
122  */
123 #define EMPTYININDEX (512-2*sizeof(POSITION)-INFILEINDEX*sizeof(INDEXENTRY))
124 
125 /**
126  *  Defines the structure of a file index in store-files and save-files.
127  *
128  *  It contains several entries (see struct InDeXeNtRy) up to a maximum of
129  *  #INFILEINDEX.
130  *
131  *  The variable number has been made of type POSITION to avoid padding
132  *  problems with some types of computers/OS and keep system independence
133  *  of the .sav files.
134  *
135  *  This struct is always 512 bytes long.
136  */
137 typedef struct FiLeInDeX {
138 	POSITION	next;			/**< Position of next FILEINDEX if any */
139 	POSITION	number;			/**< Number of used entries in this index */
140 	INDEXENTRY expression[INFILEINDEX]; /**< File index entries */
141 	SBYTE	empty[EMPTYININDEX];		/**< Padding to 512 bytes */
142 } FILEINDEX;
143 
144 STATIC_ASSERT(sizeof(FILEINDEX) == 512);
145 
146 /**
147  *
148  */
149 
150 typedef struct FiLeDaTa {
151 	FILEINDEX Index;
152 	POSITION Fill;
153 	POSITION Position;
154 	WORD Handle;
155 	WORD dirtyflag;
156 	PADPOSITION(0,0,0,2,0);
157 } FILEDATA;
158 
159 /**
160  *
161  *  Contains the pointers to an array in which a binary search will be
162  *  performed.
163  */
164 
165 typedef struct VaRrEnUm {
166 	WORD  *start;  /**< Start point for search. Points inbetween lo and hi */
167 	WORD  *lo;     /**< Start of memory area */
168 	WORD  *hi;     /**< End of memory area */
169 } VARRENUM;
170 
171 /**
172  *
173  *  Only symb.lo gets dynamically allocated. All other pointers points into this
174  *  memory.
175  */
176 
177 typedef struct ReNuMbEr {
178 	POSITION   startposition;
179 	/* First stage renumbering */
180 	VARRENUM   symb;          /**< Symbols */
181 	VARRENUM   indi;          /**< Indices */
182 	VARRENUM   vect;          /**< Vectors */
183 	VARRENUM   func;          /**< Functions */
184 	/* Second stage renumbering */
185 	WORD       *symnum;       /**< Renumbered symbols */
186 	WORD       *indnum;       /**< Renumbered indices */
187 	WORD       *vecnum;       /**< Renumbered vectors */
188 	WORD       *funnum;       /**< Renumbered functions */
189 	PADPOSITION(4,0,0,0,sizeof(VARRENUM)*4);
190 } *RENUMBER;
191 
192 /*
193   	#] sav&store :
194   	#[ Variables :
195 */
196 
197 /**
198  *  Much information is stored in arrays of which we can double the size
199  *  if the array proves to be too small. Such arrays are controled by
200  *  a variable of type #LIST. The routines that expand the lists are in the
201  *  file tools.c
202  */
203 
204 typedef struct {
205 	void *lijst;       /**< [D] Holds space for "maxnum" elements of size "size" each */
206 	char *message;     /**< Text for Malloc1 when allocating lijst. Set to constant string. */
207 	int num;           /**< Number of elements in lijst. */
208 	int maxnum;        /**< Maximum number of elements in lijst. */
209 	int size;          /**< Size of one element in lijst. */
210 	int numglobal;     /**< Marker for position when .global is executed. */
211 	int numtemp;       /**< At the moment only needed for sets and setstore. */
212 	int numclear;      /**< Only for the clear instruction. */
213 	PADPOINTER(0,6,0,0);
214 } LIST;
215 
216 /**
217  *	The KEYWORD struct defines names of commands/statements and the routine
218  *	to be called when they are encountered by the compiler or preprocessor.
219  */
220 
221 typedef struct {
222 	char *name;
223 	TFUN func;
224 	int type;
225 	int flags;
226 } KEYWORD;
227 
228 /**
229  *	The KEYWORDV struct defines names of commands/statements and the variable
230  *	to be affected when they are encountered by the compiler or preprocessor.
231  */
232 
233 typedef struct {
234 	char *name;
235 	int *var;
236 	int type;
237 	int flags;
238 } KEYWORDV;
239 
240 /**
241  *  The names of variables are kept in an array. Elements of type #NAMENODE
242  *  define a tree (that is kept balanced) that make it easy and fast to look for
243  *  variables. See also #NAMETREE.
244  */
245 
246 typedef struct NaMeNode {
247 	LONG name;      /**< Offset into NAMETREE::namebuffer. */
248 	WORD parent;    /**< =-1 if no parent. */
249 	WORD left;      /**< =-1 if no child. */
250 	WORD right;     /**< =-1 if no child. */
251 	WORD balance;   /**< Used for the balancing of the tree. */
252 	WORD type;      /**< Type associated with the name. See @ref CompilerTypes "compiler types". */
253 	WORD number;    /**< Number of variable in #LIST's like for example C_const::SymbolList. */
254 	PADLONG(0,6,0);
255 } NAMENODE;
256 
257 /**
258  *  A struct of type #NAMETREE controls a complete (balanced) tree of names
259  *  for the compiler. The compiler maintains several of such trees and the
260  *  system has been set up in such a way that one could define more of them
261  *  if we ever want to work with local name spaces.
262  */
263 
264 typedef struct NaMeTree {
265 	NAMENODE *namenode;      /**< [D] Vector of #NAMENODE's. Number of elements is #nodesize.
266 	                              =0 if no memory has been allocated. */
267 	UBYTE    *namebuffer;    /**< [D] Buffer that holds all the name strings refered to by the
268 	                              NAMENODE's. Allocation size is #namesize. =0 if no memory
269 	                              has been allocated. */
270 	LONG     nodesize;       /**< Maximum number of elements in #namenode. */
271 	LONG     nodefill;       /**< Number of currently used nodes in #namenode. */
272 	LONG     namesize;       /**< Allocation size of #namebuffer in bytes. */
273 	LONG     namefill;       /**< Number of bytes occupied. */
274 	LONG     oldnamefill;    /**< UNUSED */
275 	LONG     oldnodefill;    /**< UNUSED */
276 	LONG     globalnamefill; /**< Set by .global statement to the value of #namefill. When a .store
277 	                              command is processed, this value will be used to reset namefill.*/
278 	LONG     globalnodefill; /**< Same usage as #globalnamefill, but for nodefill. */
279 	LONG     clearnamefill;  /**< Marks the reset point used by the .clear statement. */
280 	LONG     clearnodefill;  /**< Marks the reset point used by the .clear statement. */
281 	WORD     headnode;       /**< Offset in #namenode of head node. =-1 if tree is empty. */
282 	PADPOINTER(10,0,1,0);
283 } NAMETREE;
284 
285 /**
286  *	The subexpressions in the compiler are kept track of in a (balanced) tree
287  *	to reduce the need for subexpressions and hence save much space in
288  *	large rhs expressions (like when we have xxxxxxx occurrences of objects
289  *	like f(x+1,x+1) in which each x+1 becomes a subexpression.
290  *	The struct that controls this tree is COMPTREE.
291  */
292 
293 typedef struct tree {
294 	int parent;  /**< Index of parent */
295 	int left;    /**< Left child (if not -1) */
296 	int right;   /**< Right child (if not -1) */
297 	int value;   /**< The object to be sorted and searched */
298 	int blnce;   /**< Balance factor */
299 	int usage;   /**< Number of uses in some types of trees */
300 } COMPTREE;
301 
302 /**
303  *
304  */
305 
306 typedef struct MiNmAx {
307 	WORD mini;          /**< Minimum value */
308 	WORD maxi;          /**< Maximum value */
309 	WORD size;          /**< Value of one unit in this position. */
310 } MINMAX;
311 
312 /**
313  *
314  */
315 
316 typedef struct BrAcKeTiNdEx {	/* For indexing brackets in local expressions */
317 	POSITION start;				/* Place where bracket starts - start of expr */
318 	POSITION next;				/* Place of next indexed bracket in expr */
319 	LONG bracket;				/* Offset of position in bracketbuffer */
320 	LONG termsinbracket;
321 	PADPOSITION(0,2,0,0,0);
322 } BRACKETINDEX;
323 
324 /**
325  *
326  */
327 
328 typedef struct BrAcKeTiNfO {
329 	BRACKETINDEX *indexbuffer; /**< [D] */
330 	WORD  *bracketbuffer;      /**< [D] */
331 	LONG  bracketbuffersize;
332 	LONG  indexbuffersize;
333 	LONG  bracketfill;
334 	LONG  indexfill;
335 	WORD  SortType;            /**< The sorting criterium used (like POWERFIRST etc) */
336 	PADPOINTER(4,0,1,0);
337 } BRACKETINFO;
338 
339 /**
340  *
341  *  buffers, mm, flags, and prototype are always dynamically allocated,
342  *  tablepointers only if needed (=0 if unallocated),
343  *  boomlijst and argtail only for sparse tables.
344  *
345  *  Allocation is done for both the normal and the stub instance (spare),
346  *  except for prototype and argtail which share memory.
347  */
348 
349 typedef struct TaBlEs {
350 	WORD    *tablepointers; /**< [D] Start in tablepointers table. */
351 #ifdef WITHPTHREADS
352 	WORD    **prototype;    /**< [D] The wildcard prototyping for arguments */
353 	WORD    **pattern;      /**< The pattern with which to match the arguments */
354 #else
355 	WORD    *prototype;     /**< [D] The wildcard prototyping for arguments */
356 	WORD    *pattern;       /**< The pattern with which to match the arguments */
357 #endif
358 	MINMAX  *mm;            /**< [D] Array bounds, dimension by dimension. # elements = numind. */
359 	WORD    *flags;         /**< [D] Is element in use ? etc. # elements = numind. */
360 	COMPTREE *boomlijst;    /**< [D] Tree for searching in sparse tables */
361 	UBYTE   *argtail;       /**< [D] The arguments in characters. Starts for tablebase
362 	                             with parenthesis to indicate tail */
363 	struct TaBlEs *spare;   /**< [D] For tablebase. Alternatingly stubs and real */
364 	WORD    *buffers;       /**< [D] When we use more than one compiler buffer. */
365 	LONG    totind;         /**< Total number requested */
366 	LONG    reserved;       /**< Total reservation in tablepointers for sparse */
367 	LONG    defined;        /**< Number of table elements that are defined */
368 	LONG    mdefined;       /**< Same as defined but after .global */
369 	int     prototypeSize;  /**< Size of allocated memory for prototype in bytes. */
370 	int     numind;         /**< Number of array indices */
371 	int     bounds;         /**< Array bounds check on/off. */
372 	int     strict;         /**< >0: all must be defined. <0: undefined not substitute */
373 	int     sparse;         /**< > 0 --> sparse table */
374 	int     numtree;        /**< For the tree for sparse tables */
375 	int     rootnum;        /**< For the tree for sparse tables */
376 	int     MaxTreeSize;    /**< For the tree for sparse tables */
377 	WORD    bufnum;         /**< Each table potentially its own buffer */
378 	WORD    bufferssize;    /**< When we use more than one compiler buffer */
379 	WORD    buffersfill;    /**< When we use more than one compiler buffer */
380 	WORD    tablenum;       /**< For testing of tableuse */
381 	WORD    mode;           /**< 0: normal, 1: stub */
382 	WORD    numdummies;     /**<  */
383 	PADPOINTER(4,8,6,0);
384 } *TABLES;
385 
386 /**
387  *
388  */
389 
390 typedef struct ExPrEsSiOn {
391 	POSITION	onfile;
392 	POSITION	prototype;
393     POSITION    size;
394 	RENUMBER renum;			/* For Renumbering of global stored expressions */
395 	BRACKETINFO *bracketinfo;
396 	BRACKETINFO *newbracketinfo;
397 	WORD	*renumlists;    /**< Allocated only for threaded version if variables exist,
398 	                             else points to AN.dummyrenumlist */
399 	WORD	*inmem;			/* If in memory like e.g. a polynomial */
400 	LONG	counter;
401 	LONG	name;
402 	WORD	hidelevel;
403 	WORD	vflags;			/* Various flags */
404 	WORD	printflag;
405 	WORD	status;
406 	WORD	replace;
407 	WORD	node;
408 	WORD	whichbuffer;
409 	WORD	namesize;
410 	WORD	compression;
411 	WORD	numdummies;
412 	WORD	numfactors;
413 	WORD	sizeprototype;
414 #ifdef PARALLELCODE
415     WORD    partodo;        /* Whether to be done in parallel mode */
416 	PADPOSITION(5,2,0,13,0);
417 #else
418 	PADPOSITION(5,2,0,12,0);
419 #endif
420 } *EXPRESSIONS;
421 
422 /**
423  *
424  */
425 
426 typedef struct SyMbOl {			/* Don't change unless altering .sav too */
427 	LONG	name;				/* Location in names buffer */
428 	WORD	minpower;			/* Minimum power admissible */
429 	WORD	maxpower;			/* Maximum power admissible */
430 	WORD	complex;			/* Properties wrt complex conjugation */
431 	WORD	number;				/* Number when stored in file */
432 	WORD	flags;				/* Used to indicate usage when storing */
433 	WORD	node;
434 	WORD	namesize;
435 	WORD	dimension;			/* For dimensionality checks */
436 	PADLONG(0,8,0);
437 } *SYMBOLS;
438 
439 /**
440  *
441  */
442 
443 typedef struct InDeX {			/* Don't change unless altering .sav too */
444 	LONG	name;				/* Location in names buffer */
445 	WORD	type;				/* Regular or dummy */
446 	WORD	dimension;			/* Value of d_(n,n) or -number of symbol */
447 	WORD	number;				/* Number when stored in file */
448 	WORD	flags;				/* Used to indicate usage when storing */
449 	WORD    nmin4;				/* Used for n-4 if dimension < 0 */
450 	WORD	node;
451 	WORD	namesize;
452 	PADLONG(0,7,0);
453 } *INDICES;
454 
455 /**
456  *
457  */
458 
459 typedef struct VeCtOr {			/* Don't change unless altering .sav too */
460 	LONG	name;				/* Location in names buffer */
461 	WORD	complex;			/* Properties under complex conjugation */
462 	WORD	number;				/* Number when stored in file */
463 	WORD	flags;				/* Used to indicate usage when storing */
464 	WORD	node;
465 	WORD	namesize;
466 	WORD	dimension;			/* For dimensionality checks */
467 	PADLONG(0,6,0);
468 } *VECTORS;
469 
470 /**
471  *  Contains all information about a function. Also used for tables.
472  *  It is used in the #LIST elements of #AC.
473  */
474 
475 typedef struct FuNcTiOn {  /* Don't change unless altering .sav too */
476 	TABLES  tabl;          /**< Used if redefined as table. != 0 if function is a table */
477 	LONG    symminfo;      /**< Info regarding symm properties offset in buffer */
478 	LONG    name;          /**< Location in namebuffer of #NAMETREE */
479 	WORD    commute;       /**< Commutation properties */
480 	WORD    complex;       /**< Properties under complex conjugation */
481 	WORD    number;        /**< Number when stored in file */
482 	WORD    flags;         /**< Used to indicate usage when storing */
483 	WORD    spec;          /**< Regular, Tensor, etc. See @ref FunSpecs. */
484 	WORD    symmetric;     /**< > 0 if symmetric properties */
485 	WORD    node;          /**< Location in namenode of #NAMETREE */
486 	WORD    namesize;      /**< Length of the name */
487 	WORD    dimension;     /* For dimensionality checks */
488 	WORD    maxnumargs;
489 	WORD    minnumargs;
490 	PADPOINTER(2,0,11,0);
491 } *FUNCTIONS;
492 
493 /**
494  *
495  */
496 
497 typedef struct SeTs {
498 	LONG	name;				/* Location in names buffer */
499 	WORD	type;				/* Symbol, vector, index or function */
500 	WORD	first;				/* First element in setstore */
501 	WORD	last;				/* Last element in setstore (excluding) */
502 	WORD	node;
503 	WORD	namesize;
504 	WORD	dimension;			/* For dimensionality checks */
505     WORD    flags;              /* Like: ordered */
506 	PADLONG(0,7,0);
507 } *SETS;
508 
509 /**
510  *
511  */
512 
513 typedef struct DuBiOuS {		/* Undeclared objects. Just for compiler. */
514 	LONG	name;				/* Location in names buffer */
515 	WORD	node;
516 	WORD	dummy;
517 	PADLONG(0,2,0);
518 } *DUBIOUSV;
519 
520 typedef struct FaCdOlLaR {
521 	WORD	*where;				/* A pointer(!) to the content */
522 	LONG	size;
523 	WORD	type;				/* Type can be DOLNUMBER or DOLTERMS */
524 	WORD	value;				/* in case it is a (short) number */
525 	PADPOINTER(1,0,2,0);
526 } FACDOLLAR;
527 
528 typedef struct DoLlArS {
529 	WORD	*where;				/* A pointer(!) to the object */
530 	FACDOLLAR *factors;			/* an array of factors. nfactors elements */
531 #ifdef WITHPTHREADS
532 	pthread_mutex_t	pthreadslockread;
533 	pthread_mutex_t	pthreadslockwrite;
534 #endif
535 	LONG	size;				/* The number of words */
536 	LONG	name;
537 	WORD	type;
538 	WORD	node;
539 	WORD	index;
540 	WORD	zero;
541 	WORD	numdummies;
542 	WORD	nfactors;
543 #ifdef WITHPTHREADS
544 	PADPOINTER(2,0,6,sizeof(pthread_mutex_t)*2);
545 #else
546 	PADPOINTER(2,0,6,0);
547 #endif
548 } *DOLLARS;
549 
550 /**
551  *
552  */
553 
554 typedef struct MoDoPtDoLlArS {
555 #ifdef WITHPTHREADS
556 	DOLLARS	dstruct;	/* If local dollar: list of DOLLARS for each thread */
557 #endif
558 	WORD	number;
559 	WORD	type;
560 #ifdef WITHPTHREADS
561 	PADPOINTER(0,0,2,0);
562 #endif
563 } MODOPTDOLLAR;
564 
565 /**
566  *
567  */
568 
569 typedef struct fixedset {
570 	char *name;
571 	char *description;
572 	int type;
573 	int dimension;
574 } FIXEDSET;
575 
576 /**
577  *
578  */
579 
580 typedef struct TaBlEbAsEsUbInDeX {
581 	POSITION where;
582 	LONG size;
583 	PADPOSITION(0,1,0,0,0);
584 } TABLEBASESUBINDEX;
585 
586 /**
587  *
588  */
589 
590 typedef struct TaBlEbAsE {
591 	POSITION fillpoint;
592 	POSITION current;
593 	UBYTE *name;
594 	int *tablenumbers;		/* Number of each table */
595 	TABLEBASESUBINDEX *subindex;		/* For each table */
596 	int numtables;
597 	PADPOSITION(3,0,1,0,0);
598 } TABLEBASE;
599 
600 /**
601  *	The struct FUN_INFO is used for information about functions in the file
602  *	smart.c which is supposed to intelligently look for patterns in
603  *	complicated wildcard situations involving symmetric functions.
604  */
605 
606 typedef struct {
607 	WORD *location;
608 	int numargs;
609 	int numfunnies;
610 	int numwildcards;
611 	int symmet;
612 	int tensor;
613 	int commute;
614 	PADPOINTER(0,6,0,0);
615 } FUN_INFO;
616 
617 /*
618   	#] Variables :
619   	#[ Files :
620 */
621 
622 /**
623  *	The type FILEHANDLE is the struct that controls all relevant information
624  *	of a file, whether it is open or not. The file may even not yet exist.
625  *	There is a system of caches (PObuffer) and as long as the information
626  *	to be written still fits inside the cache the file may never be
627  *	created. There are variables that can store information about different
628  *	types of files, like scratch files or sort files.
629  *	Depending on what is available in the system we may also have information
630  *	about gzip compression (currently sort file only) or locks (TFORM).
631  */
632 
633 typedef struct FiLe {
634 	POSITION POposition;    	/* File position */
635     POSITION filesize;          /* Because SEEK_END is unsafe on IBM */
636     WORD *PObuffer;             /* Address of the intermediate buffer */
637     WORD *POstop;               /* End of the buffer */
638     WORD *POfill;               /* Fill position of the buffer */
639     WORD *POfull;               /* Full buffer when only cached */
640 #ifdef WITHPTHREADS
641     WORD *wPObuffer;             /* Address of the intermediate worker buffer */
642     WORD *wPOstop;               /* End of the worker buffer */
643     WORD *wPOfill;               /* Fill position of the worker buffer */
644     WORD *wPOfull;               /* Full buffer when only worker cached */
645 #endif
646 	char *name;					/* name of the file */
647 #ifdef WITHZLIB
648 	z_streamp zsp;				/* The pointer to the stream struct for gzip */
649 	Bytef *ziobuffer;			/* The output buffer for compression */
650 #endif
651 	ULONG numblocks;			/* Number of blocks in file */
652 	ULONG inbuffer;				/* Block in the buffer */
653     LONG POsize;                /* size of the buffer */
654 #ifdef WITHZLIB
655     LONG ziosize;               /* size of the zoutbuffer */
656 #endif
657 #ifdef WITHPTHREADS
658     LONG wPOsize;                /* size of the worker buffer */
659 	pthread_mutex_t	pthreadslock;
660 #endif
661     int handle;					/**< Our own handle. Equal -1 if no file exists. */
662 	int active;					/* File is open or closed. Not used. */
663 #ifdef WITHPTHREADS
664 #ifdef WITHZLIB
665 	PADPOSITION(11,5,2,0,sizeof(pthread_mutex_t));
666 #else
667 	PADPOSITION(9,4,2,0,sizeof(pthread_mutex_t));
668 #endif
669 #else
670 #ifdef WITHZLIB
671 	PADPOSITION(7,4,2,0,0);
672 #else
673 	PADPOSITION(5,3,2,0,0);
674 #endif
675 #endif
676 } FILEHANDLE;
677 
678 /**
679  *	Input is read from 'streams' which are represented by objects of type
680  *	STREAM. A stream can be a file, a do-loop, a procedure, the string value
681  *	of a preprocessor variable .....
682  *	When a new stream is opened we have to keep information about where
683  *	to fall back in the parent stream to allow this to happen even in the
684  *	middle of reading names etc as would be the case with a`i'b
685  */
686 
687 typedef struct StreaM {
688 	off_t fileposition;
689 	off_t linenumber;
690 	off_t prevline;
691 	UBYTE *buffer;        /**< [D] Size in buffersize */
692 	UBYTE *pointer;       /**< pointer into buffer memory */
693 	UBYTE *top;           /**< pointer into buffer memory */
694 	UBYTE *FoldName;      /**< [D] */
695 	UBYTE *name;          /**< [D] */
696 	UBYTE *pname;         /**< for DOLLARSTREAM and PREVARSTREAM it points always to name, else it
697 	                           is undefined */
698 	LONG buffersize;
699 	LONG bufferposition;
700 	LONG inbuffer;
701 	int previous;
702 	int handle;
703 	int type;
704 	int prevars;
705 	int previousNoShowInput;
706 	int eqnum;
707 	int afterwards;
708 	int olddelay;
709 	int oldnoshowinput;
710 	UBYTE isnextchar;
711 	UBYTE nextchar[2];
712 	UBYTE reserved;
713 	PADPOSITION(6,3,9,0,4);
714 } STREAM;
715 
716 typedef struct SpecTatoR {
717 	POSITION position;   /* The place where we will be writing */
718 	POSITION readpos;    /* The place from which we read */
719 	FILEHANDLE *fh;
720 	char *name;          /* We identify the spectator by the name of the expression */
721 	WORD exprnumber;     /* During running we use the number. */
722 	WORD flags;          /* local, global? */
723 	PADPOSITION(2,0,0,2,0);
724 } SPECTATOR;
725 
726 /*
727   	#] Files :
728   	#[ Traces :
729 */
730 
731 /**
732  *	The struct TRACES keeps track of the progress during the expansion
733  *	of a 4-dimensional trace. Each time a term gets generated the expansion
734  *	tree continues in the next statement. When it returns it has to know
735  *	where to continue. The 4-dimensional traces are more complicated
736  *	than the n-dimensional traces (see TRACEN) because of the extra tricks
737  *	that can be used. They are responsible for the shorter final expressions.
738  */
739 
740 typedef struct TrAcEs {			/* For computing 4 dimensional traces */
741 	WORD		*accu;		/* NUMBER * 2 */
742 	WORD		*accup;
743 	WORD		*termp;
744 	WORD		*perm;		/* number */
745 	WORD		*inlist;	/* number */
746 	WORD		*nt3;		/* number/2 */
747 	WORD		*nt4;		/* number/2 */
748 	WORD		*j3;		/* number*2 */
749 	WORD		*j4;		/* number*2 */
750 	WORD		*e3;		/* number*2 */
751 	WORD		*e4;		/* number */
752 	WORD		*eers;		/* number/2 */
753 	WORD		*mepf;		/* number/2 */
754 	WORD		*mdel;		/* number/2 */
755 	WORD		*pepf;		/* number*2 */
756 	WORD		*pdel;		/* number*3/2 */
757 	WORD		sgn;
758 	WORD		stap;
759 	WORD		step1,kstep,mdum;
760 	WORD		gamm,ad,a3,a4,lc3,lc4;
761 	WORD		sign1,sign2,gamma5,num,level,factor,allsign;
762 	WORD		finalstep;
763 	PADPOINTER(0,0,19,0);
764 } TRACES;
765 
766 /**
767  *	The struct TRACEN keeps track of the progress during the expansion
768  *	of a 4-dimensional trace. Each time a term gets generated the expansion
769  *	tree continues in the next statement. When it returns it has to know
770  *	where to continue.
771  */
772 
773 typedef struct TrAcEn {			/* For computing n dimensional traces */
774 	WORD		*accu;		/* NUMBER */
775 	WORD		*accup;
776 	WORD		*termp;
777 	WORD		*perm;		/* number */
778 	WORD		*inlist;	/* number */
779 	WORD		sgn,num,level,factor,allsign;
780 	PADPOINTER(0,0,5,0);
781 } *TRACEN;
782 
783 /*
784   	#] Traces :
785   	#[ Preprocessor :
786 */
787 
788 /**
789  *	An element of the type PREVAR is needed for each preprocessor variable.
790  */
791 
792 typedef struct pReVaR {
793 	UBYTE *name;		/**< allocated */
794 	UBYTE *value;		/**< points into memory of name */
795 	UBYTE *argnames;	/**< names of arguments, zero separated. points into memory of name */
796 	int nargs;			/**< 0 = regular, >= 1: number of macro arguments. total number */
797 	int wildarg;		/**< The number of a potential ?var. If none: 0. wildarg<nargs */
798 	PADPOINTER(0,2,0,0);
799 } PREVAR;
800 
801 /**
802  *	Used for #inside
803  */
804 
805 typedef struct {
806 	WORD *buffer;
807 	int oldcompiletype;
808 	int oldparallelflag;
809 	int oldnumpotmoddollars;
810 	WORD size;
811 	WORD numdollars;
812 	WORD oldcbuf;
813 	WORD oldrbuf;
814 	WORD inscbuf;
815 	WORD oldcnumlhs;
816 	PADPOINTER(0,3,6,0);
817 } INSIDEINFO;
818 
819 /**
820  *	Used by the preprocessor to load the contents of a doloop or a procedure.
821  *	The struct PRELOAD is used both in the DOLOOP and PROCEDURE structs.
822  */
823 
824 typedef struct {
825 	UBYTE	*buffer;
826     LONG	size;
827 	PADPOINTER(1,0,0,0);
828 } PRELOAD;
829 
830 /**
831  *	An element of the type PROCEDURE is needed for each procedure in the system.
832  */
833 
834 typedef struct {
835 	PRELOAD p;
836 	UBYTE	*name;
837 	int		loadmode;
838 	PADPOINTER(0,1,0,0);
839 } PROCEDURE;
840 
841 /**
842  *	Each preprocessor do loop has a struct of type DOLOOP to keep track
843  *	of all relevant parameters like where the beginning of the loop is,
844  *	what the boundaries, increment and value of the loop parameter are, etc.
845  *	Also we keep the whole loop inside a buffer of type PRELOAD
846  */
847 
848 typedef struct DoLoOp {
849 	PRELOAD p;          /**< size, name and buffer */
850 	UBYTE *name;        /**< pointer into PRELOAD buffer */
851 	UBYTE *vars;        /* for {} or name of expression */
852 	UBYTE *contents;
853 	UBYTE *dollarname;  /**< For loop over terms in expression. Allocated with Malloc1() */
854 	LONG startlinenumber;
855 	LONG firstnum;
856 	LONG lastnum;
857 	LONG incnum;
858 	int type;
859 	int NoShowInput;
860 	int errorsinloop;
861 	int firstloopcall;
862 	WORD firstdollar;   /* When >= 0 we have to get the value from a dollar */
863 	WORD lastdollar;    /* When >= 0 we have to get the value from a dollar */
864 	WORD incdollar;     /* When >= 0 we have to get the value from a dollar */
865 	WORD NumPreTypes;
866 	WORD PreIfLevel;
867 	WORD PreSwitchLevel;
868 	PADPOINTER(4,4,6,0);
869 } DOLOOP;
870 
871 /**
872  *	The struct bit_field is used by set_in, set_set, set_del and set_sub.
873  *	They in turn are used in pre.c to toggle bits that indicate whether
874  *	a character can be used as a separator of function arguments.
875  *	This facility is used in the communication with external channels.
876  */
877 
878 struct  bit_field {	/* Assume 8 bits per byte */
879     UBYTE bit_0        : 1;
880     UBYTE bit_1        : 1;
881     UBYTE bit_2        : 1;
882     UBYTE bit_3        : 1;
883     UBYTE bit_4        : 1;
884     UBYTE bit_5        : 1;
885     UBYTE bit_6        : 1;
886     UBYTE bit_7        : 1;
887 /*
888     UINT bit_0        : 1;
889     UINT bit_1        : 1;
890     UINT bit_2        : 1;
891     UINT bit_3        : 1;
892     UINT bit_4        : 1;
893     UINT bit_5        : 1;
894     UINT bit_6        : 1;
895     UINT bit_7        : 1;
896 */
897 };
898 
899 /**
900  *	Used in set_in, set_set, set_del and set_sub.
901  */
902 
903 typedef struct bit_field set_of_char[32];
904 
905 /**
906  *	Used in set_in, set_set, set_del and set_sub.
907  */
908 
909 typedef struct bit_field *one_byte;
910 
911 /**
912  *	The struct HANDLERS is used in the communication with external channels.
913  */
914 
915 typedef struct {
916 	WORD newlogonly;
917 	WORD newhandle;
918 	WORD oldhandle;
919 	WORD oldlogonly;
920 	WORD oldprinttype;
921 	WORD oldsilent;
922 } HANDLERS;
923 
924 /*
925   	#] Preprocessor :
926   	#[ Varia :
927 */
928 
929 typedef WORD (*FINISHUFFLE)(WORD *);
930 typedef WORD (*DO_UFFLE)(WORD *,WORD,WORD,WORD);
931 typedef WORD (*COMPARE)(WORD *,WORD *,WORD);
932 
933 /**
934  *  The CBUF struct is used by the compiler. It is a compiler buffer of which
935  *  since version 3.0 there can be many.
936  */
937 
938 typedef struct CbUf {
939     WORD *Buffer;         /**< [D] Size in BufferSize */
940     WORD *Top;            /**< pointer to the end of the Buffer memory */
941     WORD *Pointer;        /**< pointer into the Buffer memory */
942     WORD **lhs;           /**< [D] Size in maxlhs. list of pointers into Buffer. */
943     WORD **rhs;           /**< [D] Size in maxrhs. list of pointers into Buffer. */
944     LONG *CanCommu;       /**< points into rhs memory behind WORD* area. */
945     LONG *NumTerms;       /**< points into rhs memory behind CanCommu area */
946     WORD *numdum;         /**< points into rhs memory behind NumTerms */
947     WORD *dimension;      /**< points into rhs memory behind numdum */
948     COMPTREE *boomlijst;  /**< [D] Number elements in MaxTreeSize */
949     LONG BufferSize;      /**< Number of allocated WORD's in Buffer */
950     int numlhs;
951     int numrhs;
952     int maxlhs;
953     int maxrhs;
954     int mnumlhs;
955     int mnumrhs;
956     int numtree;
957     int rootnum;
958     int MaxTreeSize;
959     PADPOINTER(1,9,0,0);
960 } CBUF;
961 
962 /**
963  *  When we read input from text files we have to remember not only their
964  *  handle but also their name. This is needed for error messages.
965  *  Hence we call such a file a channel and reserve a struct of type
966  *  #CHANNEL to allow to lay this link.
967  */
968 
969 typedef struct ChAnNeL {
970     char *name;          /**< [D] Name of the channel */
971     int handle;          /**< File handle */
972     PADPOINTER(0,1,0,0);
973 } CHANNEL;
974 
975 /**
976  *  Each setup parameter has one element of the struct SETUPPARAMETERS
977  *  assigned to it. By binary search in the array of them we can then
978  *  locate the proper element by name.
979  *  We have to assume that two ints make a long and either one or two longs
980  *  make a pointer. The long before the ints and padding gives a problem
981  *  in the initialization.
982  */
983 
984 typedef struct {
985     UBYTE *parameter;
986     int type;
987     int flags;
988     LONG value;
989 } SETUPPARAMETERS;
990 
991 /**
992  *  The NESTING struct is used when we enter the argument of functions and
993  *  there is the possibility that we have to change something there.
994  *  Because functions can be nested we have to keep track of all levels
995  *  of functions in case we have to move the outer layers to make room
996  *  for a larger function argument.
997  */
998 
999 typedef struct NeStInG {
1000     WORD *termsize;
1001     WORD *funsize;
1002     WORD *argsize;
1003 } *NESTING;
1004 
1005 /**
1006  *  The struct of type STORECACHE is used by a caching system for reading
1007  *  terms from stored expressions. Each thread should have its own system
1008  *  of caches.
1009  */
1010 
1011 typedef struct StOrEcAcHe {
1012     POSITION position;
1013     POSITION toppos;
1014     struct StOrEcAcHe *next;
1015     WORD buffer[2];
1016     PADPOSITION(1,0,0,2,0);
1017 } *STORECACHE;
1018 
1019 /**
1020  *  The struct PERM is used to generate all permutations when the pattern
1021  *  matcher has to try to match (anti)symmetric functions.
1022  */
1023 
1024 typedef struct PeRmUtE {
1025     WORD *objects;
1026     WORD sign;
1027     WORD n;
1028     WORD cycle[MAXMATCH];
1029     PADPOINTER(0,0,MAXMATCH+2,0);
1030 } PERM;
1031 
1032 /**
1033  *  Like struct PERM but works with pointers.
1034  */
1035 
1036 typedef struct PeRmUtEp {
1037     WORD **objects;
1038     WORD sign;
1039     WORD n;
1040     WORD cycle[MAXMATCH];
1041     PADPOINTER(0,0,MAXMATCH+2,0);
1042 } PERMP;
1043 
1044 /**
1045  *  The struct DISTRIBUTE is used to help the pattern
1046  *  matcher when matching antisymmetric tensors.
1047  */
1048 
1049 typedef struct DiStRiBuTe {
1050     WORD *obj1;
1051     WORD *obj2;
1052     WORD *out;
1053     WORD sign;
1054     WORD n1;
1055     WORD n2;
1056     WORD n;
1057     WORD cycle[MAXMATCH];
1058     PADPOINTER(0,0,(MAXMATCH+4),0);
1059 } DISTRIBUTE;
1060 
1061 /**
1062  *  The struct PARTI is used to help determining whether a partition_
1063  *  function can be replaced.
1064  */
1065 
1066 typedef struct PaRtI {
1067 	WORD *psize;  /* the sizes of the partitions */
1068 	WORD *args;   /* the offsets of the arguments to be partitioned */
1069 	WORD *nargs;  /* argument numbers (different number = different argument) */
1070 	WORD *nfun;   /* the functions into which the partitions go */
1071 	WORD numargs; /* the number of arguments to be partitioned */
1072 	WORD numpart; /* the number of partitions */
1073 	WORD where;   /* offset of the function in the term */
1074     PADPOINTER(0,0,3,0);
1075 } PARTI;
1076 
1077 /**
1078  *  The struct SORTING is used to control a sort operation.
1079  *  It includes a small and a large buffer and arrays for keeping track
1080  *  of various stages of the (merge) sorts.
1081  *  Each sort level has its own struct and different levels can have
1082  *  different sizes for its arrays.
1083  *  Also different threads have their own set of SORTING structs.
1084  */
1085 
1086 typedef struct sOrT {
1087     FILEHANDLE file;            /* The own sort file */
1088     POSITION SizeInFile[3];     /* Sizes in the various files */
1089     WORD *lBuffer;              /* The large buffer */
1090     WORD *lTop;                 /* End of the large buffer */
1091     WORD *lFill;                /* The filling point of the large buffer */
1092     WORD *used;                 /*  auxiliary during actual sort */
1093     WORD *sBuffer;              /* The small buffer */
1094     WORD *sTop;                 /* End of the small buffer */
1095     WORD *sTop2;                /* End of the extension of the small buffer */
1096     WORD *sHalf;                /* Halfway point in the extension */
1097     WORD *sFill;                /* Filling point in the small buffer */
1098     WORD **sPointer;            /* Pointers to terms in the small buffer */
1099     WORD **PoinFill;            /* Filling point for pointers to the sm.buf */
1100     WORD **SplitScratch;        /* Excess pointer space for the merge sort */
1101     WORD *cBuffer;              /* Compress buffer (if it exists) */
1102     WORD **Patches;             /* Positions of patches in large buffer */
1103     WORD **pStop;               /* Ends of patches in the large buffer */
1104     WORD **poina;               /*  auxiliary during actual sort */
1105     WORD **poin2a;              /*  auxiliary during actual sort */
1106     WORD *ktoi;                 /*  auxiliary during actual sort */
1107     WORD *tree;                 /*  auxiliary during actual sort */
1108 #ifdef WITHZLIB
1109     WORD *fpcompressed;         /*  is output filepatch compressed? */
1110     WORD *fpincompressed;       /*  is input filepatch compressed? */
1111     z_streamp zsparray;         /*  the array of zstreams for decompression */
1112 #endif
1113     POSITION *fPatches;         /* Positions of output file patches */
1114     POSITION *inPatches;        /* Positions of input file patches */
1115     POSITION *fPatchesStop;     /* Positions of output file patches */
1116     POSITION *iPatches;         /* Input file patches, Points to fPatches or inPatches */
1117     FILEHANDLE *f;              /* The actual output file */
1118     FILEHANDLE **ff;            /* Handles for a staged sort */
1119     LONG sTerms;                /* Terms in small buffer */
1120     LONG LargeSize;             /* Size of large buffer (in words) */
1121     LONG SmallSize;             /* Size of small buffer (in words) */
1122     LONG SmallEsize;            /* Size of small + extension (in words) */
1123     LONG TermsInSmall;          /* Maximum number of terms in small buffer */
1124     LONG Terms2InSmall;         /* with extension for polyfuns etc. */
1125     LONG GenTerms;              /* Number of generated terms */
1126     LONG TermsLeft;             /* Number of terms still in existence */
1127     LONG GenSpace;              /* Amount of space of generated terms */
1128     LONG SpaceLeft;             /* Space needed for still existing terms */
1129     LONG putinsize;             /* Size of buffer in putin */
1130     LONG ninterms;              /* Which input term ? */
1131     int MaxPatches;             /* Maximum number of patches in large buffer */
1132     int MaxFpatches;            /* Maximum number of patches in one filesort */
1133     int type;                   /* Main, function or sub(routine) */
1134     int lPatch;                 /* Number of patches in the large buffer */
1135     int fPatchN1;               /* Number of patches in input file */
1136     int PolyWise;               /* Is there a polyfun and if so, where? */
1137     int PolyFlag;               /*  */
1138     int cBufferSize;            /* Size of the compress buffer */
1139     int maxtermsize;            /* Keeps track for buffer allocations */
1140     int newmaxtermsize;         /* Auxiliary for maxtermsize */
1141     int outputmode;             /* Tells where the output is going */
1142     int stagelevel;             /* In case we have a 'staged' sort */
1143     WORD fPatchN;               /* Number of patches on file (output) */
1144     WORD inNum;                 /* Number of patches on file (input) */
1145     WORD stage4;                /* Are we using stage4? */
1146 #ifdef WITHZLIB
1147     PADPOSITION(28,12,12,3,0);
1148 #else
1149     PADPOSITION(25,12,12,3,0);
1150 #endif
1151 } SORTING;
1152 
1153 #ifdef WITHPTHREADS
1154 
1155 /**
1156  *  The SORTBLOCK's are used by TFORM when the master has to merge the sorted
1157  *  results of each of the workers.
1158  */
1159 
1160 typedef struct SoRtBlOcK {
1161     pthread_mutex_t *MasterBlockLock;
1162     WORD    **MasterStart;
1163     WORD    **MasterFill;
1164     WORD    **MasterStop;
1165     int     MasterNumBlocks;
1166     int     MasterBlock;
1167     int     FillBlock;
1168     PADPOINTER(0,3,0,0);
1169 } SORTBLOCK;
1170 #endif
1171 
1172 #ifdef DEBUGGER
1173 typedef struct DeBuGgInG {
1174     int eflag;
1175     int printflag;
1176     int logfileflag;
1177     int stdoutflag;
1178 } DEBUGSTR;
1179 #endif
1180 
1181 #ifdef WITHPTHREADS
1182 
1183 /**
1184  *  The THREADBUCKET struct defines one of the buckets used to pass terms
1185  *  from the master to the workers in TFORM.
1186  */
1187 
1188 typedef struct ThReAdBuCkEt {
1189     POSITION *deferbuffer;      /* For Keep Brackets: remember position */
1190     WORD *threadbuffer;         /* Here are the (primary) terms */
1191     WORD *compressbuffer;       /* For keep brackets we need the compressbuffer */
1192     LONG threadbuffersize;      /* Number of words in threadbuffer */
1193     LONG ddterms;               /* Number of primary+secondary terms represented */
1194     LONG firstterm;             /* The number of the first term in the bucket */
1195     LONG firstbracket;          /* When doing complete brackets */
1196     LONG lastbracket;           /* When doing complete brackets */
1197     pthread_mutex_t lock;       /* For the load balancing phase */
1198     int  free;                  /* Status of the bucket */
1199     int  totnum;                /* Total number of primary terms */
1200     int  usenum;                /* Which is the term being used at the moment */
1201     int  busy;                  /*  */
1202     int  type;                  /* Doing brackets? */
1203     PADPOINTER(5,5,0,sizeof(pthread_mutex_t));
1204 } THREADBUCKET;
1205 
1206 #endif
1207 
1208 /**
1209  *  The POLYMOD struct controls one univariate polynomial of which the
1210  *  coefficients have been taken modulus a (prime) number that fits inside
1211  *  a variable of type WORD. The polynomial is stored as an array of
1212  *  coefficients of size WORD.
1213  */
1214 
1215 typedef struct {
1216     WORD    *coefs;             /* The array of coefficients */
1217     WORD    numsym;             /* The number of the symbol in the polynomial */
1218     WORD    arraysize;          /* The size of the allocation of coefs */
1219     WORD    polysize;           /* The maximum power in the polynomial */
1220     WORD    modnum;             /* The prime number of the modulus */
1221 } POLYMOD;
1222 
1223 typedef struct {
1224     WORD    *outterm;            /* Used in DoShuffle/Merge/FinishShuffle system */
1225     WORD    *outfun;
1226     WORD    *incoef;
1227     WORD    *stop1;
1228     WORD    *stop2;
1229     WORD    *ststop1;
1230     WORD    *ststop2;
1231     FINISHUFFLE finishuf;
1232     DO_UFFLE	do_uffle;
1233     LONG    combilast;
1234     WORD    nincoef;
1235     WORD    level;
1236     WORD    thefunction;
1237     WORD    option;
1238     PADPOINTER(1,0,4,0);
1239 } SHvariables;
1240 
1241 typedef struct {                /* Used for computing calculational cost in optim.c */
1242     LONG    add;
1243     LONG    mul;
1244     LONG    div;
1245     LONG    pow;
1246 } COST;
1247 
1248 typedef struct {
1249     UWORD   *a;     /* The number array */
1250     UWORD   *m;     /* The modulus array */
1251     WORD    na;     /* Size of the number */
1252     WORD    nm;     /* size of the number in the modulus array */
1253 } MODNUM;
1254 
1255 /*
1256     Struct for optimizing outputs. If changed, do not forget to change
1257     the padding information in the AO struct.
1258 */
1259 typedef struct {
1260     union { /* we do this to allow padding */
1261         float fval;
1262         int ival[2]; /* This should be enough */
1263     } mctsconstant;
1264     int   horner;
1265     int   hornerdirection;
1266     int   method;
1267     int   mctstimelimit;
1268     int   mctsnumexpand;
1269     int   mctsnumkeep;
1270     int   mctsnumrepeat;
1271     int   greedytimelimit;
1272     int   greedyminnum;
1273     int   greedymaxperc;
1274     int   printstats;
1275     int   debugflags;
1276     int   schemeflags;
1277     int   mctsdecaymode;
1278     int   saIter; /* Simulated annealing updates */
1279     union {
1280         float fval;
1281         int ival[2];
1282     } saMaxT; /* Maximum temperature of SA */
1283     union {
1284         float fval;
1285         int ival[2];
1286     } saMinT; /* Minimum temperature of SA */
1287 } OPTIMIZE;
1288 
1289 typedef struct {
1290     WORD  *code;
1291     UBYTE *nameofexpr;  /* It is easier to remember an expression by name */
1292     LONG  codesize;     /* We need this for the checkpoints */
1293     WORD  exprnr;       /* Problem here is: we renumber them in execute.c */
1294     WORD  minvar;
1295     WORD  maxvar;
1296 
1297     PADPOSITION(2,1,0,3,0);
1298 } OPTIMIZERESULT;
1299 
1300 typedef struct {
1301     WORD *lhs;      /* Object to be replaced */
1302     WORD *rhs;      /* Depending on the type it will be UBYTE* or WORD* */
1303     int type;
1304     int size;       /* Size of the lhs */
1305 } DICTIONARY_ELEMENT;
1306 
1307 typedef struct {
1308     DICTIONARY_ELEMENT **elements;
1309     UBYTE *name;
1310     int sizeelements;
1311     int numelements;
1312     int numbers;        /* deal with numbers */
1313     int variables;      /* deal with single variables */
1314     int characters;     /* deal with special characters */
1315     int funwith;        /* deal with functions with arguments */
1316     int gnumelements;   /* if .global shrinks the dictionary */
1317     int ranges;
1318 } DICTIONARY;
1319 
1320 typedef struct {
1321 	WORD ncase;
1322 	WORD value;
1323 	WORD compbuffer;
1324 } SWITCHTABLE;
1325 
1326 typedef struct {
1327 	SWITCHTABLE *table;
1328 	SWITCHTABLE defaultcase;
1329 	SWITCHTABLE endswitch;
1330 	WORD typetable;
1331 	WORD maxcase;
1332 	WORD mincase;
1333 	WORD numcases;
1334 	WORD tablesize;
1335 	WORD caseoffset;
1336 	WORD iflevel;
1337 	WORD whilelevel;
1338 	WORD nestingsum;
1339     WORD padding;
1340 } SWITCH;
1341 
1342 /*
1343 	The next typedef comes originally from declare.h but because new compilers
1344 	do not like casting from void * to a function address we have to put it here
1345 */
1346 
1347 /*
1348   	#] Varia :
1349     #[ A :
1350  		#[ M : The M struct is for global settings at startup or .clear
1351 */
1352 
1353 /**
1354  *	The M_const struct is part of the global data and resides in the #ALLGLOBALS
1355  *	struct #A under the name #M.
1356  *	We see it used with the macro #AM as in AM.S0.
1357  *	It contains global settings at startup or .clear.
1358  */
1359 
1360 struct M_const {
1361     POSITION zeropos;              /* (M) is zero */
1362     SORTING *S0;                   /**< [D] The main sort buffer */
1363     UWORD   *gcmod;                /**< Global setting of modulus. Uses AC.cmod's memory */
1364     UWORD   *gpowmod;              /**< Global setting printing as powers. Uses AC.cmod's memory */
1365     UBYTE   *TempDir;              /* (M) Path with where the temporary files go */
1366     UBYTE   *TempSortDir;          /* (M) Path with where the sort files go */
1367     UBYTE   *IncDir;               /* (M) Directory path for include files */
1368     UBYTE   *InputFileName;        /* (M) */
1369     UBYTE   *LogFileName;          /* (M) */
1370     UBYTE   *OutBuffer;            /* (M) Output buffer in pre.c */
1371     UBYTE   *Path;                 /* (M) */
1372     UBYTE   *SetupDir;             /* (M) Directory with setup file */
1373     UBYTE   *SetupFile;            /* (M) Name of setup file */
1374     UBYTE   *gFortran90Kind;
1375 	UBYTE   *gextrasym;
1376 	UBYTE   *ggextrasym;
1377     UBYTE   *oldnumextrasymbols;
1378 	SPECTATOR *SpectatorFiles;
1379 #ifdef WITHPTHREADS
1380     pthread_rwlock_t handlelock;   /* (M) */
1381     pthread_mutex_t storefilelock; /* (M) */
1382 	pthread_mutex_t	sbuflock;      /* (M) Lock for writing in the AM.sbuffer */
1383     LONG    ThreadScratSize;       /* (M) Size of Fscr[0/2] buffers of the workers */
1384     LONG    ThreadScratOutSize;    /* (M) Size of Fscr[1] buffers of the workers */
1385 #endif
1386     LONG    MaxTer;                /* (M) Maximum term size. Fixed at setup. In Bytes!!!*/
1387     LONG    CompressSize;          /* (M) Size of Compress buffer */
1388     LONG    ScratSize;             /* (M) Size of Fscr[] buffers */
1389     LONG    HideSize;              /* (M) Size of Fscr[2] buffer */
1390     LONG    SizeStoreCache;        /* (M) Size of the chaches for reading global expr. */
1391     LONG    MaxStreamSize;         /* (M) Maximum buffer size in reading streams */
1392     LONG    SIOsize;               /* (M) Sort InputOutput buffer size */
1393     LONG    SLargeSize;            /* (M) */
1394     LONG    SSmallEsize;           /* (M) */
1395     LONG    SSmallSize;            /* (M) */
1396     LONG    STermsInSmall;         /* (M) */
1397     LONG    MaxBracketBufferSize;  /* (M) Max Size for B+ or AB+ per expression */
1398     LONG    hProcessBucketSize;    /* (M) */
1399     LONG    gProcessBucketSize;    /* (M) */
1400     LONG    shmWinSize;            /* (M) size for shared memory window used in communications */
1401     LONG    OldChildTime;          /* (M) Zero time. Needed in timer. */
1402     LONG    OldSecTime;            /* (M) Zero time for measuring wall clock time */
1403     LONG    OldMilliTime;          /* (M) Same, but milli seconds */
1404     LONG    WorkSize;              /* (M) Size of WorkSpace */
1405     LONG    gThreadBucketSize;     /* (C) */
1406     LONG    ggThreadBucketSize;    /* (C) */
1407     LONG    SumTime;               /*     Used in .clear */
1408     LONG    SpectatorSize;         /*     Size of the buffer in bytes */
1409     LONG    TimeLimit;             /*     Limit in sec to the total real time */
1410     int     FileOnlyFlag;          /* (M) Writing only to file */
1411     int     Interact;              /* (M) Interactive mode flag */
1412     int     MaxParLevel;           /* (M) Maximum nesting of parantheses */
1413     int     OutBufSize;            /* (M) size of OutBuffer */
1414     int     SMaxFpatches;          /* (M) */
1415     int     SMaxPatches;           /* (M) */
1416     int     StdOut;                /* (M) Regular output channel */
1417     int     ginsidefirst;          /* (M) Not used yet */
1418     int     gDefDim;               /* (M) */
1419     int     gDefDim4;              /* (M) */
1420     int     NumFixedSets;          /* (M) Number of the predefined sets */
1421     int     NumFixedFunctions;     /* (M) Number of built in functions */
1422     int     rbufnum;               /* (M) startup compiler buffer */
1423     int     dbufnum;               /* (M) dollar variables */
1424     int     sbufnum;               /* (M) subterm variables */
1425     int     zbufnum;               /* (M) special values */
1426     int     SkipClears;            /* (M) Number of .clear to skip at start */
1427     int     gTokensWriteFlag;      /* (M) */
1428     int     gfunpowers;            /* (M) */
1429     int     gStatsFlag;            /* (M) */
1430     int     gNamesFlag;            /* (M) */
1431     int     gCodesFlag;            /* (M) */
1432     int     gSortType;             /* (M) */
1433     int     gproperorderflag;      /* (M) */
1434     int     hparallelflag;         /* (M) */
1435     int     gparallelflag;         /* (M) */
1436     int     totalnumberofthreads;  /* (M) */
1437     int     gSizeCommuteInSet;
1438     int     gThreadStats;
1439     int     ggThreadStats;
1440     int     gFinalStats;
1441     int     ggFinalStats;
1442     int     gThreadsFlag;
1443     int     ggThreadsFlag;
1444     int     gThreadBalancing;
1445     int     ggThreadBalancing;
1446     int     gThreadSortFileSynch;
1447     int     ggThreadSortFileSynch;
1448     int     gProcessStats;
1449     int     ggProcessStats;
1450     int     gOldParallelStats;
1451     int     ggOldParallelStats;
1452     int     maxFlevels;            /* () maximum function levels */
1453     int     resetTimeOnClear;      /* (M) */
1454     int     gcNumDollars;          /* () number of dollars for .clear */
1455     int     MultiRun;
1456     int     gNoSpacesInNumbers;    /* For very long numbers */
1457     int     ggNoSpacesInNumbers;   /* For very long numbers */
1458     int     gIsFortran90;
1459 	int		PrintTotalSize;
1460     int     fbuffersize;           /* Size for the AT.fbufnum factorization caches */
1461     int     gOldFactArgFlag;
1462     int     ggOldFactArgFlag;
1463     int     gnumextrasym;
1464     int     ggnumextrasym;
1465 	int		NumSpectatorFiles;     /* Elements used in AM.spectatorfiles; */
1466 	int		SizeForSpectatorFiles; /* Size in AM.spectatorfiles; */
1467     int     gOldGCDflag;
1468     int     ggOldGCDflag;
1469     int     gWTimeStatsFlag;
1470     int     ggWTimeStatsFlag;
1471     int     jumpratio;
1472     WORD    MaxTal;                /* (M) Maximum number of words in a number */
1473     WORD    IndDum;                /* (M) Basis value for dummy indices */
1474     WORD    DumInd;                /* (M) */
1475     WORD    WilInd;                /* (M) Offset for wildcard indices */
1476     WORD    gncmod;                /* (M) Global setting of modulus. size of gcmod */
1477     WORD    gnpowmod;              /* (M) Global printing as powers. size gpowmod */
1478     WORD    gmodmode;              /* (M) Global mode for modulus */
1479     WORD    gUnitTrace;            /* (M) Global value of Tr[1] */
1480     WORD    gOutputMode;           /* (M) */
1481     WORD    gOutputSpaces;         /* (M) */
1482     WORD    gOutNumberType;        /* (M) */
1483     WORD    gCnumpows;             /* (M) */
1484     WORD    gUniTrace[4];          /* (M) */
1485     WORD    MaxWildcards;          /* (M) Maximum number of wildcards */
1486     WORD    mTraceDum;             /* (M) Position/Offset for generated dummies */
1487     WORD    OffsetIndex;           /* (M) */
1488     WORD    OffsetVector;          /* (M) */
1489     WORD    RepMax;                /* (M) Max repeat levels */
1490     WORD    LogType;               /* (M) Type of writing to log file */
1491     WORD    ggStatsFlag;           /* (M) */
1492     WORD    gLineLength;           /* (M) */
1493     WORD    qError;                /* (M) Only error checking {-c option} */
1494     WORD    FortranCont;           /* (M) Fortran Continuation character */
1495     WORD    HoldFlag;              /* (M) Exit on termination? */
1496     WORD    Ordering[15];          /* (M) Auxiliary for ordering wildcards */
1497     WORD    silent;                /* (M) Silent flag. Only results in output. */
1498     WORD    tracebackflag;         /* (M) For tracing errors */
1499     WORD    expnum;                /* (M) internal number of ^ function */
1500     WORD    denomnum;              /* (M) internal number of / function */
1501     WORD    facnum;                /* (M) internal number of fac_ function */
1502     WORD    invfacnum;             /* (M) internal number of invfac_ function */
1503     WORD    sumnum;                /* (M) internal number of sum_ function */
1504     WORD    sumpnum;               /* (M) internal number of sump_ function */
1505     WORD    OldOrderFlag;          /* (M) Flag for allowing old statement order */
1506     WORD    termfunnum;            /* (M) internal number of term_ function */
1507     WORD    matchfunnum;           /* (M) internal number of match_ function */
1508     WORD    countfunnum;           /* (M) internal number of count_ function */
1509     WORD    gPolyFun;              /* (M) global value of PolyFun */
1510     WORD    gPolyFunInv;           /* (M) global value of Inverse of PolyFun */
1511     WORD    gPolyFunType;          /* (M) global value of PolyFun */
1512     WORD    gPolyFunExp;
1513     WORD    gPolyFunVar;
1514     WORD    gPolyFunPow;
1515     WORD    dollarzero;            /* (M) for dollars with zero value */
1516     WORD    atstartup;             /* To protect against DATE_ ending in \n */
1517     WORD    exitflag;              /* (R) For the exit statement */
1518     WORD    NumStoreCaches;        /* () Number of storage caches per processor */
1519     WORD    gIndentSpace;          /* For indentation in output */
1520     WORD    ggIndentSpace;
1521     WORD    gShortStatsMax;        /**< For  On FewerStatistics 10; */
1522     WORD    ggShortStatsMax;       /**< For  On FewerStatistics 10; */
1523     WORD    gextrasymbols;
1524     WORD    ggextrasymbols;
1525     WORD    zerorhs;
1526     WORD    onerhs;
1527     WORD    havesortdir;
1528     WORD    vectorzero;            /* p0_ */
1529     WORD    ClearStore;
1530     WORD    BracketFactors[8];
1531 #ifdef WITHPTHREADS
1532 	PADPOSITION(17,26,62,83,(sizeof(pthread_rwlock_t)+sizeof(pthread_mutex_t)*2));
1533 #else
1534 	PADPOSITION(17,24,62,83,0);
1535 #endif
1536 };
1537 /*
1538  		#] M :
1539  		#[ P : The P struct defines objects set by the preprocessor
1540 */
1541 /**
1542  *  The P_const struct is part of the global data and resides in the
1543  *  ALLGLOBALS struct A under the name P
1544  *  We see it used with the macro AP as in AP.InOutBuf
1545  *  It contains objects that have dealings with the preprocessor.
1546  */
1547 
1548 struct P_const {
1549     LIST DollarList;               /* (R) Dollar variables. Contains pointers
1550                                        to contents of the variables.*/
1551     LIST PreVarList;               /* (R) List of preprocessor variables
1552                                        Points to contents. Can be changed */
1553     LIST LoopList;                 /* (P) List of do loops */
1554     LIST ProcList;                 /* (P) List of procedures */
1555     INSIDEINFO inside;             /*     Information during #inside/#endinside */
1556     UBYTE **PreSwitchStrings;      /* (P) The string in a switch */
1557     UBYTE *preStart;               /* (P) Preprocessor instruction buffer */
1558     UBYTE *preStop;                /* (P) end of preStart */
1559     UBYTE *preFill;                /* (P) Filling point in preStart */
1560     UBYTE *procedureExtension;     /* (P) Extension for procedure files (prc) */
1561     UBYTE *cprocedureExtension;    /* (P) Extension after .clear */
1562     LONG  *PreAssignStack;         /* For nesting #$name assignments */
1563     int *PreIfStack;               /* (P) Tracks nesting of #if */
1564     int *PreSwitchModes;           /* (P) Stack of switch status */
1565     int *PreTypes;                 /* (P) stack of #call, #do etc nesting */
1566 #ifdef WITHPTHREADS
1567     pthread_mutex_t PreVarLock;    /* (P) */
1568 #endif
1569     LONG    StopWatchZero;         /* For `timer_' and #reset timer */
1570     LONG    InOutBuf;              /* (P) Characters in the output buf in pre.c */
1571     LONG    pSize;                 /* (P) size of preStart */
1572     int     PreAssignFlag;         /* (C) Indicates #assign -> catch dollar */
1573     int     PreContinuation;       /* (C) Indicates whether the statement is new */
1574     int     PreproFlag;            /* (P) Internal use to mark work on prepro instr. */
1575     int     iBufError;             /* (P) Flag for errors with input buffer */
1576     int     PreOut;                /* (P) Flag for #+ #- */
1577     int     PreSwitchLevel;        /* (P) Nesting of #switch */
1578     int     NumPreSwitchStrings;   /* (P) Size of PreSwitchStrings */
1579     int     MaxPreTypes;           /* (P) Size of PreTypes */
1580     int     NumPreTypes;           /* (P) Number of nesting objects in PreTypes */
1581     int     MaxPreIfLevel;         /* (C) Maximum number of nested #if. Dynamic */
1582     int     PreIfLevel;            /* (C) Current position if PreIfStack */
1583     int     PreInsideLevel;        /* (C) #inside active? */
1584     int     DelayPrevar;           /* (P) Delaying prevar substitution */
1585     int     AllowDelay;            /* (P) Allow delayed prevar substitution */
1586     int     lhdollarerror;         /* (R) */
1587     int     eat;                   /* () */
1588     int     gNumPre;               /* (P) Number of preprocessor variables for .clear */
1589     int     PreDebug;              /* (C) */
1590     int     OpenDictionary;
1591     int     PreAssignLevel;        /* For nesting #$name = ...; assignments */
1592     int     MaxPreAssignLevel;     /* For nesting #$name = ...; assignments */
1593     WORD    DebugFlag;             /* (P) For debugging purposes */
1594     WORD    preError;              /* (P) Blocks certain types of execution */
1595     UBYTE   ComChar;               /* (P) Commentary character */
1596     UBYTE   cComChar;              /* (P) Old commentary character for .clear */
1597     PADPOINTER(3,21,2,2);
1598 };
1599 
1600 /*
1601  		#] P :
1602  		#[ C : The C struct defines objects changed by the compiler
1603 */
1604 
1605 /**
1606  *  The C_const struct is part of the global data and resides in the #ALLGLOBALS
1607  *  struct #A under the name #C.
1608  *  We see it used with the macro #AC as in AC.exprnames.
1609  *  It contains variables that involve the compiler and objects set during
1610  *  compilation.
1611  */
1612 
1613 struct C_const {
1614     set_of_char separators;        /**< Separators in #call and #do */
1615 	POSITION StoreFileSize;        /* () Size of store file */
1616     NAMETREE *dollarnames;         /**< [D] Names of dollar variables */
1617     NAMETREE *exprnames;           /**< [D] Names of expressions */
1618     NAMETREE *varnames;            /**< [D] Names of regular variables */
1619     LIST    ChannelList;           /**< Used for the #write statement. Contains #CHANNEL */
1620                                    /*     Later also for write? */
1621     LIST    DubiousList;           /**< List of dubious variables. Contains #DUBIOUSV.
1622                                         If not empty -> no execution */
1623     LIST    FunctionList;          /**< List of functions and properties. Contains #FUNCTIONS */
1624     LIST    ExpressionList;        /**< List of expressions, locations etc. */
1625     LIST    IndexList;             /**< List of indices */
1626     LIST    SetElementList;        /**< List of all elements of all sets */
1627     LIST    SetList;               /**< List of the sets */
1628     LIST    SymbolList;            /**< List of the symbols and their properties */
1629     LIST    VectorList;            /**< List of the vectors */
1630     LIST    PotModDolList;         /**< Potentially changed dollars */
1631     LIST    ModOptDolList;         /**< Module Option Dollars list */
1632     LIST    TableBaseList;         /**< TableBase list */
1633 /*
1634     Compile buffer variables
1635 */
1636     LIST    cbufList;              /**< List of compiler buffers */
1637 /*
1638     Objects for auto declarations
1639 */
1640     LIST    AutoSymbolList;        /* (C) */
1641     LIST    AutoIndexList;         /* (C) */
1642     LIST    AutoVectorList;        /* (C) */
1643     LIST    AutoFunctionList;      /* (C) */
1644     NAMETREE *autonames;           /**< [D] Names in autodeclare */
1645 
1646     LIST    *Symbols;              /* (C) Pointer for autodeclare. Which list is
1647                                       it searching. Later also for subroutines */
1648     LIST    *Indices;              /* (C) id. */
1649     LIST    *Vectors;              /* (C) id. */
1650     LIST    *Functions;            /* (C) id. */
1651     NAMETREE **activenames;        /** (C) Pointer for AutoDeclare statement. Points either to
1652                                            varnames or autonames. */
1653     STREAM  *Streams;              /**< [D] The input streams. */
1654     STREAM  *CurrentStream;        /**< (C) The current input stream.
1655                                        Streams are: do loop, file, prevariable. points into Streams memory. */
1656     SWITCH  *SwitchArray;
1657     WORD    *SwitchHeap;
1658     LONG    *termstack;            /**< [D] Last term statement {offset} */
1659     LONG    *termsortstack;        /**< [D] Last sort statement {offset} */
1660     UWORD   *cmod;                 /**< [D] Local setting of modulus. Pointer to value. */
1661     UWORD   *powmod;               /**< Local setting printing as powers. Points into cmod memory */
1662     UWORD   *modpowers;            /**< [D] The conversion table for mod-> powers. */
1663 	UWORD   *halfmod;              /* (C) half the modulus when not zero */
1664     WORD    *ProtoType;            /* (C) The subexpression prototype {wildcards} */
1665     WORD    *WildC;                /* (C) Filling point for wildcards. */
1666     LONG    *IfHeap;               /**< [D] Keeps track of where to go in if */
1667     LONG    *IfCount;              /**< [D] Keeps track of where to go in if */
1668     LONG    *IfStack;              /**< Keeps track of where to go in if. Points into IfHeap-memory */
1669     UBYTE   *iBuffer;              /**< [D] Compiler input buffer */
1670     UBYTE   *iPointer;             /**< Running pointer in the compiler input buffer */
1671     UBYTE   *iStop;                /**< Top of iBuffer */
1672     UBYTE   **LabelNames;          /**< [D] List of names in label statements */
1673     WORD    *FixIndices;           /**< [D] Buffer of fixed indices */
1674     WORD    *termsumcheck;         /**< [D] Checking of nesting */
1675     UBYTE   *WildcardNames;        /**< [D] Names of ?a variables */
1676     int     *Labels;               /**< Label information for during run. Pointer into LabelNames memory. */
1677     SBYTE   *tokens;               /**< [D] Array with tokens for tokenizer */
1678     SBYTE   *toptokens;            /**< Top of tokens */
1679     SBYTE   *endoftokens;          /**< End of the actual tokens */
1680     WORD    *tokenarglevel;        /**< [D] Keeps track of function arguments */
1681 	UWORD   *modinverses;          /* Table for inverses of primes */
1682     UBYTE   *Fortran90Kind;        /* The kind of number in Fortran 90 as in _ki */
1683 	WORD	**MultiBracketBuf;     /* Array of buffers for multi-level brackets */
1684 	UBYTE   *extrasym;             /* Array with the name for extra symbols in ToPolynomial */
1685 	WORD    *doloopstack;          /* To keep track of begin and end of doloops */
1686 	WORD    *doloopnest;           /* To keep track of nesting of doloops etc */
1687     char    *CheckpointRunAfter;   /**< [D] Filename of script to be executed _before_ creating the
1688                                         snapshot. =0 if no script shall be executed. */
1689     char    *CheckpointRunBefore;  /**< [D] Filename of script to be executed _after_ having
1690                                         created the snapshot. =0 if no script shall be executed.*/
1691     WORD    *IfSumCheck;           /**< [D] Keeps track of if-nesting */
1692     WORD    *CommuteInSet;         /* groups of noncommuting functions that can commute */
1693     UBYTE   *TestValue;            /* For debugging */
1694 #ifdef PARALLELCODE
1695     LONG    *inputnumbers;         /**< [D] For redefine */
1696     WORD    *pfirstnum;            /**< For redefine. Points into inputnumbers memory */
1697 #endif
1698 #ifdef WITHPTHREADS
1699     pthread_mutex_t halfmodlock;   /* () Lock for adding buffer for halfmod */
1700 #endif
1701     LONG    argstack[MAXNEST];     /* (C) {contents} Stack for nesting of Argument */
1702     LONG    insidestack[MAXNEST];  /* (C) {contents} Stack for Argument or Inside. */
1703     LONG    inexprstack[MAXNEST];  /* (C) {contents} Stack for Argument or Inside. */
1704     LONG    iBufferSize;           /* (C) Size of the input buffer */
1705     LONG    TransEname;            /* (C) Used when a new definition overwrites
1706                                        an old expression. */
1707     LONG    ProcessBucketSize;     /* (C) */
1708     LONG    mProcessBucketSize;    /* (C) */
1709     LONG    CModule;               /* (C) Counter of current module */
1710     LONG    ThreadBucketSize;      /* (C) Roughly the maximum number of input terms */
1711     LONG    CheckpointStamp;       /**< Timestamp of the last created snapshot (set to Timer(0)).*/
1712     LONG    CheckpointInterval;    /**< Time interval in milliseconds for snapshots. =0 if
1713                                         snapshots shall be created at the end of _every_ module.*/
1714     int     cbufnum;               /**< Current compiler buffer */
1715     int     AutoDeclareFlag;       /** (C) Mode of looking for names. Set to NOAUTO (=0) or
1716                                            WITHAUTO (=2), cf. AutoDeclare statement */
1717     int     NoShowInput;           /* (C) No listing of input as in .prc, #do */
1718     int     ShortStats;            /* (C) */
1719     int     compiletype;           /* (C) type of statement {DECLARATION etc} */
1720     int     firstconstindex;       /* (C) flag for giving first error message */
1721     int     insidefirst;           /* (C) Not used yet */
1722     int     minsidefirst;          /* (?) Not used yet */
1723     int     wildflag;              /* (C) Flag for marking use of wildcards */
1724     int     NumLabels;             /* (C) Number of labels {in Labels} */
1725     int     MaxLabels;             /* (C) Size of Labels array */
1726     int     lDefDim;               /* (C) */
1727     int     lDefDim4;              /* (C) */
1728     int     NumWildcardNames;      /* (C) Number of ?a variables */
1729     int     WildcardBufferSize;    /* (C) size of WildcardNames buffer */
1730     int     MaxIf;                 /* (C) size of IfHeap, IfSumCheck, IfCount */
1731     int     NumStreams;            /* (C) */
1732     int     MaxNumStreams;         /* (C) */
1733     int     firstctypemessage;     /* (C) Flag for giving first st order error */
1734     int     tablecheck;            /* (C) For table checking */
1735     int     idoption;              /* (C) */
1736     int     BottomLevel;           /* (C) For propercount. Not used!!! */
1737     int     CompileLevel;          /* (C) Subexpression level */
1738     int     TokensWriteFlag;       /* (C) */
1739     int     UnsureDollarMode;      /* (C)?Controls error messages undefined $'s */
1740     int     outsidefun;            /* (C) Used for writing Tables to file */
1741     int     funpowers;             /* (C) */
1742     int     WarnFlag;              /* (C) */
1743     int     StatsFlag;             /* (C) */
1744     int     NamesFlag;             /* (C) */
1745     int     CodesFlag;             /* (C) */
1746     int     SetupFlag;             /* (C) */
1747     int     SortType;              /* (C) */
1748     int     lSortType;             /* (C) */
1749     int     ThreadStats;           /* (C) */
1750     int     FinalStats;            /* (C) */
1751     int     OldParallelStats;      /* (C) */
1752     int     ThreadsFlag;
1753     int     ThreadBalancing;
1754     int     ThreadSortFileSynch;
1755     int     ProcessStats;          /* (C) */
1756     int     BracketNormalize;      /* (C) Indicates whether the bracket st is normalized */
1757     int     maxtermlevel;          /* (C) Size of termstack */
1758     int     dumnumflag;            /* (C) Where there dummy indices in tokenizer? */
1759     int     bracketindexflag;      /* (C) Are brackets going to be indexed? */
1760     int     parallelflag;          /* (C) parallel allowed? */
1761     int     mparallelflag;         /* (C) parallel allowed in this module? */
1762     int     inparallelflag;        /* (C) inparallel allowed? */
1763     int     partodoflag;           /* (C) parallel allowed? */
1764     int     properorderflag;       /* (C) clean normalizing. */
1765     int     vetofilling;           /* (C) vetoes overwriting in tablebase stubs */
1766     int     tablefilling;          /* (C) to notify AddRHS we are filling a table */
1767     int     vetotablebasefill;     /* (C) For the load in tablebase */
1768     int     exprfillwarning;       /* (C) Warning has been printed for expressions in fill statements */
1769     int     lhdollarflag;          /* (R) left hand dollar present */
1770     int     NoCompress;            /* (R) Controls native compression */
1771     int     IsFortran90;           /* Tells whether the Fortran is Fortran90 */
1772     int     MultiBracketLevels;    /* Number of elements in MultiBracketBuf */
1773     int     topolynomialflag;      /* To avoid ToPolynomial and FactArg together */
1774     int     ffbufnum;              /* Buffer number for user defined factorizations */
1775     int     OldFactArgFlag;
1776     int     MemDebugFlag;          /* Only used when MALLOCDEBUG in tools.c */
1777     int     OldGCDflag;
1778     int     WTimeStatsFlag;
1779 	int     doloopstacksize;
1780 	int     dolooplevel;
1781     int     CheckpointFlag;        /**< Tells preprocessor whether checkpoint code must executed.
1782                                         -1 : do recovery from snapshot, set by command line option;
1783                                         0 : do nothing; 1 : create snapshots, set by On checkpoint
1784                                         statement */
1785     int     SizeCommuteInSet;      /* Size of the CommuteInSet buffer */
1786 #ifdef PARALLELCODE
1787     int     numpfirstnum;          /* For redefine */
1788     int     sizepfirstnum;         /* For redefine */
1789 #endif
1790     int     origin;                /* Determines whether .sort or ModuleOption */
1791     int     vectorlikeLHS;
1792     WORD    argsumcheck[MAXNEST];  /* (C) Checking of nesting */
1793     WORD    insidesumcheck[MAXNEST];/* (C) Checking of nesting */
1794     WORD    inexprsumcheck[MAXNEST];/* (C) Checking of nesting */
1795     WORD    RepSumCheck[MAXREPEAT];/* (C) Checks nesting of repeat, if, argument */
1796     WORD    lUniTrace[4];          /* (C) */
1797     WORD    RepLevel;              /* (C) Tracks nesting of repeat. */
1798     WORD    arglevel;              /* (C) level of nested argument statements */
1799     WORD    insidelevel;           /* (C) level of nested inside statements */
1800     WORD    inexprlevel;           /* (C) level of nested inexpr statements */
1801     WORD    termlevel;             /* (C) level of nested term statements */
1802     WORD    MustTestTable;         /* (C) Indicates whether tables have been changed */
1803     WORD    DumNum;                /* (C) */
1804     WORD    ncmod;                 /* (C) Local setting of modulus. size of cmod */
1805     WORD    npowmod;               /* (C) Local printing as powers. size powmod */
1806     WORD    modmode;               /* (C) Mode for modulus calculus */
1807 	WORD	nhalfmod;              /* relevant word size of halfmod when defined */
1808     WORD    DirtPow;               /* (C) Flag for changes in printing mod powers */
1809     WORD    lUnitTrace;            /* (C) Local value of Tr[1] */
1810     WORD    NwildC;                /* (C) Wildcard counter */
1811     WORD    ComDefer;              /* (C) defer brackets */
1812     WORD    CollectFun;            /* (C) Collect function number */
1813     WORD    AltCollectFun;         /* (C) Alternate Collect function number */
1814     WORD    OutputMode;            /* (C) */
1815     WORD    Cnumpows;
1816     WORD    OutputSpaces;          /* (C) */
1817     WORD    OutNumberType;         /* (C) Controls RATIONAL/FLOAT output */
1818     WORD    DidClean;              /* (C) Test whether nametree needs cleaning */
1819     WORD    IfLevel;               /* (C) */
1820     WORD    WhileLevel;            /* (C) */
1821     WORD    SwitchLevel;
1822     WORD    SwitchInArray;
1823     WORD    MaxSwitch;
1824     WORD    LogHandle;             /* (C) The Log File */
1825     WORD    LineLength;            /* (C) */
1826     WORD    StoreHandle;           /* (C) Handle of .str file */
1827     WORD    HideLevel;             /* (C) Hiding indicator */
1828     WORD    lPolyFun;              /* (C) local value of PolyFun */
1829     WORD    lPolyFunInv;           /* (C) local value of Inverse of PolyFun */
1830     WORD    lPolyFunType;          /* (C) local value of PolyFunType */
1831     WORD    lPolyFunExp;
1832     WORD    lPolyFunVar;
1833     WORD    lPolyFunPow;
1834     WORD    SymChangeFlag;         /* (C) */
1835     WORD    CollectPercentage;     /* (C) Collect function percentage */
1836     WORD    ShortStatsMax;         /* For  On FewerStatistics 10; */
1837 	WORD	extrasymbols;          /* Flag for the extra symbsols output mode */
1838     WORD    PolyRatFunChanged;     /* Keeps track whether we changed in the compiler */
1839     WORD    ToBeInFactors;
1840     WORD    InnerTest;            /* For debugging */
1841 #ifdef WITHMPI
1842     WORD    RhsExprInModuleFlag;   /* (C) Set by the compiler if RHS expressions exists. */
1843 #endif
1844     UBYTE   Commercial[COMMERCIALSIZE+2]; /* (C) Message to be printed in statistics */
1845     UBYTE   debugFlags[MAXFLAGS+2];    /* On/Off Flag number(s) */
1846 #if defined(WITHPTHREADS)
1847 	PADPOSITION(49,8+3*MAXNEST,72,48+3*MAXNEST+MAXREPEAT,COMMERCIALSIZE+MAXFLAGS+4+sizeof(LIST)*17+sizeof(pthread_mutex_t));
1848 #elif defined(WITHMPI)
1849 	PADPOSITION(49,8+3*MAXNEST,72,49+3*MAXNEST+MAXREPEAT,COMMERCIALSIZE+MAXFLAGS+4+sizeof(LIST)*17);
1850 #else
1851 	PADPOSITION(47,8+3*MAXNEST,70,48+3*MAXNEST+MAXREPEAT,COMMERCIALSIZE+MAXFLAGS+4+sizeof(LIST)*17);
1852 #endif
1853 };
1854 /*
1855  		#] C :
1856  		#[ S : The S struct defines objects changed at the start of the run (Processor)
1857 		       Basically only set by the master.
1858 */
1859 /**
1860  *	The S_const struct is part of the global data and resides in the
1861  *	ALLGLOBALS struct A under the name S
1862  *	We see it used with the macro AS as in AS.ExecMode
1863  *	It has some variables used by the master in multithreaded runs
1864  */
1865 
1866 struct S_const {
1867 	POSITION MaxExprSize;          /* ( ) Maximum size of in/out/sort */
1868 #ifdef WITHPTHREADS
1869 	pthread_mutex_t	inputslock;
1870 	pthread_mutex_t	outputslock;
1871 	pthread_mutex_t	MaxExprSizeLock;
1872 #endif
1873     POSITION *OldOnFile;           /* (S) File positions of expressions */
1874     WORD    *OldNumFactors;        /* ( ) NumFactors in (old) expression */
1875     WORD    *Oldvflags;            /* ( ) vflags in (old) expression */
1876     int     NumOldOnFile;          /* (S) Number of expressions in OldOnFile */
1877     int     NumOldNumFactors;      /* (S) Number of expressions in OldNumFactors */
1878     int     MultiThreaded;         /* (S) Are we running multi-threaded? */
1879 #ifdef WITHPTHREADS
1880     int     MasterSort;            /* Final stage of sorting to the master */
1881 #endif
1882 #ifdef WITHMPI
1883     int     printflag;             /* controls MesPrint() on each slave */
1884 #endif
1885     int     Balancing;             /* For second stage loadbalancing */
1886     WORD    ExecMode;              /* (S) */
1887 
1888     WORD    CollectOverFlag;       /* (R) Indicates overflow at Collect */
1889 #ifdef WITHPTHREADS
1890 	WORD	sLevel;                /* Copy of AR0.sLevel because it can get messy */
1891 #endif
1892 #if defined(WITHPTHREADS)
1893 	PADPOSITION(3,0,5,3,sizeof(pthread_mutex_t)*3);
1894 #elif defined(WITHMPI)
1895 	PADPOSITION(3,0,5,2,0);
1896 #else
1897 	PADPOSITION(3,0,4,2,0);
1898 #endif
1899 };
1900 /*
1901  		#] S :
1902  		#[ R : The R struct defines objects changed at run time.
1903                They determine the environment that has to be transfered
1904                together with a term during multithreaded execution.
1905 */
1906 /**
1907  *  The R_const struct is part of the global data and resides either in the
1908  *  ALLGLOBALS struct A, or the ALLPRIVATES struct B (TFORM) under the name R
1909  *  We see it used with the macro AR as in AR.infile
1910  *  It has the variables that define the running environment and that
1911  *  should be transferred with a term in a multithreaded run.
1912  */
1913 
1914 struct R_const {
1915     FILEDATA    StoreData;         /* (O) */
1916     FILEHANDLE  Fscr[3];           /* (R) Dollars etc play with it too */
1917     FILEHANDLE  FoStage4[2];       /* (R) In Sort. Stage 4. */
1918     POSITION DefPosition;          /* (R) Deferred position of keep brackets. */
1919     FILEHANDLE *infile;            /* (R) Points alternatingly to Fscr[0] or Fscr[1] */
1920     FILEHANDLE *outfile;           /* (R) Points alternatingly to Fscr[1] or Fscr[0] */
1921     FILEHANDLE *hidefile;          /* (R) Points to Fscr[2] */
1922 
1923     WORD    *CompressBuffer;       /* (M) */
1924     WORD    *ComprTop;             /* (M) */
1925     WORD    *CompressPointer;      /* (R) */
1926     COMPARE CompareRoutine;
1927     ULONG   *wranfia;
1928 
1929     LONG    OldTime;               /* (R) Zero time. Needed in timer. */
1930     LONG    InInBuf;               /* (R) Characters in input buffer. Scratch files. */
1931     LONG    InHiBuf;               /* (R) Characters in hide buffer. Scratch file. */
1932     LONG    pWorkSize;             /* (R) Size of pWorkSpace */
1933     LONG    lWorkSize;             /* (R) Size of lWorkSpace */
1934     LONG    posWorkSize;           /* (R) Size of posWorkSpace */
1935 	ULONG   wranfseed;
1936     int     NoCompress;            /* (R) Controls native compression */
1937     int     gzipCompress;          /* (R) Controls gzip compression */
1938     int     Cnumlhs;               /* Local copy of cbuf[rbufnum].numlhs */
1939 	int     outtohide;             /* Indicates that output is directly to hide */
1940 #ifdef WITHPTHREADS
1941     int     exprtodo;              /* The expression to do in parallel mode */
1942 #endif
1943     int     wranfcall;
1944 	int     wranfnpair1;
1945 	int     wranfnpair2;
1946 #if ( BITSINWORD == 32 )
1947     WORD    PrimeList[5000];
1948 	WORD    numinprimelist;
1949     WORD    notfirstprime;
1950 #endif
1951     WORD    GetFile;               /* (R) Where to get the terms {like Hide} */
1952     WORD    KeptInHold;            /* (R) */
1953     WORD    BracketOn;             /* (R) Intensly used in poly_ */
1954     WORD    MaxBracket;            /* (R) Size of BrackBuf. Changed by poly_ */
1955     WORD    CurDum;                /* (R) Current maximum dummy number */
1956     WORD    DeferFlag;             /* (R) For defered brackets */
1957     WORD    TePos;                 /* (R) */
1958     WORD    sLevel;                /* (R) Sorting level */
1959     WORD    Stage4Name;            /* (R) Sorting only */
1960     WORD    GetOneFile;            /* (R) Getting from hide or regular */
1961     WORD    PolyFun;               /* (C) Number of the PolyFun function */
1962     WORD    PolyFunInv;            /* (C) Number of the Inverse of the PolyFun function */
1963     WORD    PolyFunType;           /* () value of PolyFunType */
1964     WORD    PolyFunExp;
1965     WORD    PolyFunVar;
1966     WORD    PolyFunPow;
1967     WORD    Eside;                 /* () Tells which side of = sign */
1968     WORD    MaxDum;                /* Maximum dummy value in an expression */
1969     WORD    level;                 /* Running level in Generator */
1970     WORD    expchanged;            /* (R) Info about expression */
1971     WORD    expflags;              /* (R) Info about expression */
1972     WORD    CurExpr;               /* (S) Number of current expression */
1973     WORD    SortType;              /* A copy of AC.SortType to play with */
1974     WORD    ShortSortCount;        /* For On FewerStatistics 10; */
1975 #if ( BITSINWORD == 32 )
1976 #ifdef WITHPTHREADS
1977 	PADPOSITION(8,7,8,5026,0);
1978 #else
1979 	PADPOSITION(8,7,7,5026,0);
1980 #endif
1981 #else
1982 #ifdef WITHPTHREADS
1983 	PADPOSITION(8,7,8,24,0);
1984 #else
1985 	PADPOSITION(8,7,7,24,0);
1986 #endif
1987 #endif
1988 };
1989 
1990 /*
1991  		#] R :
1992  		#[ T : These are variables that stay in each thread during multi threaded execution.
1993 */
1994 /**
1995  *	The T_const struct is part of the global data and resides either in the
1996  *	ALLGLOBALS struct A, or the ALLPRIVATES struct B (TFORM) under the name T
1997  *	We see it used with the macro AT as in AT.WorkPointer
1998  *	It has variables that are private to each thread, most of which have
1999  *	to be defined at startup.
2000  */
2001 
2002 struct T_const {
2003 #ifdef WITHPTHREADS
2004     SORTBLOCK SB;
2005 #endif
2006     SORTING *S0;                   /* (-) The thread specific sort buffer */
2007     SORTING *SS;                   /* (R) Current sort buffer */
2008     NESTING     Nest;              /* (R) Nesting of function levels etc. */
2009     NESTING     NestStop;          /* (R) */
2010     NESTING     NestPoin;          /* (R) */
2011     WORD    *BrackBuf;             /* (R) Bracket buffer. Used by poly_ at runtime. */
2012     STORECACHE  StoreCache;        /* (R) Cache for picking up stored expr. */
2013     STORECACHE  StoreCacheAlloc;   /* (R) Permanent address of StoreCache to keep valgrind happy */
2014     WORD    **pWorkSpace;          /* (R) Workspace for pointers. Dynamic. */
2015     LONG    *lWorkSpace;           /* (R) WorkSpace for LONG. Dynamic. */
2016     POSITION *posWorkSpace;        /* (R) WorkSpace for file positions */
2017     WORD    *WorkSpace;            /* (M) */
2018     WORD    *WorkTop;              /* (M) */
2019     WORD    *WorkPointer;          /* (R) Pointer in the WorkSpace heap. */
2020     int     *RepCount;             /* (M) Buffer for repeat nesting */
2021     int     *RepTop;               /* (M) Top of RepCount buffer */
2022     WORD    *WildArgTaken;         /* (N) Stack for wildcard pattern matching */
2023     UWORD   *factorials;           /* (T) buffer of factorials. Dynamic. */
2024   	WORD    *small_power_n;        /*     length of the number */
2025 	  UWORD  **small_power;          /*     the number*/
2026     UWORD   *bernoullis;           /* (T) The buffer with bernoulli numbers. Dynamic. */
2027 	WORD    *primelist;
2028     LONG    *pfac;                 /* (T) array of positions of factorials. Dynamic. */
2029     LONG    *pBer;                 /* (T) array of positions of Bernoulli's. Dynamic. */
2030     WORD    *TMaddr;               /* (R) buffer for TestSub */
2031     WORD    *WildMask;             /* (N) Wildcard info during pattern matching */
2032     WORD    *previousEfactor;      /* () Cache for factors in expressions */
2033     WORD    **TermMemHeap;        /* For TermMalloc. Set zero in Checkpoint */
2034     UWORD    **NumberMemHeap;      /* For NumberMalloc. Set zero in Checkpoint */
2035     UWORD    **CacheNumberMemHeap; /* For CacheNumberMalloc. Set zero in Checkpoint */
2036 	BRACKETINFO *bracketinfo;
2037     WORD    **ListPoly;
2038     WORD    *ListSymbols;
2039     UWORD   *NumMem;
2040     WORD    *TopologiesTerm;
2041     WORD    *TopologiesStart;
2042     PARTI   partitions;
2043     LONG    sBer;                  /* (T) Size of the bernoullis buffer */
2044     LONG    pWorkPointer;          /* (R) Offset-pointer in pWorkSpace */
2045     LONG    lWorkPointer;          /* (R) Offset-pointer in lWorkSpace */
2046     LONG    posWorkPointer;        /* (R) Offset-pointer in posWorkSpace */
2047     LONG    InNumMem;
2048     int     sfact;                 /* (T) size of the factorials buffer */
2049     int     mfac;                  /* (T) size of the pfac array. */
2050     int     ebufnum;               /* (R) extra compiler buffer */
2051     int     fbufnum;               /* extra compiler buffer for factorization cache */
2052     int     allbufnum;             /* extra compiler buffer for id,all */
2053     int     aebufnum;              /* extra compiler buffer for id,all */
2054     int     idallflag;             /* indicates use of id,all buffers */
2055     int     idallnum;
2056     int     idallmaxnum;
2057     int     WildcardBufferSize;    /* () local copy for updates */
2058 #ifdef WITHPTHREADS
2059     int     identity;              /* () When we work with B->T */
2060     int     LoadBalancing;         /* Needed for synchronization */
2061 #ifdef WITHSORTBOTS
2062     int     SortBotIn1;            /* Input stream 1 for a SortBot */
2063     int     SortBotIn2;            /* Input stream 2 for a SortBot */
2064 #endif
2065 #endif
2066     int     TermMemMax;            /* For TermMalloc. Set zero in Checkpoint */
2067     int     TermMemTop;            /* For TermMalloc. Set zero in Checkpoint */
2068     int     NumberMemMax;          /* For NumberMalloc. Set zero in Checkpoint */
2069     int     NumberMemTop;          /* For NumberMalloc. Set zero in Checkpoint */
2070     int     CacheNumberMemMax;     /* For CacheNumberMalloc. Set zero in Checkpoint */
2071     int     CacheNumberMemTop;     /* For CacheNumberMalloc. Set zero in Checkpoint */
2072     int     bracketindexflag;      /* Are brackets going to be indexed? */
2073     int     optimtimes;            /* Number of the evaluation of the MCTS tree */
2074     int     ListSymbolsSize;
2075     int     NumListSymbols;
2076     int     numpoly;
2077     int     LeaveNegative;
2078     int     TrimPower;             /* Indicates trimming in polyratfun expansion */
2079     WORD    small_power_maxx;      /*     size of the cache for small powers  */
2080     WORD    small_power_maxn;      /*     size of the cache for small powers */
2081     WORD    dummysubexp[SUBEXPSIZE+4]; /* () used in normal.c */
2082     WORD    comsym[8];             /* () Used in tools.c = {8,SYMBOL,4,0,1,1,1,3} */
2083     WORD    comnum[4];             /* () Used in tools.c = { 4,1,1,3 } */
2084     WORD    comfun[FUNHEAD+4];     /* () Used in tools.c = {7,FUNCTION,3,0,1,1,3} */
2085                                    /*            or { 8,FUNCTION,4,0,0,1,1,3 } */
2086     WORD    comind[7];             /* () Used in tools.c = {7,INDEX,3,0,1,1,3} */
2087     WORD    MinVecArg[7+ARGHEAD];  /* (N) but should be more local */
2088     WORD    FunArg[4+ARGHEAD+FUNHEAD]; /* (N) but can be more local */
2089     WORD    locwildvalue[SUBEXPSIZE]; /* () Used in argument.c = {SUBEXPRESSION,SUBEXPSIZE,0,0,0} */
2090     WORD    mulpat[SUBEXPSIZE+5];  /* () Used in argument.c = {TYPEMULT, SUBEXPSIZE+3, 0, */
2091                                    /* SUBEXPRESSION, SUBEXPSIZE, 0, 1, 0, 0, 0 } */
2092     WORD    proexp[SUBEXPSIZE+5];  /* () Used in poly.c */
2093     WORD    TMout[40];             /* (R) Passing info */
2094     WORD    TMbuff;                /* (R) Communication between TestSub and Genera */
2095 	WORD	TMdolfac;              /* factor number for dollar */
2096     WORD    nfac;                  /* (T) Number of highest stored factorial */
2097     WORD    nBer;                  /* (T) Number of highest bernoulli number. */
2098     WORD    mBer;                  /* (T) Size of buffer pBer. */
2099     WORD    PolyAct;               /* (R) Used for putting the PolyFun at end. ini at 0 */
2100     WORD    RecFlag;               /* (R) Used in TestSub. ini at zero. */
2101 	WORD    inprimelist;
2102 	WORD    sizeprimelist;
2103     WORD    fromindex;             /* Tells the compare routine whether call from index */
2104     WORD    setinterntopo;         /* Set of internal momenta for topogen */
2105     WORD    setexterntopo;         /* Set of external momenta for topogen */
2106     WORD    TopologiesLevel;
2107     WORD    TopologiesOptions[2];
2108 #ifdef WITHPTHREADS
2109 #ifdef WITHSORTBOTS
2110 	PADPOINTER(5,27,105+SUBEXPSIZE*4+FUNHEAD*2+ARGHEAD*2,0);
2111 #else
2112 	PADPOINTER(5,25,105+SUBEXPSIZE*4+FUNHEAD*2+ARGHEAD*2,0);
2113 #endif
2114 #else
2115 	PADPOINTER(5,23,105+SUBEXPSIZE*4+FUNHEAD*2+ARGHEAD*2,0);
2116 #endif
2117 };
2118 /*
2119  		#] T :
2120  		#[ N : The N struct contains variables used in running information
2121                that is inside blocks that should not be split, like pattern
2122                matching, traces etc. They are local for each thread.
2123                They don't need initializations.
2124 */
2125 /**
2126  *	The N_const struct is part of the global data and resides either in the
2127  *	ALLGLOBALS struct A, or the ALLPRIVATES struct B (TFORM) under the name N
2128  *	We see it used with the macro AN as in AN.RepFunNum
2129  *	It has variables that are private to each thread and are used as
2130  *	temporary storage during the expansion of the terms tree.
2131  */
2132 
2133 struct N_const {
2134     POSITION OldPosIn;             /* (R) Used in sort. */
2135     POSITION OldPosOut;            /* (R) Used in sort */
2136 	POSITION theposition;          /* () Used in index.c */
2137     WORD    *EndNest;              /* (R) Nesting of function levels etc. */
2138     WORD    *Frozen;               /* (R) Bracket info */
2139     WORD    *FullProto;            /* (R) Prototype of a subexpression or table */
2140     WORD    *cTerm;                /* (R) Current term for coef_ and term_ */
2141     int     *RepPoint;             /* (R) Pointer in RepCount buffer. Tracks repeat */
2142     WORD    *WildValue;            /* (N) Wildcard info during pattern matching */
2143     WORD    *WildStop;             /* (N) Wildcard info during pattern matching */
2144     WORD    *argaddress;           /* (N) Used in pattern matching of arguments */
2145     WORD    *RepFunList;           /* (N) For pattern matching */
2146     WORD    *patstop;              /* (N) Used in pattern matching */
2147     WORD    *terstop;              /* (N) Used in pattern matching */
2148     WORD    *terstart;             /* (N) Used in pattern matching */
2149     WORD    *terfirstcomm;         /* (N) Used in pattern matching */
2150     WORD    *DumFound;             /* (N) For renumbering indices {make local?} */
2151     WORD    **DumPlace;            /* (N) For renumbering indices {make local?} */
2152     WORD    **DumFunPlace;         /* (N) For renumbering indices {make local?} */
2153     WORD    *UsedSymbol;           /* (N) When storing terms of a global expr. */
2154     WORD    *UsedVector;           /* (N) When storing terms of a global expr. */
2155     WORD    *UsedIndex;            /* (N) When storing terms of a global expr. */
2156     WORD    *UsedFunction;         /* (N) When storing terms of a global expr. */
2157     WORD    *MaskPointer;          /* (N) For wildcard pattern matching */
2158     WORD    *ForFindOnly;          /* (N) For wildcard pattern matching */
2159     WORD    *findTerm;             /* (N) For wildcard pattern matching */
2160     WORD    *findPattern;          /* (N) For wildcard pattern matching */
2161 #ifdef WITHZLIB
2162 	Bytef	**ziobufnum;           /* () Used in compress.c */
2163 	Bytef	*ziobuffers;           /* () Used in compress.c */
2164 #endif
2165 	WORD	*dummyrenumlist;       /* () Used in execute.c and store.c */
2166 	int		*funargs;              /* () Used in lus.c */
2167 	WORD	**funlocs;             /* () Used in lus.c */
2168 	int		*funinds;              /* () Used in lus.c */
2169 	UWORD	*NoScrat2;             /* () Used in normal.c */
2170 	WORD	*ReplaceScrat;         /* () Used in normal.c */
2171 	TRACES	*tracestack;           /* () used in opera.c */
2172 	WORD	*selecttermundo;       /* () Used in pattern.c */
2173 	WORD	*patternbuffer;        /* () Used in pattern.c */
2174 	WORD	*termbuffer;           /* () Used in pattern.c */
2175 	WORD	**PoinScratch;         /* () used in reshuf.c */
2176 	WORD	**FunScratch;          /* () used in reshuf.c */
2177 	WORD	*RenumScratch;         /* () used in reshuf.c */
2178 	FUN_INFO *FunInfo;             /* () Used in smart.c */
2179 	WORD	**SplitScratch;        /* () Used in sort.c */
2180 	WORD	**SplitScratch1;       /* () Used in sort.c */
2181 	SORTING **FunSorts;            /* () Used in sort.c */
2182 	UWORD	*SoScratC;             /* () Used in sort.c */
2183 	WORD	*listinprint;          /* () Used in proces.c and message.c */
2184 	WORD	*currentTerm;          /* () Used in proces.c and message.c */
2185 	WORD	**arglist;             /* () Used in function.c */
2186 	int		*tlistbuf;             /* () used in lus.c */
2187 #ifdef WHICHSUBEXPRESSION
2188 	UWORD	*BinoScrat;            /* () Used in proces.c */
2189 #endif
2190 	WORD	*compressSpace;        /* () Used in sort.c */
2191 #ifdef WITHPTHREADS
2192 	THREADBUCKET *threadbuck;
2193 	EXPRESSIONS expr;
2194 #endif
2195 	UWORD	*SHcombi;
2196 	WORD    *poly_vars;
2197     UWORD   *cmod;                 /* Local setting of modulus. Pointer to value. */
2198 	SHvariables SHvar;
2199 	LONG	deferskipped;          /* () Used in proces.c store.c and parallel.c */
2200 	LONG	InScratch;             /* () Used in sort.c */
2201 	LONG	SplitScratchSize;      /* () Used in sort.c */
2202 	LONG	InScratch1;            /* () Used in sort.c */
2203 	LONG	SplitScratchSize1;     /* () Used in sort.c */
2204 	LONG	ninterms;              /* () Used in proces.c and sort.c */
2205 #ifdef WITHPTHREADS
2206 	LONG	inputnumber;           /* () For use in redefine */
2207 	LONG	lastinindex;
2208 #endif
2209 #ifdef WHICHSUBEXPRESSION
2210 	LONG	last2;                 /* () Used in proces.c */
2211 	LONG	last3;                 /* () Used in proces.c */
2212 #endif
2213 	LONG	SHcombisize;
2214     int     NumTotWildArgs;        /* (N) Used in pattern matching */
2215     int     UseFindOnly;           /* (N) Controls pattern routines */
2216     int     UsedOtherFind;         /* (N) Controls pattern routines */
2217     int     ErrorInDollar;         /* (R) */
2218 	int		numfargs;              /* () Used in lus.c */
2219 	int		numflocs;              /* () Used in lus.c */
2220 	int		nargs;                 /* () Used in lus.c */
2221 	int		tohunt;                /* () Used in lus.c */
2222 	int		numoffuns;             /* () Used in lus.c */
2223 	int		funisize;              /* () Used in lus.c */
2224 	int		RSsize;                /* () Used in normal.c */
2225 	int		numtracesctack;        /* () used in opera.c */
2226 	int		intracestack;          /* () used in opera.c */
2227 	int		numfuninfo;            /* () Used in smart.c */
2228 	int		NumFunSorts;           /* () Used in sort.c */
2229 	int		MaxFunSorts;           /* () Used in sort.c */
2230 	int		arglistsize;           /* () Used in function.c */
2231 	int		tlistsize;             /* () used in lus.c */
2232 	int		filenum;               /* () used in setfile.c */
2233 	int		compressSize;          /* () Used in sort.c */
2234 	int		polysortflag;
2235     int     nogroundlevel;         /* () Used to see whether pattern matching at groundlevel */
2236 	int		subsubveto;            /* () Sabotage combining subexpressions in TestSub */
2237 	WORD	MaxRenumScratch;       /* () used in reshuf.c */
2238     WORD    oldtype;               /* (N) WildCard info at pattern matching */
2239     WORD    oldvalue;              /* (N) WildCard info at pattern matching */
2240     WORD    NumWild;               /* (N) Used in Wildcard */
2241     WORD    RepFunNum;             /* (N) Used in pattern matching */
2242     WORD    DisOrderFlag;          /* (N) Disorder option? Used in pattern matching */
2243     WORD    WildDirt;              /* (N) dirty in wldcard substitution. */
2244     WORD    NumFound;              /* (N) in reshuf only. Local? */
2245     WORD    WildReserve;           /* (N) Used in the wildcards */
2246     WORD    TeInFun;               /* (R) Passing type of action */
2247     WORD    TeSuOut;               /* (R) Passing info. Local? */
2248     WORD    WildArgs;              /* (R) */
2249     WORD    WildEat;               /* (R) */
2250     WORD    PolyNormFlag;          /* (R) For polynomial arithmetic */
2251     WORD    PolyFunTodo;           /* deals with expansions and multiplications */
2252     WORD    sizeselecttermundo;    /* () Used in pattern.c */
2253     WORD    patternbuffersize;     /* () Used in pattern.c */
2254     WORD    numlistinprint;        /* () Used in process.c */
2255     WORD    ncmod;                 /* () used as some type of flag to disable */
2256     WORD    ExpectedSign;          /** Used in pattern matching of antisymmetric functions */
2257     WORD    SignCheck;             /** Used in pattern matching of antisymmetric functions */
2258     WORD    IndDum;                /* Active dummy indices */
2259     WORD    poly_num_vars;
2260     WORD    idfunctionflag;
2261     WORD    poly_vars_type;        /* type of allocation. For free. */
2262     WORD    tryterm;               /* For EndSort(...,2) */
2263 #ifdef WHICHSUBEXPRESSION
2264 	WORD	nbino;                 /* () Used in proces.c */
2265 	WORD	last1;                 /* () Used in proces.c */
2266 #endif
2267 #ifdef WITHPTHREADS
2268 #ifdef WHICHSUBEXPRESSION
2269 #ifdef WITHZLIB
2270 	PADPOSITION(55,11,23,28,sizeof(SHvariables));
2271 #else
2272 	PADPOSITION(53,11,23,28,sizeof(SHvariables));
2273 #endif
2274 #else
2275 #ifdef WITHZLIB
2276 	PADPOSITION(54,9,23,26,sizeof(SHvariables));
2277 #else
2278 	PADPOSITION(52,9,23,26,sizeof(SHvariables));
2279 #endif
2280 #endif
2281 #else
2282 #ifdef WHICHSUBEXPRESSION
2283 #ifdef WITHZLIB
2284 	PADPOSITION(53,9,23,28,sizeof(SHvariables));
2285 #else
2286 	PADPOSITION(51,9,23,28,sizeof(SHvariables));
2287 #endif
2288 #else
2289 #ifdef WITHZLIB
2290 	PADPOSITION(52,7,23,26,sizeof(SHvariables));
2291 #else
2292 	PADPOSITION(50,7,23,26,sizeof(SHvariables));
2293 #endif
2294 #endif
2295 #endif
2296 };
2297 
2298 /*
2299  		#] N :
2300  		#[ O : The O struct concerns output variables
2301 */
2302 /**
2303  *	The O_const struct is part of the global data and resides in the
2304  *	ALLGLOBALS struct A under the name O
2305  *	We see it used with the macro AO as in AO.OutputLine
2306  *	It contains variables that involve the writing of text output and
2307  *	save/store files.
2308  */
2309 
2310 struct O_const {
2311     FILEDATA    SaveData;          /* (O) */
2312     STOREHEADER SaveHeader;        /* ()  System Independent save-Files */
2313 	OPTIMIZERESULT OptimizeResult;
2314     UBYTE   *OutputLine;           /* (O) Sits also in debug statements */
2315     UBYTE   *OutStop;              /* (O) Top of OutputLine buffer */
2316     UBYTE   *OutFill;              /* (O) Filling point in OutputLine buffer */
2317     WORD    *bracket;              /* (O) For writing brackets */
2318     WORD    *termbuf;              /* (O) For writing terms */
2319     WORD    *tabstring;
2320     UBYTE   *wpos;                 /* (O) Only when storing file {local?} */
2321     UBYTE   *wpoin;                /* (O) Only when storing file {local?} */
2322     UBYTE   *DollarOutBuffer;      /* (O) Outputbuffer for Dollars */
2323     UBYTE   *CurBufWrt;            /* (O) Name of currently written expr. */
2324     VOID    (*FlipWORD)(UBYTE *);  /* ()  Function pointers for translations. Initialized by ReadSaveHeader() */
2325     VOID    (*FlipLONG)(UBYTE *);
2326     VOID    (*FlipPOS)(UBYTE *);
2327     VOID    (*FlipPOINTER)(UBYTE *);
2328     VOID    (*ResizeData)(UBYTE *,int,UBYTE *,int);
2329     VOID    (*ResizeWORD)(UBYTE *,UBYTE *);
2330     VOID    (*ResizeNCWORD)(UBYTE *,UBYTE *);
2331     VOID    (*ResizeLONG)(UBYTE *,UBYTE *);
2332     VOID    (*ResizePOS)(UBYTE *,UBYTE *);
2333     VOID    (*ResizePOINTER)(UBYTE *,UBYTE *);
2334     VOID    (*CheckPower)(UBYTE *);
2335     VOID    (*RenumberVec)(UBYTE *);
2336 	DICTIONARY **Dictionaries;
2337 	UBYTE	*tensorList;           /* Dynamically allocated list with functions that are tensorial. */
2338     WORD    *inscheme;             /* for feeding a Horner scheme to Optimize */
2339 /*----Leave NumInBrack as first non-pointer. This is used by the checkpoints--*/
2340     LONG    NumInBrack;            /* (O) For typing [] option in print */
2341     LONG    wlen;                  /* (O) Used to store files. */
2342     LONG    DollarOutSizeBuffer;   /* (O) Size of DollarOutBuffer */
2343     LONG    DollarInOutBuffer;     /* (O) Characters in DollarOutBuffer */
2344 #if defined(mBSD) && defined(MICROTIME)
2345     LONG    wrap;                  /* (O) For statistics time. wrap around */
2346     LONG    wrapnum;               /* (O) For statistics time. wrap around */
2347 #endif
2348     OPTIMIZE Optimize;
2349     int     OutInBuffer;           /* (O) Which routine does the writing */
2350     int     NoSpacesInNumbers;     /*     For very long numbers */
2351     int     BlockSpaces;           /*     For very long numbers */
2352     int     CurrentDictionary;
2353     int     SizeDictionaries;
2354     int     NumDictionaries;
2355     int     CurDictNumbers;
2356     int     CurDictVariables;
2357     int     CurDictSpecials;
2358     int     CurDictFunWithArgs;
2359     int     CurDictNumberWarning;
2360     int     CurDictNotInFunctions;
2361     int     CurDictInDollars;
2362     int     gNumDictionaries;
2363     WORD    schemenum;             /* for feeding a Horner scheme to Optimize */
2364     WORD    transFlag;             /* ()  >0 indicades that translations have to be done */
2365     WORD    powerFlag;             /* ()  >0 indicades that some exponents/powers had to be adjusted */
2366     WORD    mpower;                /*     For maxpower adjustment to larger value */
2367     WORD    resizeFlag;            /* ()  >0 indicades that something went wrong when resizing words */
2368     WORD    bufferedInd;           /* ()  Contains extra INDEXENTRIES, see ReadSaveIndex() for an explanation */
2369     WORD    OutSkip;               /* (O) How many chars to skip in output line */
2370     WORD    IsBracket;             /* (O) Controls brackets */
2371     WORD    InFbrack;              /* (O) For writing only */
2372     WORD    PrintType;             /* (O) */
2373     WORD    FortFirst;             /* (O) Only in sch.c */
2374     WORD    DoubleFlag;            /* (O) Output in double precision */
2375     WORD    IndentSpace;           /* For indentation in output */
2376     WORD    FactorMode;            /* When the output should be written as factors */
2377     WORD    FactorNum;             /* Number of factor currently treated */
2378     WORD    ErrorBlock;
2379     WORD    OptimizationLevel;     /* Level of optimization in the output */
2380     UBYTE   FortDotChar;           /* (O) */
2381 /*
2382 	For the padding, please count also the number of int's in the OPTIMIZE struct.
2383 */
2384 #if defined(mBSD) && defined(MICROTIME)
2385 	PADPOSITION(25,6,35,17,1);
2386 #else
2387 	PADPOSITION(25,4,35,17,1);
2388 #endif
2389 };
2390 /*
2391  		#] O :
2392  		#[ X : The X struct contains variables that deal with the external channel
2393 */
2394 /**
2395  *	The X_const struct is part of the global data and resides in the
2396  *	ALLGLOBALS struct A under the name X
2397  *	We see it used with the macro AX as in AX.timeout
2398  *	It contains variables that involve communication with external programs
2399  */
2400 
2401 struct X_const {
2402 	UBYTE *currentPrompt;
2403 	UBYTE *shellname;          /* if !=NULL (default is "/bin/sh -c"), start in
2404 	                              the specified subshell*/
2405 	UBYTE *stderrname;         /* If !=NULL (default if "/dev/null"), stderr is
2406 	                              redirected to the specified file*/
2407 	int timeout;               /* timeout to initialize preset channels.
2408 	                              If timeout<0, the preset channels are
2409 	                              already initialized*/
2410 	int killSignal;            /* signal number, SIGKILL by default*/
2411 	int killWholeGroup;        /* if 0, the signal is sent only to a process,
2412 	                              if !=0 (default) is sent to a whole process group*/
2413 	int daemonize;             /* if !=0 (default), start in a daemon mode */
2414 	int	currentExternalChannel;
2415 	PADPOINTER(0,5,0,0);
2416 };
2417 /*
2418  		#] X :
2419  		#[ Definitions :
2420 */
2421 
2422 #ifdef WITHPTHREADS
2423 
2424 /**
2425  *	With pthreads (TFORM) the ALLGLOBALS struct has all the variables of which
2426  *	there is only a single copy.
2427  */
2428 
2429 typedef struct AllGlobals {
2430     struct M_const M;
2431     struct C_const C;
2432     struct S_const S;
2433     struct O_const O;
2434     struct P_const P;
2435 	struct X_const X;
2436 	PADPOSITION(0,0,0,0,sizeof(struct P_const)+sizeof(struct X_const));
2437 } ALLGLOBALS;
2438 
2439 /**
2440  *	With pthreads (TFORM) the ALLPRIVATES struct has all the variables of which
2441  *	each thread must have its own (private) copy.
2442  */
2443 
2444 typedef struct AllPrivates {
2445     struct R_const R;
2446     struct N_const N;
2447     struct T_const T;
2448 	PADPOSITION(0,0,0,0,sizeof(struct T_const));
2449 } ALLPRIVATES;
2450 
2451 #else
2452 
2453 /**
2454  *	Without pthreads (FORM) the ALLGLOBALS struct has all the global variables
2455  */
2456 
2457 typedef struct AllGlobals {
2458     struct M_const M;
2459     struct C_const C;
2460     struct S_const S;
2461     struct R_const R;
2462     struct N_const N;
2463     struct O_const O;
2464     struct P_const P;
2465     struct T_const T;
2466 	struct X_const X;
2467 	PADPOSITION(0,0,0,0,sizeof(struct P_const)+sizeof(struct T_const)+sizeof(struct X_const));
2468 } ALLGLOBALS;
2469 
2470 #endif
2471 
2472 /*
2473  		#] Definitions :
2474     #] A :
2475   	#[ FG :
2476 */
2477 
2478 #ifdef WITHPTHREADS
2479 #define PHEAD  ALLPRIVATES *B,
2480 #define PHEAD0 ALLPRIVATES *B
2481 #define BHEAD  B,
2482 #define BHEAD0 B
2483 #else
2484 #define PHEAD
2485 #define PHEAD0 VOID
2486 #define BHEAD
2487 #define BHEAD0
2488 #endif
2489 
2490 #ifdef ANSI
2491 typedef WORD (*WCN)(PHEAD WORD *,WORD *,WORD,WORD);
2492 typedef WORD (*WCN2)(PHEAD WORD *,WORD *);
2493 #else
2494 typedef WORD (*WCN)();
2495 typedef WORD (*WCN2)();
2496 #endif
2497 
2498 /**
2499  *	The FIXEDGLOBALS struct is an anachronism. It started as the struct
2500  *	with global variables that needed initialization.
2501  *	It contains the elements Operation and OperaFind which define a very early
2502  *	way of automatically jumping to the proper operation. We find the results
2503  *	of it in parts of the file opera.c
2504  *	Later operations were treated differently in a more transparent way.
2505  *	We never changed the existing code. The most important part is currently
2506  *	the cTable which is used intensively in the compiler.
2507  */
2508 
2509 typedef struct FixedGlobals {
2510 	WCN		Operation[8];
2511 	WCN2	OperaFind[6];
2512 	char	*VarType[10];
2513 	char	*ExprStat[21];
2514 	char	*FunNam[2];
2515 	char	*swmes[3];
2516 	char	*fname;
2517 	char	*fname2;
2518 	UBYTE	*s_one;
2519 	WORD	fnamebase;
2520 	WORD	fname2base;
2521 	UINT	cTable[256];
2522 } FIXEDGLOBALS;
2523 
2524 /*
2525   	#] FG :
2526 */
2527 
2528 #endif
2529