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