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