FORM v5.0.0-35-g6318119
setfile.c
Go to the documentation of this file.
1
5/* #[ License : */
6/*
7 * Copyright (C) 1984-2026 J.A.M. Vermaseren
8 * When using this file you are requested to refer to the publication
9 * J.A.M.Vermaseren "New features of FORM" math-ph/0010025
10 * This is considered a matter of courtesy as the development was paid
11 * for by FOM the Dutch physics granting agency and we would like to
12 * be able to track its scientific use to convince FOM of its value
13 * for the community.
14 *
15 * This file is part of FORM.
16 *
17 * FORM is free software: you can redistribute it and/or modify it under the
18 * terms of the GNU General Public License as published by the Free Software
19 * Foundation, either version 3 of the License, or (at your option) any later
20 * version.
21 *
22 * FORM is distributed in the hope that it will be useful, but WITHOUT ANY
23 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
24 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
25 * details.
26 *
27 * You should have received a copy of the GNU General Public License along
28 * with FORM. If not, see <http://www.gnu.org/licenses/>.
29 */
30/* #] License : */
31/*
32 #[ Includes :
33
34 Routines that deal with settings and the setup file
35*/
36
37#include "form3.h"
38
39char curdirp[] = ".";
40char cursortdirp[] = ".";
41char commentchar[] = "*";
42char dotchar[] = "_";
43char highfirst[] = "highfirst";
44char lowfirst[] = "lowfirst";
45char procedureextension[] = "prc";
46
47#define NUMERICALVALUE 0
48#define STRINGVALUE 1
49#define PATHVALUE 2
50#define ONOFFVALUE 3
51#define DEFINEVALUE 4
52
53SETUPPARAMETERS setupparameters[] =
54{
55 {(UBYTE *)"bracketindexsize", NUMERICALVALUE, 0, (LONG)MAXBRACKETBUFFERSIZE}
56 ,{(UBYTE *)"commentchar", STRINGVALUE, 0, (LONG)commentchar}
57 ,{(UBYTE *)"compresssize", NUMERICALVALUE, 0, (LONG)COMPRESSBUFFER}
58 ,{(UBYTE *)"constindex", NUMERICALVALUE, 0, (LONG)NUMFIXED}
59 ,{(UBYTE *)"continuationlines", NUMERICALVALUE, 0, (LONG)FORTRANCONTINUATIONLINES}
60#ifdef WITHFLOAT
61 ,{(UBYTE *)"defaultprecision", NUMERICALVALUE, 0, (LONG)DEFAULTPRECISION}
62#endif
63 ,{(UBYTE *)"define", DEFINEVALUE, 0, (LONG)0}
64 ,{(UBYTE *)"dotchar", STRINGVALUE, 0, (LONG)dotchar}
65 ,{(UBYTE *)"factorizationcache", NUMERICALVALUE, 0, (LONG)FBUFFERSIZE}
66 ,{(UBYTE *)"filepatches", NUMERICALVALUE, 0, (LONG)MAXFPATCHES}
67 ,{(UBYTE *)"functionlevels", NUMERICALVALUE, 0, (LONG)MAXFLEVELS}
68 ,{(UBYTE *)"hidesize", NUMERICALVALUE, 0, (LONG)0}
69 ,{(UBYTE *)"incdir", PATHVALUE, 0, (LONG)curdirp}
70 ,{(UBYTE *)"indentspace", NUMERICALVALUE, 0, (LONG)INDENTSPACE}
71 ,{(UBYTE *)"insidefirst", ONOFFVALUE, 0, (LONG)1}
72 ,{(UBYTE *)"jumpratio", NUMERICALVALUE, 0, (LONG)JUMPRATIO}
73 ,{(UBYTE *)"largepatches", NUMERICALVALUE, 0, (LONG)MAXPATCHES}
74 ,{(UBYTE *)"largesize", NUMERICALVALUE, 0, (LONG)LARGEBUFFER}
75 ,{(UBYTE *)"maxnumbersize", NUMERICALVALUE, 0, (LONG)0}
76/* ,{(UBYTE *)"maxnumbersize", NUMERICALVALUE, 0, (LONG)MAXNUMBERSIZE} */
77 ,{(UBYTE *)"maxtermsize", NUMERICALVALUE, 0, (LONG)MAXTER}
78#ifdef WITHFLOAT
79 ,{(UBYTE *)"maxweight", NUMERICALVALUE, 0, (LONG)MAXWEIGHT}
80#endif
81 ,{(UBYTE *)"maxwildcards", NUMERICALVALUE, 0, (LONG)MAXWILDC}
82 ,{(UBYTE *)"nospacesinnumbers", ONOFFVALUE, 0, (LONG)0}
83 ,{(UBYTE *)"numstorecaches", NUMERICALVALUE, 0, (LONG)NUMSTORECACHES}
84 ,{(UBYTE *)"nwritefinalstatistics", ONOFFVALUE, 0, (LONG)0}
85 ,{(UBYTE *)"nwriteprocessstatistics", ONOFFVALUE, 0, (LONG)0}
86 ,{(UBYTE *)"nwritestatistics", ONOFFVALUE, 0, (LONG)0}
87 ,{(UBYTE *)"nwritethreadstatistics", ONOFFVALUE, 0, (LONG)0}
88 ,{(UBYTE *)"oldfactarg", ONOFFVALUE, 0, (LONG)NEWFACTARG}
89 ,{(UBYTE *)"oldgcd", ONOFFVALUE, 0, (LONG)1}
90 ,{(UBYTE *)"oldorder", ONOFFVALUE, 0, (LONG)0}
91 ,{(UBYTE *)"oldparallelstatistics", ONOFFVALUE, 0, (LONG)0}
92 ,{(UBYTE *)"parentheses", NUMERICALVALUE, 0, (LONG)MAXPARLEVEL}
93 ,{(UBYTE *)"path", PATHVALUE, 0, (LONG)curdirp}
94 ,{(UBYTE *)"procedureextension", STRINGVALUE, 0, (LONG)procedureextension}
95 ,{(UBYTE *)"processbucketsize", NUMERICALVALUE, 0, (LONG)DEFAULTPROCESSBUCKETSIZE}
96 ,{(UBYTE *)"resettimeonclear", ONOFFVALUE, 0, (LONG)1}
97 ,{(UBYTE *)"scratchsize", NUMERICALVALUE, 0, (LONG)SCRATCHSIZE}
98 ,{(UBYTE *)"shmwinsize", NUMERICALVALUE, 0, (LONG)SHMWINSIZE}
99 ,{(UBYTE *)"sizestorecache", NUMERICALVALUE, 0, (LONG)SIZESTORECACHE}
100 ,{(UBYTE *)"smallextension", NUMERICALVALUE, 0, (LONG)SMALLOVERFLOW}
101 ,{(UBYTE *)"smallsize", NUMERICALVALUE, 0, (LONG)SMALLBUFFER}
102 ,{(UBYTE *)"sortiosize", NUMERICALVALUE, 0, (LONG)SORTIOSIZE}
103 ,{(UBYTE *)"sorttype", STRINGVALUE, 0, (LONG)lowfirst}
104 ,{(UBYTE *)"spectatorsize", NUMERICALVALUE, 0, (LONG)SPECTATORSIZE}
105 ,{(UBYTE *)"subfilepatches", NUMERICALVALUE, 0, (LONG)SMAXFPATCHES}
106 ,{(UBYTE *)"sublargepatches", NUMERICALVALUE, 0, (LONG)SMAXPATCHES}
107 ,{(UBYTE *)"sublargesize", NUMERICALVALUE, 0, (LONG)SLARGEBUFFER}
108 ,{(UBYTE *)"subsmallextension", NUMERICALVALUE, 0, (LONG)SSMALLOVERFLOW}
109 ,{(UBYTE *)"subsmallsize", NUMERICALVALUE, 0, (LONG)SSMALLBUFFER}
110 ,{(UBYTE *)"subsortiosize", NUMERICALVALUE, 0, (LONG)SSORTIOSIZE}
111 ,{(UBYTE *)"subtermsinsmall", NUMERICALVALUE, 0, (LONG)STERMSSMALL}
112 ,{(UBYTE *)"tempdir", STRINGVALUE, 0, (LONG)curdirp}
113 ,{(UBYTE *)"tempsortdir", STRINGVALUE, 0, (LONG)cursortdirp}
114 ,{(UBYTE *)"termsinsmall", NUMERICALVALUE, 0, (LONG)TERMSSMALL}
115 ,{(UBYTE *)"threadbucketsize", NUMERICALVALUE, 0, (LONG)DEFAULTTHREADBUCKETSIZE}
116 ,{(UBYTE *)"threadloadbalancing", ONOFFVALUE, 0, (LONG)DEFAULTTHREADLOADBALANCING}
117 ,{(UBYTE *)"threads", NUMERICALVALUE, 0, (LONG)DEFAULTTHREADS}
118 ,{(UBYTE *)"threadscratchoutsize", NUMERICALVALUE, 0, (LONG)THREADSCRATCHOUTSIZE}
119 ,{(UBYTE *)"threadscratchsize", NUMERICALVALUE, 0, (LONG)THREADSCRATCHSIZE}
120 ,{(UBYTE *)"threadsortfilesynch", ONOFFVALUE, 0, (LONG)0}
121 ,{(UBYTE *)"totalsize", ONOFFVALUE, 0, (LONG)2}
122 ,{(UBYTE *)"workspace", NUMERICALVALUE, 0, (LONG)WORKBUFFER}
123 ,{(UBYTE *)"wtimestats", ONOFFVALUE, 0, (LONG)2}
124};
125
126/*
127 #] Includes :
128 #[ Setups :
129 #[ DoSetups :
130*/
131
132int DoSetups(void)
133{
134 UBYTE *setbuffer, *s, *t, *u /*, c */;
135 int errors = 0;
136 setbuffer = LoadInputFile((UBYTE *)setupfilename,SETUPFILE);
137 if ( setbuffer ) {
138/*
139 The contents of the file are now in setbuffer.
140 Each line is commentary or a single command.
141 The buffer is terminated with a zero.
142*/
143 s = setbuffer;
144 while ( *s ) {
145 if ( *s == ' ' || *s == '\t' || *s == '*' || *s == '#' || *s == '\n' ) {
146 while ( *s && *s != '\n' ) s++;
147 }
148 else if ( tolower(*s) < 'a' || tolower(*s) > 'z' ) {
149 t = s;
150 while ( *s && *s != '\n' ) s++;
151/*
152 c = *s; *s = 0;
153 Error1("Setup file: Illegal statement: ",t);
154 errors++; *s = c;
155*/
156 }
157 else {
158 t = s; /* name of the option */
159 while ( tolower(*s) >= 'a' && tolower(*s) <= 'z' ) s++;
160 *s++ = 0;
161 while ( *s == ' ' || *s == '\t' ) s++;
162 u = s; /* 'value' of the option */
163 while ( *s && *s != '\n' && *s != '\r' ) s++;
164 if ( *s ) *s++ = 0;
165 errors += ProcessOption(t,u,0);
166 }
167 while ( *s == '\n' || *s == '\r' ) s++;
168 }
169 M_free(setbuffer,"setup file buffer");
170 }
171 if ( errors ) return(1);
172 else return(0);
173}
174
175/*
176 #] DoSetups :
177 #[ ProcessOption :
178*/
179
180static char *proop1[3] = { "Setup file", "Setups in .frm file", "Setup in environment" };
181
182int ProcessOption(UBYTE *s1, UBYTE *s2, int filetype)
183{
184 SETUPPARAMETERS *sp;
185 int n, giveback = 0, error = 0;
186 UBYTE *s, *t, *s2ret;
187 LONG x;
188 sp = GetSetupPar(s1);
189 if ( sp ) {
190/*
191 We check now whether there are `' variables to be looked up in the
192 environment. This is new (30-may-2008). This is only allowed in s2.
193*/
194restart:;
195 {
196 UBYTE *s3,*s4,*s5,*s6, c, *start;
197 int n1,n2,n3;
198 s = s2;
199 while ( *s ) {
200 if ( *s == '\\' ) s += 2;
201 else if ( *s == '`' ) {
202 start = s; s++;
203 while ( *s && *s != '\'' ) {
204 if ( *s == '\\' ) s++;
205 s++;
206 }
207 if ( *s == 0 ) {
208 MesPrint("%s: Illegal use of ` character for parameter %s"
209 ,proop1[filetype],s1);
210 return(1);
211 }
212 c = *s; *s = 0;
213 s3 = (UBYTE *)getenv((char *)(start+1));
214 if ( s3 == 0 ) {
215 MesPrint("%s: Cannot find environment variable %s for parameter %s"
216 ,proop1[filetype],start+1,s1);
217 return(1);
218
219 }
220 *s = c; s++;
221 n1 = start - s2; s4 = s3; n2 = 0;
222 while ( *s4 ) {
223 if ( *s4 == '\\' ) { s4++; n2++; }
224 s4++; n2++;
225 }
226 s4 = s; n3 = 0;
227 while ( *s4 ) {
228 if ( *s4 == '\\' ) { s4++; n3++; }
229 s4++; n3++;
230 }
231 s4 = (UBYTE *)Malloc1((n1+n2+n3+1)*sizeof(UBYTE),"environment in setup");
232 s5 = s2; s6 = s4;
233 while ( n1-- > 0 ) *s6++ = *s5++;
234 s5 = s3;
235 while ( n2-- > 0 ) *s6++ = *s5++;
236 s5 = s;
237 while ( n3-- > 0 ) *s6++ = *s5++;
238 *s6 = 0;
239 if ( giveback ) M_free(s2,"environment in setup");
240 s2 = s4;
241 giveback = 1;
242 goto restart;
243 }
244 else s++;
245 }
246 }
247 n = sp->type;
248 s2ret = s2;
249 switch ( n ) {
250 case NUMERICALVALUE:
251 ParseNumber(x,s2);
252 if ( *s2 == 'K' ) { x = x * 1000; s2++; }
253 else if ( *s2 == 'M' ) { x = x * 1000000; s2++; }
254 else if ( *s2 == 'G' ) { x = x * 1000000000; s2++; }
255 else if ( *s2 == 'T' ) { x = x * 1000000000000; s2++; }
256 if ( *s2 && *s2 != ' ' && *s2 != '\t' ) {
257 MesPrint("%s: Numerical value expected for parameter %s"
258 ,proop1[filetype],s1);
259 error = 1; break;
260 }
261 sp->value = x;
262 sp->flags = USEDFLAG;
263 break;
264 case STRINGVALUE:
265 if ( StrICmp(s1,(UBYTE *)"tempsortdir") == 0 ) AM.havesortdir = 1;
266 s = s2; t = s2;
267 while ( *s ) {
268 if ( *s == ' ' || *s == '\t' ) break;
269 if ( *s == '\\' ) s++;
270 *t++ = *s++;
271 }
272 *t = 0;
273 if ( sp->flags == USEDFLAG && sp->value != 0 )
274 M_free((void *)(sp->value),"Process option");
275 sp->value = (LONG)strDup1(s2,"Process option");
276 sp->flags = USEDFLAG;
277 break;
278 case PATHVALUE:
279 if ( StrICmp(s1,(UBYTE *)"incdir") == 0 ) {
280 AM.IncDir = 0;
281 }
282 else if ( StrICmp(s1,(UBYTE *)"path") == 0 ) {
283 if ( AM.Path ) M_free(AM.Path,"path");
284 AM.Path = 0;
285 }
286 else {
287 MesPrint("Setups: %s not yet implemented",s1);
288 error = 1;
289 break;
290 }
291 if ( sp->flags == USEDFLAG && sp->value != 0 )
292 M_free((void *)(sp->value),"Process option");
293 sp->value = (LONG)strDup1(s2,"Process option");
294 sp->flags = USEDFLAG;
295 break;
296 case ONOFFVALUE:
297 if ( tolower(*s2) == 'o' && tolower(s2[1]) == 'n'
298 && ( s2[2] == 0 || s2[2] == ' ' || s2[2] == '\t' ) )
299 sp->value = 1;
300 else if ( tolower(*s2) == 'o' && tolower(s2[1]) == 'f'
301 && tolower(s2[2]) == 'f'
302 && ( s2[3] == 0 || s2[3] == ' ' || s2[3] == '\t' ) )
303 sp->value = 0;
304 else {
305 MesPrint("%s: Unrecognized option for parameter %s: %s"
306 ,proop1[filetype],s1,s2);
307 error = 1; break;
308 }
309 sp->flags = USEDFLAG;
310 break;
311 case DEFINEVALUE:
312/*
313 if ( sp->value ) M_free((UBYTE *)(sp->value),"Process option");
314 sp->value = (LONG)strDup1(s2,"Process option");
315*/
316 if ( TheDefine(s2,2) ) error = 1;
317 break;
318 default:
319 Error1("Error in setupparameter table for:",s1);
320 error = 1;
321 break;
322 }
323 }
324 else {
325 MesPrint("%s: Keyword not recognized: %s",proop1[filetype],s1);
326 error = 1;
327 }
328 if ( giveback ) M_free(s2ret,"environment in setup");
329 return(error);
330}
331
332/*
333 #] ProcessOption :
334 #[ GetSetupPar :
335*/
336
337SETUPPARAMETERS *GetSetupPar(UBYTE *s)
338{
339 int hi, med, lo, i;
340 lo = 0;
341 // -1: remove possibility of out-of-bounds read in StrICmp
342 hi = sizeof(setupparameters)/sizeof(SETUPPARAMETERS) - 1;
343 do {
344 med = ( hi + lo ) / 2;
345 i = StrICmp(s,(UBYTE *)setupparameters[med].parameter);
346 if ( i == 0 ) return(setupparameters+med);
347 if ( i < 0 ) hi = med-1;
348 else lo = med+1;
349 } while ( hi >= lo );
350 return(0);
351}
352
353/*
354 #] GetSetupPar :
355 #[ RecalcSetups :
356*/
357
358int RecalcSetups(void)
359{
360 SETUPPARAMETERS *sp, *sp1;
361
362 sp1 = GetSetupPar((UBYTE *)"threads");
363 if ( AM.totalnumberofthreads > 1 ) sp1->value = AM.totalnumberofthreads - 1;
364 else sp1->value = 0;
365/*
366 if ( sp1->value > 0 ) AM.totalnumberofthreads = sp1->value+1;
367 if ( AM.totalnumberofthreads == 0 ) AM.totalnumberofthreads = 1;
368*/
369 sp = GetSetupPar((UBYTE *)"filepatches");
370 if ( sp->value < AM.totalnumberofthreads-1 )
371 sp->value = AM.totalnumberofthreads - 1;
372
373 sp = GetSetupPar((UBYTE *)"smallsize");
374 sp1 = GetSetupPar((UBYTE *)"smallextension");
375 if ( 6*sp1->value < 7*sp->value ) sp1->value = (7*sp->value)/6;
376 sp = GetSetupPar((UBYTE *)"termsinsmall");
377 sp->value = ( sp->value + 15 ) & (-16L);
378#ifdef WITHPTHREADS
379 {
380 SETUPPARAMETERS *sp2;
381 LONG totalsize, minimumsize;
382 sp = GetSetupPar((UBYTE *)"largesize");
383 totalsize = sp1->value+sp->value;
384 sp2 = GetSetupPar((UBYTE *)"maxtermsize");
385 AM.MaxTer = sp2->value*sizeof(WORD);
386 if ( AM.MaxTer < 200*(LONG)(sizeof(WORD)) ) AM.MaxTer = 200*(LONG)(sizeof(WORD));
387 if ( AM.MaxTer > MAXPOSITIVE - 200*(LONG)(sizeof(WORD)) ) AM.MaxTer = MAXPOSITIVE - 200*(LONG)(sizeof(WORD));
388 AM.MaxTer /= sizeof(WORD);
389 AM.MaxTer *= sizeof(WORD);
390#ifdef WITHSORTBOTS
391 if ( AM.totalnumberofthreads-1 > 2 ) {
392 minimumsize = (2*(AM.totalnumberofthreads-1)-2)*(AM.MaxTer+
393 NUMBEROFBLOCKSINSORT*MINIMUMNUMBEROFTERMS/2*AM.MaxTer);
394 }
395 else
396#endif
397 {
398 minimumsize = (AM.totalnumberofthreads-1)*(AM.MaxTer+
399 NUMBEROFBLOCKSINSORT*MINIMUMNUMBEROFTERMS*AM.MaxTer);
400 }
401 if ( totalsize < minimumsize ) {
402 sp->value = minimumsize - sp1->value;
403 }
404 }
405#endif
406 return(0);
407}
408
409/*
410 #] RecalcSetups :
411 #[ AllocSetups :
412*/
413
414int AllocSetups(void)
415{
416 SETUPPARAMETERS *sp;
417 LONG LargeSize, SmallSize, SmallEsize, TermsInSmall, IOsize;
418 int MaxPatches, MaxFpatches, error = 0, i, size;
419 UBYTE *s;
420#ifndef WITHPTHREADS
421 int j;
422#endif
423 sp = GetSetupPar((UBYTE *)"threads");
424 if ( sp->value > 0 ) AM.totalnumberofthreads = sp->value+1;
425
426 AM.OutBuffer = (UBYTE *)Malloc1(AM.OutBufSize+1,"OutputBuffer");
427 AP.PreAssignStack =(LONG *)Malloc1(AP.MaxPreAssignLevel*sizeof(LONG *),"PreAssignStack");
428 for ( i = 0; i < AP.MaxPreAssignLevel; i++ ) AP.PreAssignStack[i] = 0;
429 AC.iBuffer = (UBYTE *)Malloc1(AC.iBufferSize+1,"statement buffer");
430 AC.iStop = AC.iBuffer + AC.iBufferSize-2;
431 AP.preStart = (UBYTE *)Malloc1(AP.pSize,"instruction buffer");
432 AP.preStop = AP.preStart + AP.pSize - 3;
433 /* AP.PreIfStack is already allocated in StartPrepro(), but to be sure we
434 "if" the freeing */
435 if ( AP.PreIfStack ) M_free(AP.PreIfStack,"PreIfStack");
436 AP.PreIfStack = (int *)Malloc1(AP.MaxPreIfLevel*sizeof(int),
437 "Preprocessor if stack");
438 AP.PreIfStack[0] = EXECUTINGIF;
439 sp = GetSetupPar((UBYTE *)"insidefirst");
440 AM.ginsidefirst = AC.minsidefirst = AC.insidefirst = sp->value;
441/*
442 We need to consider eliminating this variable
443*/
444 sp = GetSetupPar((UBYTE *)"maxtermsize");
445 AM.MaxTer = sp->value*sizeof(WORD);
446 if ( AM.MaxTer < 200*(LONG)(sizeof(WORD)) ) AM.MaxTer = 200*(LONG)(sizeof(WORD));
447 if ( AM.MaxTer > MAXPOSITIVE - 200*(LONG)(sizeof(WORD)) ) AM.MaxTer = MAXPOSITIVE - 200*(LONG)(sizeof(WORD));
448 AM.MaxTer /= (LONG)sizeof(WORD);
449 AM.MaxTer *= (LONG)sizeof(WORD);
450/*
451 Allocate workspace.
452*/
453 sp = GetSetupPar((UBYTE *)"workspace");
454 AM.WorkSize = sp->value;
455#ifdef WITHPTHREADS
456#else
457 AT.WorkSpace = (WORD *)Malloc1(AM.WorkSize*sizeof(WORD),(char *)(sp->parameter));
458 AT.WorkTop = AT.WorkSpace + AM.WorkSize;
459 AT.WorkPointer = AT.WorkSpace;
460#endif
461/*
462 Fixed indices
463*/
464 sp = GetSetupPar((UBYTE *)"constindex");
465 if ( ( sp->value+100+5*WILDOFFSET ) > MAXPOSITIVE ) {
466 MesPrint("Setting of %s in setupfile too large","constindex");
467 AM.OffsetIndex = MAXPOSITIVE - 5*WILDOFFSET - 100;
468 MesPrint("value corrected to maximum allowed: %d",AM.OffsetIndex);
469 }
470 else AM.OffsetIndex = sp->value + 1;
471 AC.FixIndices = (WORD *)Malloc1((AM.OffsetIndex)*sizeof(WORD),(char *)(sp->parameter));
472 AM.WilInd = AM.OffsetIndex + WILDOFFSET;
473 AM.DumInd = AM.OffsetIndex + 2*WILDOFFSET;
474 AM.IndDum = AM.DumInd + WILDOFFSET;
475#ifndef WITHPTHREADS
476 AR.CurDum = AN.IndDum = AM.IndDum;
477#endif
478 AM.mTraceDum = AM.IndDum + 2*WILDOFFSET;
479
480 sp = GetSetupPar((UBYTE *)"parentheses");
481 AM.MaxParLevel = sp->value+1;
482 AC.tokenarglevel = (WORD *)Malloc1((sp->value+1)*sizeof(WORD),(char *)(sp->parameter));
483/*
484 Space during calculations
485*/
486 sp = GetSetupPar((UBYTE *)"maxnumbersize");
487/*
488 size = ( sp->value + 11 ) & (-4);
489 AM.MaxTal = size - 2;
490 if ( AM.MaxTal > (AM.MaxTer/sizeof(WORD)-2)/2 )
491 AM.MaxTal = (AM.MaxTer/sizeof(WORD)-2)/2;
492 if ( AM.MaxTal < (AM.MaxTer/sizeof(WORD)-2)/4 )
493 AM.MaxTal = (AM.MaxTer/sizeof(WORD)-2)/4;
494*/
495/*
496 There is too much confusion about MaxTal cq maxnumbersize.
497 It seems better to fix it at its maximum value. This way we only worry
498 about maxtermsize. This can be understood better by the 'innocent' user.
499*/
500 if ( sp->value == 0 ) {
501 AM.MaxTal = (AM.MaxTer/sizeof(WORD)-2)/2;
502 }
503 else {
504 size = ( sp->value + 11 ) & (-4);
505 AM.MaxTal = size - 2;
506 if ( (size_t)AM.MaxTal > (size_t)((AM.MaxTer/sizeof(WORD)-2)/2) )
507 AM.MaxTal = (AM.MaxTer/sizeof(WORD)-2)/2;
508 }
509 AM.MaxTal &= -sizeof(WORD)*2;
510
511 sp->value = AM.MaxTal;
512 AC.cmod = (UWORD *)Malloc1(AM.MaxTal*4*sizeof(UWORD),(char *)(sp->parameter));
513 AM.gcmod = AC.cmod + AM.MaxTal;
514 AC.powmod = AM.gcmod + AM.MaxTal;
515 AM.gpowmod = AC.powmod + AM.MaxTal;
516/*
517 The IO buffers for the input and output expressions.
518 Fscr[2] will be assigned in a later stage for hiding expressions from
519 the regular action. That will make the program faster.
520*/
521 sp = GetSetupPar((UBYTE *)"scratchsize");
522 AM.ScratSize = sp->value/sizeof(WORD);
523 if ( AM.ScratSize < 4*AM.MaxTer ) AM.ScratSize = 4*AM.MaxTer;
524 AM.HideSize = AM.ScratSize;
525 sp = GetSetupPar((UBYTE *)"hidesize");
526 if ( sp->value > 0 ) {
527 AM.HideSize = sp->value/sizeof(WORD);
528 if ( AM.HideSize < 4*AM.MaxTer ) AM.HideSize = 4*AM.MaxTer;
529 }
530 sp = GetSetupPar((UBYTE *)"factorizationcache");
531 AM.fbuffersize = sp->value;
532#ifdef WITHPTHREADS
533 sp = GetSetupPar((UBYTE *)"threadscratchsize");
534 AM.ThreadScratSize = sp->value/sizeof(WORD);
535 sp = GetSetupPar((UBYTE *)"threadscratchoutsize");
536 AM.ThreadScratOutSize = sp->value/sizeof(WORD);
537#endif
538#ifndef WITHPTHREADS
539 for ( j = 0; j < 2; j++ ) {
540 WORD *ScratchBuf;
541 ScratchBuf = (WORD *)Malloc1(AM.ScratSize*sizeof(WORD),"scratchsize");
542 AR.Fscr[j].POsize = AM.ScratSize * sizeof(WORD);
543 AR.Fscr[j].POfull = AR.Fscr[j].POfill = AR.Fscr[j].PObuffer = ScratchBuf;
544 AR.Fscr[j].POstop = AR.Fscr[j].PObuffer + AM.ScratSize;
545 PUTZERO(AR.Fscr[j].POposition);
546 }
547 AR.Fscr[2].PObuffer = 0;
548#endif
549 sp = GetSetupPar((UBYTE *)"threadbucketsize");
550 AC.ThreadBucketSize = AM.gThreadBucketSize = AM.ggThreadBucketSize = sp->value;
551 sp = GetSetupPar((UBYTE *)"threadloadbalancing");
552 AC.ThreadBalancing = AM.gThreadBalancing = AM.ggThreadBalancing = sp->value;
553 sp = GetSetupPar((UBYTE *)"threadsortfilesynch");
554 AC.ThreadSortFileSynch = AM.gThreadSortFileSynch = AM.ggThreadSortFileSynch = sp->value;
555/*
556 The size for shared memory window for oneside MPI2 communications (unused)
557*/
558 sp = GetSetupPar((UBYTE *)"shmwinsize");
559 AM.shmWinSize = sp->value/sizeof(WORD);
560 if ( AM.shmWinSize < 4*AM.MaxTer ) AM.shmWinSize = 4*AM.MaxTer;
561/*
562 The sort buffer
563*/
564 sp = GetSetupPar((UBYTE *)"smallsize");
565 SmallSize = sp->value;
566 sp = GetSetupPar((UBYTE *)"smallextension");
567 SmallEsize = sp->value;
568 sp = GetSetupPar((UBYTE *)"largesize");
569 LargeSize = sp->value;
570 sp = GetSetupPar((UBYTE *)"termsinsmall");
571 TermsInSmall = sp->value;
572 sp = GetSetupPar((UBYTE *)"largepatches");
573 MaxPatches = sp->value;
574 sp = GetSetupPar((UBYTE *)"filepatches");
575 MaxFpatches = sp->value;
576 sp = GetSetupPar((UBYTE *)"sortiosize");
577 IOsize = sp->value;
578 if ( IOsize < AM.MaxTer ) { IOsize = AM.MaxTer; sp->value = IOsize; }
579#ifndef WITHPTHREADS
580#ifdef WITHZLIB
581 for ( j = 0; j < 2; j++ ) { AR.Fscr[j].ziosize = IOsize; }
582#endif
583#endif
584 AM.S0 = 0;
585 AM.S0 = AllocSort(LargeSize,SmallSize,SmallEsize,TermsInSmall
586 ,MaxPatches,MaxFpatches,IOsize,0);
587 /* AM.S0->file.ziosize was already set to a (larger) value by AllocSort, here it is re-set. */
588#ifdef WITHZLIB
589 AM.S0->file.ziosize = IOsize;
590#ifndef WITHPTHREADS
591 AR.FoStage4[0].ziosize = IOsize;
592 AR.FoStage4[1].ziosize = IOsize;
593 AT.S0 = AM.S0;
594#endif
595#else
596#ifndef WITHPTHREADS
597 AT.S0 = AM.S0;
598#endif
599#endif
600#ifndef WITHPTHREADS
601 AR.FoStage4[0].POsize = ((IOsize+sizeof(WORD)-1)/sizeof(WORD))*sizeof(WORD);
602 AR.FoStage4[1].POsize = ((IOsize+sizeof(WORD)-1)/sizeof(WORD))*sizeof(WORD);
603#endif
604 sp = GetSetupPar((UBYTE *)"subsmallsize");
605 AM.SSmallSize = sp->value;
606 sp = GetSetupPar((UBYTE *)"subsmallextension");
607 AM.SSmallEsize = sp->value;
608 sp = GetSetupPar((UBYTE *)"sublargesize");
609 AM.SLargeSize = sp->value;
610 sp = GetSetupPar((UBYTE *)"subtermsinsmall");
611 AM.STermsInSmall = sp->value;
612 sp = GetSetupPar((UBYTE *)"sublargepatches");
613 AM.SMaxPatches = sp->value;
614 sp = GetSetupPar((UBYTE *)"subfilepatches");
615 AM.SMaxFpatches = sp->value;
616 sp = GetSetupPar((UBYTE *)"subsortiosize");
617 AM.SIOsize = sp->value;
618 /* As for IOsize, make sure SIOsize is at least as large as AM.MaxTer. */
619 if ( AM.SIOsize < AM.MaxTer ) { AM.SIOsize = AM.MaxTer; sp->value = AM.SIOsize; }
620 sp = GetSetupPar((UBYTE *)"spectatorsize");
621 AM.SpectatorSize = sp->value;
622/*
623 The next code is just for the moment (26-jan-1997) because we have
624 the new parts combined with the old. Once the old parts are gone
625 from the program, we can eliminate this code too.
626*/
627 sp = GetSetupPar((UBYTE *)"functionlevels");
628 AM.maxFlevels = sp->value + 1;
629#ifdef WITHPTHREADS
630#else
631 AT.Nest = (NESTING)Malloc1((LONG)sizeof(struct NeStInG)*AM.maxFlevels,"functionlevels");
632 AT.NestStop = AT.Nest + AM.maxFlevels;
633 AT.NestPoin = AT.Nest;
634#endif
635
636 sp = GetSetupPar((UBYTE *)"maxwildcards");
637 AM.MaxWildcards = sp->value;
638#ifdef WITHPTHREADS
639#else
640 AT.WildMask = (WORD *)Malloc1((LONG)AM.MaxWildcards*sizeof(WORD),"maxwildcards");
641#endif
642
643 sp = GetSetupPar((UBYTE *)"compresssize");
644 if ( sp->value < 2*AM.MaxTer ) sp->value = 2*AM.MaxTer;
645 AM.CompressSize = sp->value;
646#ifndef WITHPTHREADS
647 AR.CompressBuffer = (WORD *)Malloc1((AM.CompressSize+10)*sizeof(WORD),"compresssize");
648 AR.CompressPointer = AR.CompressBuffer;
649 AR.ComprTop = AR.CompressBuffer + AM.CompressSize;
650#endif
651 sp = GetSetupPar((UBYTE *)"bracketindexsize");
652 if ( sp->value < 20*AM.MaxTer ) sp->value = 20*AM.MaxTer;
653 AM.MaxBracketBufferSize = sp->value/sizeof(WORD);
654
655 sp = GetSetupPar((UBYTE *)"dotchar");
656 AO.FortDotChar = ((UBYTE *)(sp->value))[0];
657 sp = GetSetupPar((UBYTE *)"commentchar");
658 AP.cComChar = AP.ComChar = ((UBYTE *)(sp->value))[0];
659 sp = GetSetupPar((UBYTE *)"procedureextension");
660/*
661 Check validity first.
662*/
663 s = (UBYTE *)(sp->value);
664 if ( FG.cTable[*s] != 0 ) {
665 MesPrint(" Illegal string for procedure extension %s",(UBYTE *)sp->value);
666 error = -2;
667 }
668 else {
669 s++;
670 while ( *s ) {
671 if ( *s == ' ' || *s == '\t' || *s == '\n' ) {
672 MesPrint(" Illegal string for procedure extension %s",(UBYTE *)sp->value);
673 error = -2;
674 break;
675 }
676 s++;
677 }
678 }
679 AP.cprocedureExtension = strDup1((UBYTE *)(sp->value),"procedureExtension");
680 AP.procedureExtension = strDup1(AP.cprocedureExtension,"procedureExtension");
681
682 sp = GetSetupPar((UBYTE *)"totalsize");
683 if ( sp->value != 2 ) AM.PrintTotalSize = sp->value;
684
685 sp = GetSetupPar((UBYTE *)"continuationlines");
686 AM.FortranCont = sp->value;
687 sp = GetSetupPar((UBYTE *)"oldorder");
688 AM.OldOrderFlag = sp->value;
689 sp = GetSetupPar((UBYTE *)"resettimeonclear");
690 AM.resetTimeOnClear = sp->value;
691 sp = GetSetupPar((UBYTE *)"nospacesinnumbers");
692 AO.NoSpacesInNumbers = AM.gNoSpacesInNumbers = AM.ggNoSpacesInNumbers = sp->value;
693 sp = GetSetupPar((UBYTE *)"indentspace");
694 AO.IndentSpace = AM.gIndentSpace = AM.ggIndentSpace = sp->value;
695 sp = GetSetupPar((UBYTE *)"jumpratio");
696 AM.jumpratio = sp->value;
697 sp = GetSetupPar((UBYTE *)"nwritestatistics");
698 AC.StatsFlag = AM.gStatsFlag = AM.ggStatsFlag = 1-sp->value;
699 sp = GetSetupPar((UBYTE *)"nwritefinalstatistics");
700 AC.FinalStats = AM.gFinalStats = AM.ggFinalStats = 1-sp->value;
701 sp = GetSetupPar((UBYTE *)"nwritethreadstatistics");
702 AC.ThreadStats = AM.gThreadStats = AM.ggThreadStats = 1-sp->value;
703 sp = GetSetupPar((UBYTE *)"nwriteprocessstatistics");
704 AC.ProcessStats = AM.gProcessStats = AM.ggProcessStats = 1-sp->value;
705 sp = GetSetupPar((UBYTE *)"oldparallelstatistics");
706 AC.OldParallelStats = AM.gOldParallelStats = AM.ggOldParallelStats = sp->value;
707 sp = GetSetupPar((UBYTE *)"oldfactarg");
708 AC.OldFactArgFlag = AM.gOldFactArgFlag = AM.ggOldFactArgFlag = sp->value;
709 sp = GetSetupPar((UBYTE *)"oldgcd");
710 AC.OldGCDflag = AM.gOldGCDflag = AM.ggOldGCDflag = sp->value;
711 sp = GetSetupPar((UBYTE *)"wtimestats");
712 if ( sp->value == 2 ) sp->value = AM.ggWTimeStatsFlag;
713 AC.WTimeStatsFlag = AM.gWTimeStatsFlag = AM.ggWTimeStatsFlag = sp->value;
714#ifdef WITHFLOAT
715 sp = GetSetupPar((UBYTE *)"maxweight");
716 AC.MaxWeight = AM.gMaxWeight = AM.ggMaxWeight = sp->value;
717 sp = GetSetupPar((UBYTE *)"defaultprecision");
718 AC.DefaultPrecision = AM.gDefaultPrecision = AM.ggDefaultPrecision = sp->value;
719#endif
720 sp = GetSetupPar((UBYTE *)"sorttype");
721 if ( StrICmp((UBYTE *)"lowfirst",(UBYTE *)sp->value) == 0 ) {
722 AC.lSortType = SORTLOWFIRST;
723 }
724 else if ( StrICmp((UBYTE *)"highfirst",(UBYTE *)sp->value) == 0 ) {
725 AC.lSortType = SORTHIGHFIRST;
726 }
727 else {
728 MesPrint(" Illegal SortType specification: %s",(UBYTE *)sp->value);
729 error = -2;
730 }
731
732 sp = GetSetupPar((UBYTE *)"processbucketsize");
733 AM.hProcessBucketSize = AM.gProcessBucketSize =
734 AC.ProcessBucketSize = AC.mProcessBucketSize = sp->value;
735/*
736 The store caches (code installed 15-aug-2006 JV)
737*/
738 sp = GetSetupPar((UBYTE *)"numstorecaches");
739 AM.NumStoreCaches = sp->value;
740 sp = GetSetupPar((UBYTE *)"sizestorecache");
741 AM.SizeStoreCache = sp->value;
742 /* Make sure this is a multiple of sizeof(WORD). */
743 AM.SizeStoreCache = ((AM.SizeStoreCache+sizeof(WORD)-1)/sizeof(WORD))*sizeof(WORD);
744#ifndef WITHPTHREADS
745/*
746 Install the store caches (15-aug-2006 JV)
747 Note that in the case of PTHREADS this is done in InitializeOneThread
748*/
749 AT.StoreCache = AT.StoreCacheAlloc = 0;
750 if ( AM.NumStoreCaches > 0 ) {
751 STORECACHE sa, sb;
752 size = sizeof(struct StOrEcAcHe)+AM.SizeStoreCache;
753 size = ((size-1)/sizeof(size_t)+1)*sizeof(size_t);
754 AT.StoreCacheAlloc = (STORECACHE)Malloc1(size*AM.NumStoreCaches,"StoreCaches");
755 AT.StoreCache = AT.StoreCacheAlloc;
756 sa = AT.StoreCache;
757 for ( j = 0; j < AM.NumStoreCaches; j++ ) {
758 sb = (STORECACHE)(void *)((UBYTE *)sa+size);
759 if ( j == AM.NumStoreCaches-1 ) {
760 sa->next = 0;
761 }
762 else {
763 sa->next = sb;
764 }
765 SETBASEPOSITION(sa->position,-1);
766 SETBASEPOSITION(sa->toppos,-1);
767 sa = sb;
768 }
769 }
770#endif
771
772/*
773 And now some order sensitive things
774*/
775 if ( AM.Path == 0 ) {
776 sp = GetSetupPar((UBYTE *)"path");
777 AM.Path = strDup1((UBYTE *)(sp->value),"path");
778 }
779 if ( AM.IncDir == 0 ) {
780 sp = GetSetupPar((UBYTE *)"incdir");
781 AM.IncDir = strDup1((UBYTE *)(sp->value),"incdir");
782 }
783/*
784 if ( AM.TempDir == 0 ) {
785 sp = GetSetupPar((UBYTE *)"tempdir");
786 AM.TempDir = strDup1((UBYTE *)(sp->value),"tempdir");
787 }
788*/
789 return(error);
790}
791
792/*
793 #] AllocSetups :
794 #[ WriteSetup :
795
796 The routine writes the values of the setup parameters.
797 We should do this better. (JV, 21-may-2008)
798 The way it should be done is:
799 a: write the raw values.
800 b: give readjusted values.
801 c: give derived values.
802 Because this is a difficult subject, it would be nice to have a LaTeX
803 document that explains this all exactly. There should then be a
804 mechanism to poke the values of the setup into the LaTeX document.
805 probably the easiest way is to make a file with lots of \def definitions
806 and have that included into the LaTeX file.
807*/
808
809void WriteSetup(void)
810{
811 int n = sizeof(setupparameters)/sizeof(SETUPPARAMETERS);
812 SETUPPARAMETERS *sp;
813 MesPrint(" The setup parameters are:");
814 for ( sp = setupparameters; n > 0; n--, sp++ ) {
815 switch(sp->type){
816 case NUMERICALVALUE:
817 MesPrint(" %s: %l",sp->parameter,sp->value);
818 break;
819 case PATHVALUE:
820 if ( StrICmp(sp->parameter,(UBYTE *)"path") == 0 && AM.Path ) {
821 MesPrint(" %s: '%s'",sp->parameter,(UBYTE *)(AM.Path));
822 break;
823 }
824 if ( StrICmp(sp->parameter,(UBYTE *)"incdir") == 0 && AM.IncDir ) {
825 MesPrint(" %s: '%s'",sp->parameter,(UBYTE *)(AM.IncDir));
826 break;
827 }
828 /* fall through */
829 case STRINGVALUE:
830 if ( StrICmp(sp->parameter,(UBYTE *)"tempdir") == 0 && AM.TempDir ) {
831 MesPrint(" %s: '%s'",sp->parameter,(UBYTE *)(AM.TempDir));
832 }
833 else if ( StrICmp(sp->parameter,(UBYTE *)"tempsortdir") == 0 && AM.TempSortDir ) {
834 MesPrint(" %s: '%s'",sp->parameter,(UBYTE *)(AM.TempSortDir));
835 }
836 else {
837 MesPrint(" %s: '%s'",sp->parameter,(UBYTE *)(sp->value));
838 }
839 break;
840 case ONOFFVALUE:
841 if ( sp->value == 0 )
842 MesPrint(" %s: OFF",sp->parameter);
843 else if ( sp->value == 1 )
844 MesPrint(" %s: ON",sp->parameter);
845 break;
846 case DEFINEVALUE:
847/*
848 MesPrint(" %s: '%s'",sp->parameter,(UBYTE *)(sp->value));
849*/
850 break;
851 }
852 }
853 AC.SetupFlag = 0;
854}
855
856/*
857 #] WriteSetup :
858 #[ AllocSort :
859
860 Routine allocates a complete struct for sorting.
861 To be used for the main allocation of the sort buffers, and
862 in a later stage for the function and subroutine sort buffers.
863 The level arg denotes a main buffer allocation (0) or a sub-buffer
864 allocation (1), used only for printing warning messages for buffer
865 size adjustments in DEBUGGING mode.
866*/
867SORTING *AllocSort(LONG inLargeSize, LONG inSmallSize, LONG inSmallEsize, LONG inTermsInSmall,
868 int inMaxPatches, int inMaxFpatches, LONG inIOsize, int level)
869{
870 DUMMYUSE(level); /* This is only used in DEBUGGING mode */
871 LONG LargeSize = inLargeSize;
872 LONG SmallSize = inSmallSize;
873 LONG SmallEsize = inSmallEsize;
874 LONG TermsInSmall = inTermsInSmall;
875 int MaxPatches = inMaxPatches;
876 int MaxFpatches = inMaxFpatches;
877 LONG IOsize = inIOsize;
878
879 LONG longer,terms2insmall,sortsize,longerp;
880 LONG IObuffersize = IOsize;
881 LONG IOtry;
882 SORTING *sort;
883 int fname2Size = 0, j = 0;
884 char *s;
885 if ( AM.S0 != 0 ) {
886 s = FG.fname2; fname2Size = 0;
887 while ( *s ) { s++; fname2Size++; }
888 fname2Size += 16;
889 }
890 if ( MaxFpatches < 4 ) MaxFpatches = 4;
891 longer = MaxPatches > MaxFpatches ? MaxPatches : MaxFpatches;
892 longerp = longer;
893 while ( (1 << j) < longerp ) j++;
894 longerp = (1 << j) + 1;
895 longerp += sizeof(WORD*) - (longerp%sizeof(WORD *));
896 longer++;
897 longer += sizeof(WORD*) - (longer%sizeof(WORD *));
898 if ( SmallSize < 16*AM.MaxTer ) SmallSize = 16*AM.MaxTer+16;
899 TermsInSmall = (TermsInSmall+15) & (-16L);
900 terms2insmall = 2*TermsInSmall; /* Used to be just + 100 rather than *2 */
901 if ( SmallEsize < (SmallSize*3)/2 ) SmallEsize = (SmallSize*3)/2;
902 if ( LargeSize > 0 && LargeSize < 2*SmallSize ) LargeSize = 2*SmallSize;
903 SmallEsize = (SmallEsize+15) & (-16L);
904 if ( LargeSize < 0 ) LargeSize = 0;
905 sortsize = sizeof(SORTING);
906 sortsize = (sortsize+15)&(-16L);
907 IObuffersize = (IObuffersize+sizeof(WORD)-1)/sizeof(WORD);
908/*
909 The next statement fixes a bug. In the rare case that we have a
910 problem here, we expand the size of the large buffer or the
911 small extension
912*/
913 if ( (ULONG)( LargeSize+SmallEsize ) < MaxFpatches*((IObuffersize
914 +COMPINC)*sizeof(WORD)+2*AM.MaxTer) ) {
915 if ( LargeSize == 0 )
916 SmallEsize = MaxFpatches*((IObuffersize+COMPINC)*sizeof(WORD)+2*AM.MaxTer);
917 else
918 LargeSize = MaxFpatches*((IObuffersize+COMPINC)*sizeof(WORD)+2*AM.MaxTer)
919 - SmallEsize;
920 }
921
922 IOtry = ((LargeSize+SmallEsize)/MaxFpatches-2*AM.MaxTer)/sizeof(WORD)-COMPINC;
923
924 /* Here both IObuffersize and IOtry are in units of sizeof(WORD). */
925 if ( IObuffersize < IOtry ) {
926 IObuffersize = IOtry;
927 }
928
929#if DEBUGGING
930 char *prefix;
931 if ( level == 0 ) { prefix = ""; }
932 else { prefix = "Sub"; }
933 if ( LargeSize != inLargeSize ) { MesPrint("Warning: %sLargeSize adjusted: %l -> %l", prefix, inLargeSize, LargeSize); }
934 if ( SmallSize != inSmallSize ) { MesPrint("Warning: %sSmallSize adjusted: %l -> %l", prefix, inSmallSize, SmallSize); }
935 if ( SmallEsize != inSmallEsize ) {MesPrint("Warning: %sSmallEsize adjusted: %l -> %l", prefix, inSmallEsize, SmallEsize); }
936 if ( TermsInSmall != inTermsInSmall ) { MesPrint("Warning: %sTermsInSmall adjusted: %l -> %l", prefix, inTermsInSmall, TermsInSmall); }
937 if ( MaxPatches != inMaxPatches ) { MesPrint("Warning: MaxPatches adjusted: %d -> %d", inMaxPatches, MaxPatches); }
938 if ( MaxFpatches != inMaxFpatches ) {MesPrint("Warning: MaxFPatches adjusted: %d -> %d", inMaxFpatches, MaxFpatches); }
939 /* This one is always changed if the LargeSize has not been... */
940 /* if ( IObuffersize != inIOsize/(LONG)sizeof(WORD) ) { MesPrint("Warning: IOsize adjusted: %l -> %l", inIOsize/sizeof(WORD), IObuffersize); } */
941#endif
942
943 /* Allocate separate buffers for most struct members, for better testing and debugging with valgrind. */
944 sort = Malloc1(sizeof(*sort), "AllocSort: sorting struct");
945
946 sort->LargeSize = LargeSize/sizeof(WORD);
947 sort->SmallSize = SmallSize/sizeof(WORD);
948 sort->SmallEsize = SmallEsize/sizeof(WORD);
949 sort->MaxPatches = MaxPatches;
950 sort->MaxFpatches = MaxFpatches;
951 sort->TermsInSmall = TermsInSmall;
952 sort->Terms2InSmall = terms2insmall;
953
954 sort->sPointer = Malloc1(sizeof(*(sort->sPointer ))*terms2insmall, "AllocSort: sPointer");
955 sort->Patches = Malloc1(sizeof(*(sort->Patches ))*longer, "AllocSort: Patches");
956 sort->pStop = Malloc1(sizeof(*(sort->pStop ))*longer, "AllocSort: pStop");
957 sort->poina = Malloc1(sizeof(*(sort->poina ))*longerp, "AllocSort: poina");
958 sort->poin2a = Malloc1(sizeof(*(sort->poin2a ))*longerp, "AllocSort: poin2a");
959
960 sort->fPatches = Malloc1(sizeof(*(sort->fPatches ))*longer, "AllocSort: fPatches");
961 sort->fPatchesStop = Malloc1(sizeof(*(sort->fPatchesStop))*longer, "AllocSort: fPatchesStop");
962 sort->inPatches = Malloc1(sizeof(*(sort->inPatches ))*longer, "AllocSort: inPatches");
963 sort->tree = Malloc1(sizeof(*(sort->tree ))*longerp, "AllocSort: tree");
964 sort->used = Malloc1(sizeof(*(sort->used ))*longerp, "AllocSort: used");
965
966#ifdef WITHZLIB
967 sort->fpcompressed = Malloc1(sizeof(*(sort->fpcompressed ))*(longerp+2), "AllocSort: fpcompressed");
968 sort->fpincompressed = Malloc1(sizeof(*(sort->fpincompressed))*(longerp+2), "AllocSort: fpincompressed");
969 sort->zsparray = 0;
970#endif
971
972 sort->ktoi = Malloc1(sizeof(*(sort->ktoi))*(longerp+2), "AllocSort: ktoi");
973
974 // The combined Large buffer and Small buffer (+ extension) are used.
975 // They must be allocated together.
976 sort->lBuffer = Malloc1(sizeof(*(sort->lBuffer))*(sort->LargeSize+sort->SmallEsize), "AllocSort: lBuffer+sBuffer");
977 sort->lTop = sort->lBuffer+sort->LargeSize;
978
979 sort->sBuffer = sort->lTop;
980 if ( sort->LargeSize == 0 ) { sort->lBuffer = 0; sort->lTop = 0; }
981 sort->sTop = sort->sBuffer + sort->SmallSize;
982 sort->sTop2 = sort->sBuffer + sort->SmallEsize;
983 sort->sHalf = sort->sBuffer + (LONG)((sort->SmallSize+sort->SmallEsize)>>1);
984
985 sort->file.PObuffer = Malloc1(IObuffersize*sizeof(*(sort->file.PObuffer))+fname2Size+16, "AllocSort: PObuffer");
986 sort->file.POstop = sort->file.PObuffer+IObuffersize;
987 sort->file.POsize = IObuffersize * sizeof(WORD);
988 sort->file.POfill = sort->file.POfull = sort->file.PObuffer;
989 sort->file.active = 0;
990 sort->file.handle = -1;
991 PUTZERO(sort->file.POposition);
992#ifdef WITHPTHREADS
993 sort->file.pthreadslock = dummylock;
994#endif
995#ifdef WITHZLIB
996 sort->file.ziosize = IObuffersize*sizeof(WORD);
997 sort->file.ziobuffer = 0;
998#endif
999 if ( AM.S0 != 0 ) {
1000 sort->file.name = (char *)(sort->file.PObuffer + IObuffersize);
1001 AllocSortFileName(sort);
1002 }
1003 else sort->file.name = 0;
1004 sort->cBuffer = 0;
1005 sort->cBufferSize = 0;
1006 sort->f = 0;
1007 sort->PolyWise = 0;
1008
1009 return(sort);
1010}
1011
1012/*
1013 #] AllocSort :
1014 #[ AllocSortFileName :
1015*/
1016
1017void AllocSortFileName(SORTING *sort)
1018{
1019 GETIDENTITY
1020 char *s, *t;
1021/*
1022 This is not the allocation before the tempfiles are determined.
1023 Hence we can use the name in FG.fname2 and modify the tail
1024*/
1025 s = FG.fname2; t = sort->file.name;
1026 while ( *s ) *t++ = *s++;
1027#ifdef WITHPTHREADS
1028 t[-2] = 'F';
1029 snprintf(t-1,FG.fname2size-(t-1-sort->file.name),"%d.%d",identity,AN.filenum);
1030#else
1031 t[-2] = 'f';
1032 snprintf(t-1,FG.fname2size-(t-1-sort->file.name),"%d",AN.filenum);
1033#endif
1034 AN.filenum++;
1035}
1036
1037/*
1038 #] AllocSortFileName :
1039 #[ AllocFileHandle :
1040*/
1041
1042FILEHANDLE *AllocFileHandle(WORD par,char *name)
1043{
1044 GETIDENTITY
1045 LONG allocation, Ssize;
1046 FILEHANDLE *fh;
1047 int i = 0;
1048 char *s, *t;
1049
1050 s = FG.fname2; i = 0;
1051 while ( *s ) { s++; i++; }
1052 if ( par == 0 ) { i += 16; Ssize = AM.SIOsize; }
1053 else { s = name; while ( *s ) { i++; s++; } i+= 2; Ssize = AM.SpectatorSize; }
1054
1055 allocation = sizeof(FILEHANDLE) + (Ssize+1)*sizeof(WORD) + i*sizeof(char)
1056 +FG.fname2size+20;
1057 fh = (FILEHANDLE *)Malloc1(allocation,"FileHandle");
1058
1059 fh->PObuffer = (WORD *)(fh+1);
1060 fh->POstop = fh->PObuffer+Ssize;
1061 fh->POsize = Ssize * sizeof(WORD);
1062 fh->active = 0;
1063 fh->handle = -1;
1064 PUTZERO(fh->POposition);
1065#ifdef WITHPTHREADS
1066 fh->pthreadslock = dummylock;
1067#endif
1068 if ( par == 0 ) { /* sort file */
1069 if ( AM.S0 != 0 ) {
1070 fh->name = (char *)(fh->POstop + 1);
1071 s = FG.fname2; t = fh->name;
1072 while ( *s ) *t++ = *s++;
1073#ifdef WITHPTHREADS
1074 t[-2] = 'F';
1075 snprintf(t-1,FG.fname2size-(t-1-fh->name),"%d-%d",identity,AN.filenum);
1076#else
1077 t[-2] = 'f';
1078 snprintf(t-1,FG.fname2size-(t-1-fh->name),"%d",AN.filenum);
1079#endif
1080 AN.filenum++;
1081 }
1082 else fh->name = 0;
1083 }
1084 else { /* Spectator file */
1085 fh->name = (char *)(fh->POstop + 1);
1086 s = FG.fname; t = fh->name;
1087 for ( i = 0; i < FG.fnamebase; i++ ) *t++ = *s++;
1088 s = name;
1089 while ( *s ) *t++ = *s++;
1090 *t = 0;
1091 }
1092 fh->POfill = fh->POfull = fh->PObuffer;
1093 return(fh);
1094}
1095
1096/*
1097 #] AllocFileHandle :
1098 #[ DeAllocFileHandle :
1099
1100 Made to repair deallocation of AN.filenum. 21-sep-2000
1101*/
1102
1103void DeAllocFileHandle(FILEHANDLE *fh)
1104{
1105 GETIDENTITY
1106 if ( fh->handle >= 0 ) {
1107 CloseFile(fh->handle);
1108 fh->handle = -1;
1109 remove(fh->name);
1110 }
1111 AN.filenum--; /* free namespace. was forgotten in first reading */
1112 M_free(fh,"Temporary FileHandle");
1113}
1114
1115/*
1116 #] DeAllocFileHandle :
1117 #[ MakeSetupAllocs :
1118*/
1119
1120int MakeSetupAllocs(void)
1121{
1122 if ( RecalcSetups() || AllocSetups() ) return(1);
1123 else return(0);
1124}
1125
1126/*
1127 #] MakeSetupAllocs :
1128 #[ AllocNormData :
1129
1130 Allocate the arrays within the NORMDATA struct. These are dynamic,
1131 such that valgrind can detect buffer overruns in these arrays.
1132*/
1133
1134NORMDATA* AllocNormData(void)
1135{
1136 NORMDATA* tmp = Malloc1(sizeof(NORMDATA), "NormData struct");
1137
1138 tmp->psym = Malloc1(7*NORMSIZE*sizeof(*(tmp->psym)), "Normalize struct psym");
1139 tmp->pvec = Malloc1(1*NORMSIZE*sizeof(*(tmp->pvec)), "Normalize struct pvec");
1140 tmp->pdot = Malloc1(3*NORMSIZE*sizeof(*(tmp->pdot)), "Normalize struct pdot");
1141 tmp->pdel = Malloc1(2*NORMSIZE*sizeof(*(tmp->pdel)), "Normalize struct pdel");
1142 tmp->pind = Malloc1(1*NORMSIZE*sizeof(*(tmp->pind)), "Normalize struct pind");
1143 tmp->peps = Malloc1(NORMSIZE/3*sizeof(*(tmp->peps)), "Normalize struct peps");
1144 tmp->pden = Malloc1(NORMSIZE/3*sizeof(*(tmp->pden)), "Normalize struct pden");
1145 tmp->pcom = Malloc1(1*NORMSIZE*sizeof(*(tmp->pcom)), "Normalize struct pcom");
1146 tmp->pnco = Malloc1(1*NORMSIZE*sizeof(*(tmp->pnco)), "Normalize struct pnco");
1147 tmp->pcon = Malloc1(2*NORMSIZE*sizeof(*(tmp->pcon)), "Normalize struct pcon");
1148
1149 return tmp;
1150}
1151
1152/*
1153 #] AllocNormData :
1154 #[ TryFileSetups :
1155
1156 Routine looks in the input file for a start of the type
1157 [#-]
1158 #: setupparameter value
1159 It keeps looking until the first line that does not start with
1160 #-, #+ or #:
1161 Then it rewinds the input.
1162*/
1163
1164#define SETBUFSIZE 257
1165
1166int TryFileSetups(void)
1167{
1168 LONG oldstreamposition;
1169 int oldstream;
1170 int error = 0, eqnum;
1171 int oldNoShowInput = AC.NoShowInput;
1172 UBYTE buff[SETBUFSIZE+1], *s, *t, *u, *settop, c;
1173 LONG linenum, prevline;
1174
1175 if ( AC.CurrentStream == 0 ) return(error);
1176 oldstream = AC.CurrentStream - AC.Streams;
1177 oldstreamposition = GetStreamPosition(AC.CurrentStream);
1178 linenum = AC.CurrentStream->linenumber;
1179 prevline = AC.CurrentStream->prevline;
1180 eqnum = AC.CurrentStream->eqnum;
1181 AC.NoShowInput = 1;
1182 settop = buff + SETBUFSIZE;
1183 if ( AC.CurrentStream->type == INPUTSTREAM && oldstreamposition == 0 ) AC.CurrentStream->fileposition = 0;
1184 for(;;) {
1185 c = GetInput();
1186 if ( c == '*' || c == '\n' ) {
1187 while ( c != '\n' && c != ENDOFINPUT ) c = GetInput();
1188 if ( c == ENDOFINPUT ) goto eoi;
1189 continue;
1190 }
1191 if ( c == ENDOFINPUT ) goto eoi;
1192 if ( c != '#' ) break;
1193 c = GetInput();
1194 if ( c == ENDOFINPUT ) goto eoi;
1195 if ( c != '-' && c != '+' && c != ':' ) break;
1196 if ( c != ':' ) {
1197 while ( c != '\n' && c != ENDOFINPUT ) c = GetInput();
1198 continue;
1199 }
1200 s = buff;
1201 while ( ( c = GetInput() ) == ' ' || c == '\t' || c == '\r' ) {}
1202 if ( c == ENDOFINPUT ) break;
1203 if ( c == LINEFEED ) continue;
1204 if ( c == 0 || c == ENDOFINPUT ) break;
1205 while ( c != LINEFEED && c != ENDOFINPUT ) {
1206 *s++ = c;
1207 c = GetInput();
1208 if ( c != LINEFEED && c != '\r' ) continue;
1209 if ( s >= settop ) {
1210 while ( c != '\n' && c != ENDOFINPUT ) c = GetInput();
1211 MesPrint("Setups in .frm file: Line too long. setup ignored");
1212 error++; goto nextline;
1213 }
1214 }
1215 *s++ = '\n';
1216 t = s = buff; /* name of the option */
1217 while ( tolower(*s) >= 'a' && tolower(*s) <= 'z' ) s++;
1218 if ( *s != '\n' ) {
1219 *s++ = 0;
1220 while ( *s == ' ' || *s == '\t' ) s++;
1221 u = s; /* 'value' of the option */
1222 while ( *s && *s != '\n' && *s != '\r' ) s++;
1223 if ( *s ) *s++ = 0;
1224 }
1225 else {
1226 /* The value is empty. */
1227 u = s;
1228 *s++ = 0;
1229 }
1230 error += ProcessOption(t,u,1);
1231nextline:;
1232 }
1233 AC.NoShowInput = oldNoShowInput;
1234 AC.CurrentStream = AC.Streams + oldstream;
1235 PositionStream(AC.CurrentStream,oldstreamposition);
1236 AC.CurrentStream->linenumber = linenum;
1237 AC.CurrentStream->prevline = prevline;
1238 AC.CurrentStream->eqnum = eqnum;
1239 ClearPushback();
1240 if ( AC.CurrentStream->type == INPUTSTREAM ) AC.CurrentStream->fileposition = -1;
1241 return(error);
1242eoi:
1243 MesPrint("Input file without a program.");
1244 return(-1);
1245}
1246
1247/*
1248 #] TryFileSetups :
1249 #[ TryEnvironment :
1250*/
1251
1252int TryEnvironment(void)
1253{
1254 char *s, *t, *u, varname[100];
1255 int i,imax = sizeof(setupparameters)/sizeof(SETUPPARAMETERS);
1256 int error = 0;
1257 varname[0] = 'F'; varname[1] = 'O'; varname[2] = 'R'; varname[3] = 'M';
1258 varname[4] = '_'; varname[5] = 0;
1259 for ( i = 0; i < imax; i++ ) {
1260 t = s = (char *)(setupparameters[i].parameter);
1261 u = varname+5;
1262 while ( *s ) { *u++ = (char)(toupper((unsigned char)*s)); s++; }
1263 *u = 0;
1264 s = (char *)(getenv(varname));
1265 if ( s ) {
1266 error += ProcessOption((UBYTE *)t,(UBYTE *)s,2);
1267 }
1268 }
1269 return(error);
1270}
1271
1272/*
1273 #] TryEnvironment :
1274 #] Setups :
1275*/
int TheDefine(UBYTE *, int)
Definition pre.c:2030
int handle
Definition structs.h:709
struct NeStInG * NESTING
struct FiLe FILEHANDLE
struct sOrT SORTING
struct StOrEcAcHe * STORECACHE