Parameters.cc 20.7 KB
Newer Older
1
2
3
4
5
#include <fstream>
#include <sstream>
#include <algorithm>
#include <stdarg.h>
#include <time.h>
Thomas Witkowski's avatar
Thomas Witkowski committed
6
#include <cstring>
7
8
#include <sys/types.h>
#include <sys/stat.h>
9
10

#ifndef WIN32
11
#include <unistd.h>
12
13
#endif

Thomas Witkowski's avatar
Thomas Witkowski committed
14
15
#include "Parameters.h"
#include "Serializer.h"
16
17
18
19

namespace AMDiS {

  const char Parameters::comment='%';
20
  const std::string Parameters::separators=",; ";
21
22
23
24
25
26
  Parameters* Parameters::singlett = NULL;
  const char* Parameters::param_call_fct = NULL;
  const char* Parameters::param_call_file = NULL;
  int Parameters::param_call_line = 0;


27
  int Parameters::getGlobalParameter(int info, const std::string& key, 
28
29
				     const char *format, ...)
  {
30
31
    FUNCNAME("Parameters::getGlobalParameter()");

32
    std::vector<struct Parameters::param>::iterator i;
33
    param tParam(key);
34
    const char* funcName2 = param_call_fct ? param_call_fct : funcName;
35
    va_list arg;
36
37
38

    Parameters::initIntern();

39
40
    if (Parameters::singlett->paramInfo) {
      if (Parameters::singlett->paramInfo > 1)
41
	info = max(info, Parameters::singlett->paramInfo - 1);
42
    } else {
43
      info = 0;
44
    }
45

46
    if (0 == Parameters::singlett->allParam.size()) {
Thomas Witkowski's avatar
Thomas Witkowski committed
47
      if (0 == Parameters::singlett->filename.size()) {
Thomas Witkowski's avatar
Thomas Witkowski committed
48
	INFO(info, 1)("no parameters defined\n");
Thomas Witkowski's avatar
Thomas Witkowski committed
49
	return 0;
50
51
      } else {
	Parameters::singlett->read(Parameters::singlett->filename,key);
52
      }
53
    }
54

55
56
    i = std::find(Parameters::singlett->allParam.begin(),
		  Parameters::singlett->allParam.end(), tParam);
57

58
59
    if (i == Parameters::singlett->allParam.end()) {
      if (funcName != funcName2) {
Thomas Witkowski's avatar
Thomas Witkowski committed
60
61
	INFO(info, 1)("initialization of parameter `%s'\n", key.data());
	INFO(info, 1)("fails on line %d of file %s\n", param_call_line,
62
63
		     param_call_file);
      } else {
Thomas Witkowski's avatar
Thomas Witkowski committed
64
	INFO(info, 1)("initialization of parameter `%s' fails\n", key.data());
65
      }
66
   
Thomas Witkowski's avatar
Thomas Witkowski committed
67
      return 0;
68
    }
69
70

    va_start(arg, format);
Thomas Witkowski's avatar
Thomas Witkowski committed
71
    int count = 0;
72
  
Thomas Witkowski's avatar
Thomas Witkowski committed
73
    INFO(info, 2)("parameter `%s' initialized with: ", key.data());
74

Thomas Witkowski's avatar
Thomas Witkowski committed
75
    std::string s = (*i).parameters;
76
 
Thomas Witkowski's avatar
Thomas Witkowski committed
77
    for (const char *p = format; *p; p++) {
78
79
      if (*p != '%')  
	continue;
80

Thomas Witkowski's avatar
Thomas Witkowski committed
81
      const char *word = Parameters::singlett->getNextWord(&s);
82
      if (!*word) {
Thomas Witkowski's avatar
Thomas Witkowski committed
83
	PRINT_INFO(info, 2)("\n");
Thomas Witkowski's avatar
Thomas Witkowski committed
84
85
86
87
88
89
90
	if (0 < (*i).funcName.size()) {
	  INFO(info, 4)("parameter initialized by %s()\n", (*i).funcName.data());
	  INFO(info, 4)("on line %d of file \"%s\"\n", 
			(*i).lineNo, (*i).filename.data());
	} else if (0 < (*i).filename.size()) {
	  INFO(info, 4)("parameter initialized on line %2d of init file \"%s\"\n",
			(*i).lineNo, (*i).filename.data());
91
	} else {
Thomas Witkowski's avatar
Thomas Witkowski committed
92
	  INFO(info, 4)("location of initialization unknown\n");
93
94
	}
	va_end(arg);
Thomas Witkowski's avatar
Thomas Witkowski committed
95
	return count;
96
      }
97
98
99
100
      count++;

      switch(*++p) {
      case 'S':
Thomas Witkowski's avatar
Thomas Witkowski committed
101
102
103
104
105
	{
	  char *Sval = va_arg(arg, char *);
	  *Sval = static_cast<char>(atoi(word));
	  INFO(info, 2)("%d ", *Sval);
	}
106
107
	break;
      case 'U':
Thomas Witkowski's avatar
Thomas Witkowski committed
108
109
110
111
112
	{
	  unsigned char *Uval = va_arg(arg, unsigned char *);
	  *Uval = static_cast<unsigned char>(atoi(word));
	  INFO(info, 2)("%d ", *Uval);
	}
113
114
	break;
      case 'c':
Thomas Witkowski's avatar
Thomas Witkowski committed
115
116
117
118
119
	{
	  char *cval = va_arg(arg, char *); 
	  *cval = *word;
	  INFO(info, 2)("%c ", *cval);
	}
120
121
	break;
      case 's':
Thomas Witkowski's avatar
Thomas Witkowski committed
122
123
124
125
126
	{
	  char *sval = va_arg(arg, char *);
	  strcpy(sval, word);
	  INFO(info, 2)("%s ", sval);
	}
127
128
	break;
      case 'd':
Thomas Witkowski's avatar
Thomas Witkowski committed
129
130
131
132
133
	{
	  int *ival = va_arg(arg, int *);
	  *ival = atoi(word);
	  INFO(info, 2)("%d ", *ival);
	}
134
135
136
137
	break;
      case 'e':
      case 'f':
      case 'g':
Thomas Witkowski's avatar
Thomas Witkowski committed
138
139
140
141
142
	{
	  double *rval = va_arg(arg, double *);
	  *rval = atof(word);
	  INFO(info, 2)("%g ", *rval);
	}
143
	break;
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
      case 'v':	
	{
	  WorldVector<double> *vecVal = va_arg(arg, WorldVector<double> *);
	  std::string sstr = std::string(word);
	  int ind = 0;
	  int found = sstr.find_first_of(",; ");
	  std::string seperator;
	  seperator = sstr[found];
	  
	  while (found != static_cast<int>(std::string::npos) && 
		 ind < static_cast<int>(vecVal->size())) {
	    if (found > 0) {
	      (*vecVal)[ind] = atof(sstr.substr(0, found).c_str());
	      ind++;
	    }
	    sstr = sstr.substr(found + 1);
	    found = sstr.find_first_of(seperator);
	  }
	  if (sstr.length() > 0 && ind < static_cast<int>(vecVal->size()))
	    (*vecVal)[ind] = atof(sstr.c_str());	
	}
	break;
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
      case 'E': // list of double values, example parameter: {a,b,c,d,e}
      case 'F':
      case 'G':
	{
	  std::vector<double> *vecVal = va_arg(arg, std::vector<double> *);
	  std::string sstr = std::string(word);

       std::string brackets1 = "[{(", brackets2 = "]})";
	  int bracketIdx1 = sstr.find_first_of(brackets1);
       int bracket = brackets1.find_first_of(sstr[bracketIdx1]);
       int bracketIdx2 = sstr.find_first_of(brackets2[bracket]);
       TEST_EXIT(bracket>=0 && bracketIdx1>=0 && bracketIdx2>=0 && bracketIdx1<bracketIdx2)
		("no enclosing brackets found in '%s' \n",key.data());
       sstr = sstr.substr(bracketIdx1+1, bracketIdx2-bracketIdx1);

	  int found = sstr.find_first_of(separators);
	  std::string seperator;
	  seperator = sstr[found];
	  
	  while (found != static_cast<int>(std::string::npos)) {
	    if (found > 0) {
	      vecVal->push_back(atof(sstr.substr(0, found).c_str()));
	    }
	    sstr = sstr.substr(found + 1);
	    found = sstr.find_first_of(seperator);
	  }
	  if (sstr.length() > 0)
	    vecVal->push_back(atof(sstr.c_str()));
194
195
	  if (vecVal->size() == 0)
	    WARNING("no values in parameter vector!\n");
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
	}
	break;
      case 'D': // list of int values, example parameter: {a,b,c,d,e}
	{
	  std::vector<int> *vecVal = va_arg(arg, std::vector<int> *);
	  std::string sstr = std::string(word);

       std::string brackets1 = "[{(", brackets2 = "]})";
	  int bracketIdx1 = sstr.find_first_of(brackets1);
       int bracket = brackets1.find_first_of(sstr[bracketIdx1]);
       int bracketIdx2 = sstr.find_first_of(brackets2[bracket]);
       TEST_EXIT(bracket>=0 && bracketIdx1>=0 && bracketIdx2>=0 && bracketIdx1<bracketIdx2)
		("no enclosing brackets found in '%s' \n",key.data());
       sstr = sstr.substr(bracketIdx1+1, bracketIdx2-bracketIdx1);

	  int found = sstr.find_first_of(separators);
	  std::string seperator;
	  seperator = sstr[found];
	  
	  while (found != static_cast<int>(std::string::npos)) {
	    if (found > 0) {
	      vecVal->push_back(atoi(sstr.substr(0, found).c_str()));
	    }
	    sstr = sstr.substr(found + 1);
	    found = sstr.find_first_of(seperator);
	  }
	  if (sstr.length() > 0)
	    vecVal->push_back(atoi(sstr.c_str()));
224
       if (vecVal->size() == 0)
225
226
227
         WARNING("no values in parameter vector!\n");
	}
	break;
228
229
230
      case '*':
	break;
      default: 
Thomas Witkowski's avatar
Thomas Witkowski committed
231
232
	INFO(info, 2)("\n");
	INFO(info, 2)
233
234
	  ("unknow format specifier `%%%c', skipping initialization of %s\n",
	   *p, key.data());
235
      }
236
237
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
238
    INFO(info, 2)("\n");
239
240

    if ((*i).funcName.size() > 0) {
Thomas Witkowski's avatar
Thomas Witkowski committed
241
242
      INFO(info, 4)("parameter initialized by %s()\n", (*i).funcName.data());
      INFO(info, 4)("on line %d of file \"%s\"\n", (*i).lineNo,
243
244
		   (*i).filename.data());
    } else if ((*i).filename.size() > 0) {
Thomas Witkowski's avatar
Thomas Witkowski committed
245
      INFO(info, 4)
246
247
248
	("parameter initialized on line %2d of init file \"%s\"\n",
	 (*i).lineNo, (*i).filename.data());
    } else {
Thomas Witkowski's avatar
Thomas Witkowski committed
249
      INFO(info, 4)("location of initialization unknown\n");
250
251
    }
    
252
    va_end(arg);
253

254
    return count;
255
256
  }

257

Thomas Witkowski's avatar
Thomas Witkowski committed
258
259
  int Parameters::getGlobalParameter(int flag, const std::string& key, 
				     std::string* param)
260
261
262
263
264
265
266
267
268
  {
    static char tempParam[255];
    TEST_EXIT(param)("no parameter\n");
    strcpy(tempParam, param->c_str());
    int result = getGlobalParameter(flag, key, "%s", tempParam);
    param->assign(tempParam);
    return result;
  }

269

270
271
  void Parameters::read(const std::string& aFilename, 
			const std::string& maxKey)
272
273
274
  {
    FUNCNAME("Parameters::read()");

275
276
    char line[256];
    int nLine = 0;
277
278
    std::string key, parameter;
    std::string actfile;
279
280
281
282

    if (aFilename.size() == 0)
      return;

283
    singlett->inputFile.open(aFilename.c_str(), std::ios::in);
284
285
286
287
288
    if (!inputFile.is_open()) {
      ERROR("init-file can't be opened\n");
      return;
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
289
    INFO(paramInfo, 2)("reading from file %s\n", aFilename.data());
290
291
    actfile = getActFile(aFilename);
    
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
    while (!inputFile.eof()) {
      inputFile.getline(line, 255);
      nLine++;

      key = getKey(line, nLine, aFilename);
      
      if (key == "")
	continue;

      parameter = getPar(key, line, &nLine, aFilename);
      if (parameter == "")  
	continue;
      
      addParam(key, parameter, actfile, nLine, funcName);
    }

    singlett->inputFile.close();
  }

311

312
  const std::string& Parameters::getActFile(const std::string& aFilename)
313
  {
314
315
    FUNCNAME("Parameters::getActFile()");

316
    std::list< std::string >::iterator i;
317
    for (i = filenames.begin(); i != filenames.end(); i++)
318
319
      if (aFilename==*i) 
	break;
320
  
321
    if (i != filenames.end()) {
322
      return(const_cast<const std::string&>(*i));
323
324
    } else {
      filenames.push_back(aFilename);
325
      return(const_cast<const std::string&>(aFilename));
326
    }
327
328
  }

329

330
331
332
333
334
335
336
  void Parameters::swap(int i, int j)
  {
    param tmp(allParam[i]);
    allParam[i] = allParam[j];
    allParam[j] = tmp;
  }

337

338
339
  void Parameters::qsort(int left, int right)
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
340
341
    if (left >= right) 
      return;
342

343
344
345
    swap(left, (left + right) / 2);
    int last = left;
    for (int i = left + 1; i <= right; i++)
346
347
348
349
      if (allParam[i].key.compare(allParam[left].key) < 0)
	swap(++last, i);

    swap(left, last);
350
351
    qsort(left, last - 1);
    qsort(last + 1, right);
352
353
354
  }


355
356
  const std::string Parameters::getKey(const std::string& s, int nLine, 
					 const std::string& aFilename)
357
  {
358
359
    FUNCNAME("Parameters::getKey()");

Thomas Witkowski's avatar
Thomas Witkowski committed
360
    std::string fn, key = "";
361
362
    char c;
    int i, epos;
Thomas Witkowski's avatar
Thomas Witkowski committed
363
364
    std::string h = " \t\r\f";
    int pos = s.find_first_not_of(" \t\f\r"); //skip Blank
365
  
366
    if (pos < 0)
367
368
      return key;

Thomas Witkowski's avatar
Thomas Witkowski committed
369
    if (s[pos] == comment || s[pos] == '\0' || s[pos] == '\n')
370
371
      return(key);

372
373
374
375
376
377
378
    if (s[pos] == '#') {
      if (static_cast<int>(s.find("#include")) == pos) {
	/****************************************************************************/
	/*  another init file has to be included                                    */
	/****************************************************************************/

	pos += strlen("#include");
Thomas Witkowski's avatar
Thomas Witkowski committed
379
	pos = s.find_first_not_of(" \t\f\r");
380
381
382
383
384
385

	i = 0;
	switch (c = s[pos++]) {
	case '<':
	  c = '>';
	case '\"':
Thomas Witkowski's avatar
Thomas Witkowski committed
386
387
	  h += c;
	  epos = s.find_first_not_of(h, pos);
388
	  fn = s.substr(pos,epos-1);
389
       
390
391
392
	  if (s[epos] != c) {
	    ERROR("aFilename of include not terminated by %c\n", c);
	    ERROR("skipping line %d of file %s\n", nLine, aFilename.c_str());
393
394
	    return("");
	  }
395
396
397
398
399
400
401
402
403
404
405
406
	  break;
	default:
	  ERROR("no aFilename of include file found\n");
	  ERROR("skipping line %d of file %s\n", nLine, aFilename.c_str());
	  return("");
	}

	read(fn);
	return("");
      } else {
	ERROR("# must not be the first character on a line; except #include\n");
	return("");
407
      }
408
    }
409
410
411
412
413
414

    /****************************************************************************/
    /*  now get the key                                                         */
    /****************************************************************************/
    i = 0;
    epos=s.find_first_of(":#",pos+1);
415
416
417
418
419
    if (s[epos] == '#') {
      ERROR("key must not contain '%c'.\n", '#');
      ERROR("Skipping line %d of file %s\n", nLine, aFilename.c_str());
      return("");
    }
420
  
421
    key = s.substr(pos,epos);
422

423
424
425
426
427
428
429
430
431
432
433
    if (s[epos] != ':') {
      ERROR("key was not terminated by ':'.\n");
      ERROR("Skipping line %d of file %s\n", nLine, aFilename.c_str());
      return("");
    }
    
    if (key.size() == 0) {
      ERROR("use of ':' without key.\n");
      ERROR("Skipping line %d of file %s\n", nLine, aFilename.c_str());
      return("");
    }
434

Thomas Witkowski's avatar
Thomas Witkowski committed
435
    return key;
436
437
  }

438
  const std::string Parameters::getPar(const std::string& key, 
Thomas Witkowski's avatar
Thomas Witkowski committed
439
440
				       const std::string& si, int *nl, 
				       const std::string& fn)
441
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
442
443
444
    FUNCNAME("Parameters::getPar()");

    int ol = *nl;
445
    std::string inp;
Thomas Witkowski's avatar
Thomas Witkowski committed
446
    std::string s = si;
447
    std::string parameter="";
448

Thomas Witkowski's avatar
Thomas Witkowski committed
449
450
    int pos = s.find(':');
    pos = s.find_first_not_of(" \r\f\t",pos+1);
451
  
Thomas Witkowski's avatar
Thomas Witkowski committed
452
453
454
455
456
457
458
459
460
461
462
463
464
465
    int i = pos;
    while(i < static_cast<int>(s.length()) && 
	  s[i] != '#' && s[i] != '%' && s[i] != '\n') {
      if (s[i] == '\\'  && i+1 < static_cast<int>(s.length()) &&  s[i + 1] == '\n') {
	s = s.substr(0, i);
	(*nl)++;
	inputFile >> inp;
	s+=inp;
	if (inputFile.eof()) {
	  ERROR("EOF reached while reading parameters of key %s\n", key.c_str());
	  if (ol == *nl-1) 
	    ERROR("Skipping line %d of file %s\n", *nl, fn.c_str());
	  else     
	    ERROR("Skipping lines %d-%d of file %s\n", ol, *nl, fn.c_str());
466
	    
Thomas Witkowski's avatar
Thomas Witkowski committed
467
	  return("");
468
	}
Thomas Witkowski's avatar
Thomas Witkowski committed
469
470
471
472
473
474
475
476
477
478
      } else {
	if (isBlankChar(static_cast<char>(s[i]))) {
	  parameter+= ' ';
	  i=pos=s.find_first_not_of(" \r\t\f", i);
	  if (i == static_cast<int>(std::string::npos)) {
	    i = parameter.length()-1;
	    break;
	  }
	} else {
	  parameter += s.substr(i++,1);
479
	}
Thomas Witkowski's avatar
Thomas Witkowski committed
480
      }
481
482
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
483
484
    i = parameter.find_last_not_of(" \r\t\f");
    parameter.resize(i + 1);
485

Thomas Witkowski's avatar
Thomas Witkowski committed
486
487
488
489
490
491
    if (i == 0 && isBlankChar(parameter[0])) {
      ERROR("no parameter of key %s.\n", key.c_str());
      if (ol == *nl) 
	ERROR("Skipping line %d of file %s\n", *nl, fn.c_str());
      else   
	ERROR("Skipping lines %d-%d of file %s\n", ol, *nl, fn.c_str());
492

Thomas Witkowski's avatar
Thomas Witkowski committed
493
494
      return("");
    }
495

496
    return parameter;
497
498
  }

499
500
501
  void Parameters::addParam(const std::string& key, 
			    const std::string& parameter,
			    const std::string& actfile, 
502
			    int  nLine, 
503
			    const std::string& fname)
504
505
  {
    FUNCNAME("Parameters::addParam()");
Thomas Witkowski's avatar
Thomas Witkowski committed
506

507
508
509
510
511
512
513
    unsigned size_k, size_p;
    int scmp = 0;
    param newPar;

    size_k = key.size()+1;
    size_p = parameter.size()+1;

514
    std::vector<param>::iterator it;
Thomas Witkowski's avatar
Thomas Witkowski committed
515
516
517
    for (it = allParam.begin(); it != allParam.end(); it++)
      if ((scmp = key.compare((*it).key)) >=0)  
	break;  
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542

    if (it != allParam.end() && scmp == 0) {
      /****************************************************************************/
      /*  key does already exist: save new parameters                             */
      /****************************************************************************/
      (*it).parameters = parameter;
      (*it).filename = actfile;
      (*it).funcName = fname;
      (*it).lineNo = nLine;
      
      return;
    }

    newPar.key = key;
    newPar.parameters = parameter;
    newPar.filename = actfile;
    newPar.funcName.assign(fname);
    newPar.lineNo = nLine;
    allParam.insert(it, newPar);
  }



  void Parameters::initIntern()
  {
543
544
    if (singlett == NULL)
      singlett = new Parameters;
545
546
547
548
549
550
551
552
  }

  void Parameters::printParameters()
  {
    FUNCNAME("Parameters::printParameters()");

    initIntern();

553
    std::vector<param>::iterator it;
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
    for (it = singlett->allParam.begin(); it != singlett->allParam.end(); it++) {
      MSG("%s:  %s\n", (*it).key.data(), (*it).parameters.data());
      if (0 < (*it).funcName.size()) {
	MSG("initialized by %s() on line %3d of file \"%s\"\n", 
	    (*it).funcName.data(), (*it).lineNo, (*it).filename.data());
      }	else if (0 < (*it).filename.size()) {
	MSG("initialized on line %2d of file \"%s\"\n",
	    (*it).lineNo, (*it).filename.data());
      } else {
	MSG("can not locate initialization location\n");
      }
    }
  }


569
  void Parameters::init(int p, std::string fn, const char *flags)
570
571
572
  {
    FUNCNAME("Parameters::init()");
  
573
574
575
576
577
578
579
580
    std::ostringstream tmp_file;
    std::ofstream cpp_flags;
    std::ofstream call_cpp;
    std::string file;
    std::ofstream outFile;
    std::string lfn = fn;
    std::string::size_type fpos= lfn.find('/');

Thomas Witkowski's avatar
Thomas Witkowski committed
581
    if (fpos == std::string::npos)
582
      fpos = 0;
Thomas Witkowski's avatar
Thomas Witkowski committed
583
    else
584
      ++fpos;
Thomas Witkowski's avatar
Thomas Witkowski committed
585
    
586
587
    lfn.insert(fpos,".#");

588
589
590
#ifdef WIN32
    int val(0);
#else
591
592
    struct stat buf;

Thomas Witkowski's avatar
Thomas Witkowski committed
593
594
595
    int val = lstat(lfn.c_str(), &buf);
    if (val == 0)
      if (buf.st_mode&S_IFLNK && buf.st_size > 0)
596
597
	ERROR_EXIT("Unsaved version of init file exists\n");

598
#endif
599
600
    initIntern();
    if (0 == fn.size()) {
Thomas Witkowski's avatar
Thomas Witkowski committed
601
      Global::init();
602
603
604
605
606
607
      return;
    }

    if (NULL == flags) {
      singlett->read(fn);
    } else {
608
      singlett->inputFile.open(fn.data(), std::ios::in);
Thomas Witkowski's avatar
Thomas Witkowski committed
609
      if (!(singlett->inputFile.rdstate())) {
610
611
612
613
	ERROR("can not read from file %s\n", fn.data());
	return;
      }
      singlett->inputFile.close();
Thomas Witkowski's avatar
Thomas Witkowski committed
614

Thomas Witkowski's avatar
Thomas Witkowski committed
615
616
617
618
      ERROR("no cpp available; reading file %s without help of cpp\n", fn.c_str());
      init(p, fn);
      
      return;
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
    } 

    val = 10; // default for level of information
    getGlobalParameter(0, "level of information", "%d", &val);
    singlett->msgInfo=val;

    val = 1; // default for WAIT
    getGlobalParameter(0, "WAIT", "%d", &val);
    singlett->msgWait=val;

    val = 1; // default for parameter information
    getGlobalParameter(0, "parameter information", "%d", &val);
    singlett->paramInfo = val;

    if (!singlett->msgInfo)  
      singlett->paramInfo = 0;
  
Thomas Witkowski's avatar
Thomas Witkowski committed
636
    if (p && singlett->msgInfo) 
637
638
      printParameters();
  
Thomas Witkowski's avatar
Thomas Witkowski committed
639
    Global::init();
640
641
642
643
644
645
  } 

  void Parameters::readArgv(int argc, char **argv)
  {
    FUNCNAME("Parameters::readArgv()");

646
647
    for (int i = 0; i < argc; i++)
      if (strcmp("-rs", argv[i]) == 0)
648
649
650
651
652
653
654
655
656
657
	ADD_PARAMETER(0, "argv->rs", argv[i + 1]);
  }

  int Parameters::initFuncName(const char * call_fct, const char * call_file, 
			       int call_line)
  {
    param_call_fct = call_fct;
    param_call_file = call_file;
    param_call_line = call_line;

658
    return 1;
659
660
  }

661
  int Parameters::binSearch(const std::string& key, int n_keys)
662
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
663
664
    int left = 0;
    int right = n_keys - 1;
665
666
  
    while (left <= right) {
Thomas Witkowski's avatar
Thomas Witkowski committed
667
668
669
      int mid = (left + right) / 2;
      int cond = allParam[mid].key.compare(key);
      if (cond  < 0) {
670
671
672
673
	left = mid + 1;
      } else if (cond > 0) {
	right = mid - 1;
      }	else {
Thomas Witkowski's avatar
Thomas Witkowski committed
674
	return mid;
675
676
677
      }
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
678
    return -1;
679
680
681
682
  }


 
683
684
  void Parameters::addGlobalParameter(int p, const std::string key, 
				      const std::string par, const char *fname, 
685
686
687
688
689
690
				      const char *file, int line)
  {
    FUNCNAME("Parameters::addGlobalParameter()");

    initIntern();

Thomas Witkowski's avatar
Thomas Witkowski committed
691
    if (key.size() == 0 || par.size() == 0)
692
693
      return;

694
695
    std::string file_str = "";
    if (file != NULL)
696
      file_str = std::string(file);
697
698
    std::string fname_str = "";
    if (fname != NULL)
699
700
      fname_str = std::string(fname);
    singlett->addParam(key, par, file_str, line, fname_str);
701

Thomas Witkowski's avatar
Thomas Witkowski committed
702
    int val = 10; // defualt for level of information
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
    getGlobalParameter(0, "level of information", "%d", &val);
    singlett->msgInfo = val;

    val = 1; // default for WAIT
    getGlobalParameter(0, "WAIT", "%d", &val);
    singlett->msgWait = val;

    val = 1; // default for parameter information
    getGlobalParameter(0, "parameter information", "%d", &val);
    singlett->paramInfo = val;

    if (!singlett->msgInfo)  
      singlett->paramInfo = 0;
  
    if (p && singlett->msgInfo) 
      printParameters();  
  }  



723
  const char *Parameters::getNextWord(std::string *s) const
724
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
725
    static char Val[512];
726
  
Thomas Witkowski's avatar
Thomas Witkowski committed
727
728
729
    int wb1 = s->find_first_not_of(" "); 
    if (wb1 == static_cast<int>(std::string::npos))
      return NULL;    
730

Thomas Witkowski's avatar
Thomas Witkowski committed
731
    int wb2 = s->find_first_of(" ");
Thomas Witkowski's avatar
Thomas Witkowski committed
732
    if (wb2 == static_cast<int>(std::string::npos))
733
      wb2 = s->length();
Thomas Witkowski's avatar
Thomas Witkowski committed
734
735
    
    s->copy(Val, wb2 - wb1, wb1);
736

Thomas Witkowski's avatar
Thomas Witkowski committed
737
    Val[wb2 - wb1] = '\0';
738

Thomas Witkowski's avatar
Thomas Witkowski committed
739
    return Val;
740
741
  }

742
  void Parameters::save(const std::string file, int info)
743
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
744
    std::ofstream fp;
745
    std::vector<param>::iterator it;
746
747
748

