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 
39 char curdirp[] = ".";
40 char cursortdirp[] = ".";
41 char commentchar[] = "*";
42 char dotchar[] = "_";
43 char highfirst[] = "highfirst";
44 char lowfirst[] = "lowfirst";
45 char procedureextension[] = "prc";
46 
47 #define NUMERICALVALUE 0
48 #define STRINGVALUE 1
49 #define PATHVALUE 2
50 #define ONOFFVALUE 3
51 #define DEFINEVALUE 4
52 
53 SETUPPARAMETERS 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 
126 int 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 
174 static char *proop1[3] = { "Setup file", "Setups in .frm file", "Setup in environment" };
175 
176 int 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 */
188 restart:;
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 
331 SETUPPARAMETERS *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 
351 int 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 
398 int 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 
782 VOID 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 
838 SORTING *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 
973 VOID 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 
998 FILEHANDLE *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 
1058 void 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 
1075 int 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 
1095 int 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);
1160 nextline:;
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);
1171 eoi:
1172  MesPrint("Input file without a program.");
1173  return(-1);
1174 }
1175 
1176 /*
1177  #] TryFileSetups :
1178  #[ TryEnvironment :
1179 */
1180 
1181 int 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 */
struct sOrT SORTING
Definition: structs.h:633
struct FiLe FILEHANDLE
Definition: structs.h:1086
struct NeStInG * NESTING
struct StOrEcAcHe * STORECACHE
int TheDefine(UBYTE *, int)
Definition: pre.c:1942
int handle
Definition: structs.h:661