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