    initIntern();

749
    fp.open(file.data(), std::ios::out);
Thomas Witkowski's avatar
Thomas Witkowski committed
750
    if (0 != fp.rdstate())
751
752
753
      return;

    for (it = singlett->allParam.begin(); it !=singlett->allParam.end(); it++) {
754
      fp << (*it).key <<  ":  " << (*it).parameters << std::endl;
755
756
757
758

      if (info) {
	if (((*it).funcName.size()) > 0) {
	  fp << "%initialized by " << (*it).funcName << "() on line " <<
759
	    (*it).lineNo << " of file \"" << (*it).filename << "\"" << std::endl;
760
761
	} else if ((*it).filename.size() > 0) {
	  fp << "%initialized on line "<< (*it).lineNo << 
762
	    " of file \""<< (*it).filename << "\""<< std::endl;
763
764
765
766
767
768
	}
      }
    }
    fp.close();
  }

769
770
  void Parameters::clear() 
  {
771
772
    if (singlett != NULL)
      delete singlett;
773
774
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
  void Parameters::serialize(std::ostream &out)
  {
    SerUtil::serialize(out, paramInfo);
    SerUtil::serialize(out, msgInfo);
    SerUtil::serialize(out, msgWait);
    int size = static_cast<int>(allParam.size());
    SerUtil::serialize(out, size);
    for (int i = 0; i < size; i++)
      allParam[i].serialize(out);
  }

  void Parameters::deserialize(std::istream &in)
  {
    SerUtil::deserialize(in, paramInfo);
    SerUtil::deserialize(in, msgInfo);
    SerUtil::deserialize(in, msgWait);
    int size;
    SerUtil::deserialize(in, size);
    allParam.resize(size);
    for (int i = 0; i < size; i++)
      allParam[i].deserialize(in);
  }

  int Parameters::param::operator==(const param& aParam) const
  { 
800
801
802
    return key == aParam.key;
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
  void Parameters::param::serialize(std::ostream &out)
  {
    out << key << std::endl;
    out << parameters << std::endl;
    out << filename << std::endl;
    out << funcName << std::endl;
    SerUtil::serialize(out, lineNo);
  }
  
  void Parameters::param::deserialize(std::istream &in)
  {
    in >> key; in.get();
    in >> parameters; in.get();
    in >> filename; in.get();
    in >> funcName; in.get();
    SerUtil::deserialize(in, lineNo);
  }

821
}