FORM  4.2.1
setfile.c
Go to the documentation of this file.
1 
5 /* #[ License : */
6 /*
7  * Copyright (C) 1984-2017 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  if ( AM.FortranCont <= 0 ) AM.FortranCont = 1;
669  sp = GetSetupPar((UBYTE *)"oldorder");
670  AM.OldOrderFlag = sp->value;
671  sp = GetSetupPar((UBYTE *)"resettimeonclear");
672  AM.resetTimeOnClear = sp->value;
673  sp = GetSetupPar((UBYTE *)"nospacesinnumbers");
674  AO.NoSpacesInNumbers = AM.gNoSpacesInNumbers = AM.ggNoSpacesInNumbers = sp->value;
675  sp = GetSetupPar((UBYTE *)"indentspace");
676  AO.IndentSpace = AM.gIndentSpace = AM.ggIndentSpace = sp->value;
677  sp = GetSetupPar((UBYTE *)"jumpratio");
678  AM.jumpratio = sp->value;
679  sp = GetSetupPar((UBYTE *)"nwritestatistics");
680  AC.StatsFlag = AM.gStatsFlag = AM.ggStatsFlag = 1-sp->value;
681  sp = GetSetupPar((UBYTE *)"nwritefinalstatistics");
682  AC.FinalStats = AM.gFinalStats = AM.ggFinalStats = 1-sp->value;
683  sp = GetSetupPar((UBYTE *)"nwritethreadstatistics");
684  AC.ThreadStats = AM.gThreadStats = AM.ggThreadStats = 1-sp->value;
685  sp = GetSetupPar((UBYTE *)"nwriteprocessstatistics");
686  AC.ProcessStats = AM.gProcessStats = AM.ggProcessStats = 1-sp->value;
687  sp = GetSetupPar((UBYTE *)"oldparallelstatistics");
688  AC.OldParallelStats = AM.gOldParallelStats = AM.ggOldParallelStats = sp->value;
689  sp = GetSetupPar((UBYTE *)"oldfactarg");
690  AC.OldFactArgFlag = AM.gOldFactArgFlag = AM.ggOldFactArgFlag = sp->value;
691  sp = GetSetupPar((UBYTE *)"oldgcd");
692  AC.OldGCDflag = AM.gOldGCDflag = AM.ggOldGCDflag = sp->value;
693  sp = GetSetupPar((UBYTE *)"wtimestats");
694  if ( sp->value == 2 ) sp->value = AM.ggWTimeStatsFlag;
695  AC.WTimeStatsFlag = AM.gWTimeStatsFlag = AM.ggWTimeStatsFlag = sp->value;
696  sp = GetSetupPar((UBYTE *)"sorttype");
697  if ( StrICmp((UBYTE *)"lowfirst",(UBYTE *)sp->value) == 0 ) {
698  AC.lSortType = SORTLOWFIRST;
699  }
700  else if ( StrICmp((UBYTE *)"highfirst",(UBYTE *)sp->value) == 0 ) {
701  AC.lSortType = SORTHIGHFIRST;
702  }
703  else {
704  MesPrint(" Illegal SortType specification: %s",(UBYTE *)sp->value);
705  error = -2;
706  }
707 
708  sp = GetSetupPar((UBYTE *)"processbucketsize");
709  AM.hProcessBucketSize = AM.gProcessBucketSize =
710  AC.ProcessBucketSize = AC.mProcessBucketSize = sp->value;
711 /*
712  The store caches (code installed 15-aug-2006 JV)
713 */
714  sp = GetSetupPar((UBYTE *)"numstorecaches");
715  AM.NumStoreCaches = sp->value;
716  sp = GetSetupPar((UBYTE *)"sizestorecache");
717  AM.SizeStoreCache = sp->value;
718 #ifndef WITHPTHREADS
719 /*
720  Install the store caches (15-aug-2006 JV)
721  Note that in the case of PTHREADS this is done in InitializeOneThread
722 */
723  AT.StoreCache = AT.StoreCacheAlloc = 0;
724  if ( AM.NumStoreCaches > 0 ) {
725  STORECACHE sa, sb;
726  size = sizeof(struct StOrEcAcHe)+AM.SizeStoreCache;
727  size = ((size-1)/sizeof(size_t)+1)*sizeof(size_t);
728  AT.StoreCacheAlloc = (STORECACHE)Malloc1(size*AM.NumStoreCaches,"StoreCaches");
729  AT.StoreCache = AT.StoreCacheAlloc;
730  sa = AT.StoreCache;
731  for ( j = 0; j < AM.NumStoreCaches; j++ ) {
732  sb = (STORECACHE)(VOID *)((UBYTE *)sa+size);
733  if ( j == AM.NumStoreCaches-1 ) {
734  sa->next = 0;
735  }
736  else {
737  sa->next = sb;
738  }
739  SETBASEPOSITION(sa->position,-1);
740  SETBASEPOSITION(sa->toppos,-1);
741  sa = sb;
742  }
743  }
744 #endif
745 
746 /*
747  And now some order sensitive things
748 */
749  if ( AM.Path == 0 ) {
750  sp = GetSetupPar((UBYTE *)"path");
751  AM.Path = strDup1((UBYTE *)(sp->value),"path");
752  }
753  if ( AM.IncDir == 0 ) {
754  sp = GetSetupPar((UBYTE *)"incdir");
755  AM.IncDir = strDup1((UBYTE *)(sp->value),"incdir");
756  }
757 /*
758  if ( AM.TempDir == 0 ) {
759  sp = GetSetupPar((UBYTE *)"tempdir");
760  AM.TempDir = strDup1((UBYTE *)(sp->value),"tempdir");
761  }
762 */
763  return(error);
764 }
765 
766 /*
767  #] AllocSetups :
768  #[ WriteSetup :
769 
770  The routine writes the values of the setup parameters.
771  We should do this better. (JV, 21-may-2008)
772  The way it should be done is:
773  a: write the raw values.
774  b: give readjusted values.
775  c: give derived values.
776  Because this is a difficult subject, it would be nice to have a LaTeX
777  document that explains this all exactly. There should then be a
778  mechanism to poke the values of the setup into the LaTeX document.
779  probably the easiest way is to make a file with lots of \def definitions
780  and have that included into the LaTeX file.
781 */
782 
783 VOID WriteSetup()
784 {
785  int n = sizeof(setupparameters)/sizeof(SETUPPARAMETERS);
786  SETUPPARAMETERS *sp;
787  MesPrint(" The setup parameters are:");
788  for ( sp = setupparameters; n > 0; n--, sp++ ) {
789  switch(sp->type){
790  case NUMERICALVALUE:
791  MesPrint(" %s: %l",sp->parameter,sp->value);
792  break;
793  case PATHVALUE:
794  if ( StrICmp(sp->parameter,(UBYTE *)"path") == 0 && AM.Path ) {
795  MesPrint(" %s: '%s'",sp->parameter,(UBYTE *)(AM.Path));
796  break;
797  }
798  if ( StrICmp(sp->parameter,(UBYTE *)"incdir") == 0 && AM.IncDir ) {
799  MesPrint(" %s: '%s'",sp->parameter,(UBYTE *)(AM.IncDir));
800  break;
801  }
802  /* fall through */
803  case STRINGVALUE:
804  if ( StrICmp(sp->parameter,(UBYTE *)"tempdir") == 0 && AM.TempDir ) {
805  MesPrint(" %s: '%s'",sp->parameter,(UBYTE *)(AM.TempDir));
806  }
807  else if ( StrICmp(sp->parameter,(UBYTE *)"tempsortdir") == 0 && AM.TempSortDir ) {
808  MesPrint(" %s: '%s'",sp->parameter,(UBYTE *)(AM.TempSortDir));
809  }
810  else {
811  MesPrint(" %s: '%s'",sp->parameter,(UBYTE *)(sp->value));
812  }
813  break;
814  case ONOFFVALUE:
815  if ( sp->value == 0 )
816  MesPrint(" %s: OFF",sp->parameter);
817  else if ( sp->value == 1 )
818  MesPrint(" %s: ON",sp->parameter);
819  break;
820  case DEFINEVALUE:
821 /*
822  MesPrint(" %s: '%s'",sp->parameter,(UBYTE *)(sp->value));
823 */
824  break;
825  }
826  }
827  AC.SetupFlag = 0;
828 }
829 
830 /*
831  #] WriteSetup :
832  #[ AllocSort :
833 
834  Routine allocates a complete struct for sorting.
835  To be used for the main allocation of the sort buffers, and
836  in a later stage for the function and subroutine sort buffers.
837 */
838 
839 SORTING *AllocSort(LONG LargeSize, LONG SmallSize, LONG SmallEsize, LONG TermsInSmall,
840  int MaxPatches, int MaxFpatches, LONG IOsize)
841 {
842  LONG allocation,longer,terms2insmall,sortsize,longerp;
843  LONG IObuffersize = IOsize;
844  LONG IOtry;
845  SORTING *sort;
846  int i = 0, j = 0;
847  char *s;
848  if ( AM.S0 != 0 ) {
849  s = FG.fname2; i = 0;
850  while ( *s ) { s++; i++; }
851  i += 16;
852  }
853  if ( MaxFpatches < 4 ) MaxFpatches = 4;
854  longer = MaxPatches > MaxFpatches ? MaxPatches : MaxFpatches;
855  longerp = longer;
856  while ( (1 << j) < longerp ) j++;
857  longerp = (1 << j) + 1;
858  longerp += sizeof(WORD*) - (longerp%sizeof(WORD *));
859  longer++;
860  longer += sizeof(WORD*) - (longer%sizeof(WORD *));
861  if ( SmallSize < 16*AM.MaxTer ) SmallSize = 16*AM.MaxTer+16;
862  TermsInSmall = (TermsInSmall+15) & (-16L);
863  terms2insmall = 2*TermsInSmall; /* Used to be just + 100 rather than *2 */
864  if ( SmallEsize < (SmallSize*3)/2 ) SmallEsize = (SmallSize*3)/2;
865  if ( LargeSize > 0 && LargeSize < 2*SmallSize ) LargeSize = 2*SmallSize;
866 /* if ( SmallEsize < 3*AM.MaxTer ) SmallEsize = 3*AM.MaxTer; */
867  SmallEsize = (SmallEsize+15) & (-16L);
868  if ( LargeSize < 0 ) LargeSize = 0;
869  sortsize = sizeof(SORTING);
870  sortsize = (sortsize+15)&(-16L);
871  IObuffersize = (IObuffersize+sizeof(WORD)-1)/sizeof(WORD);
872 /*
873  The next statement fixes a bug. In the rare case that we have a
874  problem here, we expand the size of the large buffer or the
875  small extension
876 */
877  if ( (ULONG)( LargeSize+SmallEsize ) < MaxFpatches*((IObuffersize
878  +COMPINC)*sizeof(WORD)+2*AM.MaxTer) ) {
879  if ( LargeSize == 0 )
880  SmallEsize = MaxFpatches*((IObuffersize+COMPINC)*sizeof(WORD)+2*AM.MaxTer);
881  else
882  LargeSize = MaxFpatches*((IObuffersize+COMPINC)*sizeof(WORD)+2*AM.MaxTer)
883  - SmallEsize;
884  }
885 
886  IOtry = ((LargeSize+SmallEsize)/MaxFpatches-2*AM.MaxTer)/sizeof(WORD)-COMPINC;
887 
888  if ( (LONG)(IObuffersize*sizeof(WORD)) < IOtry )
889  IObuffersize = (IOtry+sizeof(WORD)-1)/sizeof(WORD);
890 
891  allocation =
892  3*sizeof(POSITION)*(LONG)longer /* Filepositions!! */
893  +2*sizeof(WORD *)*longer
894  +2*(longerp*(sizeof(WORD *)+sizeof(WORD)))
895  +(3*longerp+2)*sizeof(WORD)
896 #ifdef WITHZLIB
897  +(2*longerp+4)*sizeof(WORD)
898 #endif
899  +terms2insmall*sizeof(WORD *)
900  +terms2insmall*sizeof(WORD *)/2
901  +LargeSize
902  +SmallEsize
903  +sortsize
904  +IObuffersize*sizeof(WORD) + i + 16;
905  sort = (SORTING *)Malloc1(allocation,"sort buffers");
906 
907  sort->LargeSize = LargeSize/sizeof(WORD);
908  sort->SmallSize = SmallSize/sizeof(WORD);
909  sort->SmallEsize = SmallEsize/sizeof(WORD);
910  sort->MaxPatches = MaxPatches;
911  sort->MaxFpatches = MaxFpatches;
912  sort->TermsInSmall = TermsInSmall;
913  sort->Terms2InSmall = terms2insmall;
914 
915  sort->sPointer = (WORD **)(sort+1);
916  sort->SplitScratch = sort->sPointer + terms2insmall;
917  sort->Patches = (WORD **)(sort->SplitScratch + terms2insmall/2);
918  sort->pStop = sort->Patches+longer;
919  sort->poina = sort->pStop+longer;
920  sort->poin2a = sort->poina + longerp;
921  sort->fPatches = (POSITION *)(sort->poin2a+longerp);
922  sort->fPatchesStop = sort->fPatches + longer;
923  sort->inPatches = sort->fPatchesStop + longer;
924  sort->tree = (WORD *)(sort->inPatches + longer);
925  sort->used = sort->tree+longerp;
926 #ifdef WITHZLIB
927  sort->fpcompressed = sort->used+longerp;
928  sort->fpincompressed = sort->fpcompressed+longerp+2;
929  sort->ktoi = sort->fpincompressed+longerp+2;
930  sort->zsparray = 0;
931 #else
932  sort->ktoi = sort->used + longerp;
933 #endif
934  sort->lBuffer = (WORD *)(sort->ktoi + longerp + 2);
935  sort->lTop = sort->lBuffer+sort->LargeSize;
936  sort->sBuffer = sort->lTop;
937  if ( sort->LargeSize == 0 ) { sort->lBuffer = 0; sort->lTop = 0; }
938  sort->sTop = sort->sBuffer + sort->SmallSize;
939  sort->sTop2 = sort->sBuffer + sort->SmallEsize;
940  sort->sHalf = sort->sBuffer + (LONG)((sort->SmallSize+sort->SmallEsize)>>1);
941  sort->file.PObuffer = (WORD *)(sort->sTop2);
942  sort->file.POstop = sort->file.PObuffer+IObuffersize;
943  sort->file.POsize = IObuffersize * sizeof(WORD);
944  sort->file.POfill = sort->file.POfull = sort->file.PObuffer;
945  sort->file.active = 0;
946  sort->file.handle = -1;
947  PUTZERO(sort->file.POposition);
948 #ifdef WITHPTHREADS
949  sort->file.pthreadslock = dummylock;
950 #endif
951 #ifdef WITHZLIB
952 /* sort->file.ziosize = IOsize; */
953  sort->file.ziosize = IObuffersize*sizeof(WORD);
954  sort->file.ziobuffer = 0;
955 #endif
956  if ( AM.S0 != 0 ) {
957  sort->file.name = (char *)(sort->file.PObuffer + IObuffersize);
958  AllocSortFileName(sort);
959  }
960  else sort->file.name = 0;
961  sort->cBuffer = 0;
962  sort->cBufferSize = 0;
963  sort->f = 0;
964  sort->PolyWise = 0;
965 
966  return(sort);
967 }
968 
969 /*
970  #] AllocSort :
971  #[ AllocSortFileName :
972 */
973 
974 VOID AllocSortFileName(SORTING *sort)
975 {
976  GETIDENTITY
977  char *s, *t;
978 /*
979  This is not the allocation before the tempfiles are determined.
980  Hence we can use the name in FG.fname2 and modify the tail
981 */
982  s = FG.fname2; t = sort->file.name;
983  while ( *s ) *t++ = *s++;
984 #ifdef WITHPTHREADS
985  t[-2] = 'F';
986  sprintf(t-1,"%d.%d",identity,AN.filenum);
987 #else
988  t[-2] = 'f';
989  sprintf(t-1,"%d",AN.filenum);
990 #endif
991  AN.filenum++;
992 }
993 
994 /*
995  #] AllocSortFileName :
996  #[ AllocFileHandle :
997 */
998 
999 FILEHANDLE *AllocFileHandle(WORD par,char *name)
1000 {
1001  GETIDENTITY
1002  LONG allocation, Ssize;
1003  FILEHANDLE *fh;
1004  int i = 0;
1005  char *s, *t;
1006 
1007  s = FG.fname2; i = 0;
1008  while ( *s ) { s++; i++; }
1009  if ( par == 0 ) { i += 16; Ssize = AM.SIOsize; }
1010  else { s = name; while ( *s ) { i++; s++; } i+= 2; Ssize = AM.SpectatorSize; }
1011 
1012  allocation = sizeof(FILEHANDLE) + (Ssize+1)*sizeof(WORD) + i*sizeof(char);
1013  fh = (FILEHANDLE *)Malloc1(allocation,"FileHandle");
1014 
1015  fh->PObuffer = (WORD *)(fh+1);
1016  fh->POstop = fh->PObuffer+Ssize;
1017  fh->POsize = Ssize * sizeof(WORD);
1018  fh->active = 0;
1019  fh->handle = -1;
1020  PUTZERO(fh->POposition);
1021 #ifdef WITHPTHREADS
1022  fh->pthreadslock = dummylock;
1023 #endif
1024  if ( par == 0 ) { /* sort file */
1025  if ( AM.S0 != 0 ) {
1026  fh->name = (char *)(fh->POstop + 1);
1027  s = FG.fname2; t = fh->name;
1028  while ( *s ) *t++ = *s++;
1029 #ifdef WITHPTHREADS
1030  t[-2] = 'F';
1031  sprintf(t-1,"%d-%d",identity,AN.filenum);
1032 #else
1033  t[-2] = 'f';
1034  sprintf(t-1,"%d",AN.filenum);
1035 #endif
1036  AN.filenum++;
1037  }
1038  else fh->name = 0;
1039  }
1040  else { /* Spectator file */
1041  fh->name = (char *)(fh->POstop + 1);
1042  s = FG.fname; t = fh->name;
1043  for ( i = 0; i < FG.fnamebase; i++ ) *t++ = *s++;
1044  s = name;
1045  while ( *s ) *t++ = *s++;
1046  *t = 0;
1047  }
1048  fh->POfill = fh->POfull = fh->PObuffer;
1049  return(fh);
1050 }
1051 
1052 /*
1053  #] AllocFileHandle :
1054  #[ DeAllocFileHandle :
1055 
1056  Made to repair deallocation of AN.filenum. 21-sep-2000
1057 */
1058 
1059 void DeAllocFileHandle(FILEHANDLE *fh)
1060 {
1061  GETIDENTITY
1062  if ( fh->handle >= 0 ) {
1063  CloseFile(fh->handle);
1064  fh->handle = -1;
1065  remove(fh->name);
1066  }
1067  AN.filenum--; /* free namespace. was forgotten in first reading */
1068  M_free(fh,"Temporary FileHandle");
1069 }
1070 
1071 /*
1072  #] DeAllocFileHandle :
1073  #[ MakeSetupAllocs :
1074 */
1075 
1076 int MakeSetupAllocs()
1077 {
1078  if ( RecalcSetups() || AllocSetups() ) return(1);
1079  else return(0);
1080 }
1081 
1082 /*
1083  #] MakeSetupAllocs :
1084  #[ TryFileSetups :
1085 
1086  Routine looks in the input file for a start of the type
1087  [#-]
1088  #: setupparameter value
1089  It keeps looking until the first line that does not start with
1090  #-, #+ or #:
1091  Then it rewinds the input.
1092 */
1093 
1094 #define SETBUFSIZE 257
1095 
1096 int TryFileSetups()
1097 {
1098  LONG oldstreamposition;
1099  int oldstream;
1100  int error = 0, eqnum;
1101  int oldNoShowInput = AC.NoShowInput;
1102  UBYTE buff[SETBUFSIZE+1], *s, *t, *u, *settop, c;
1103  LONG linenum, prevline;
1104 
1105  if ( AC.CurrentStream == 0 ) return(error);
1106  oldstream = AC.CurrentStream - AC.Streams;
1107  oldstreamposition = GetStreamPosition(AC.CurrentStream);
1108  linenum = AC.CurrentStream->linenumber;
1109  prevline = AC.CurrentStream->prevline;
1110  eqnum = AC.CurrentStream->eqnum;
1111  AC.NoShowInput = 1;
1112  settop = buff + SETBUFSIZE;
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  return(error);
1170 eoi:
1171  MesPrint("Input file without a program.");
1172  return(-1);
1173 }
1174 
1175 /*
1176  #] TryFileSetups :
1177  #[ TryEnvironment :
1178 */
1179 
1180 int TryEnvironment()
1181 {
1182  char *s, *t, *u, varname[100];
1183  int i,imax = sizeof(setupparameters)/sizeof(SETUPPARAMETERS);
1184  int error = 0;
1185  varname[0] = 'F'; varname[1] = 'O'; varname[2] = 'R'; varname[3] = 'M';
1186  varname[4] = '_'; varname[5] = 0;
1187  for ( i = 0; i < imax; i++ ) {
1188  t = s = (char *)(setupparameters[i].parameter);
1189  u = varname+5;
1190  while ( *s ) { *u++ = (char)(toupper((unsigned char)*s)); s++; }
1191  *u = 0;
1192  s = (char *)(getenv(varname));
1193  if ( s ) {
1194  error += ProcessOption((UBYTE *)t,(UBYTE *)s,2);
1195  }
1196  }
1197  return(error);
1198 }
1199 
1200 /*
1201  #] TryEnvironment :
1202  #] Setups :
1203 */
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