Initfile.cc 4.17 KB
Newer Older
Praetorius, Simon's avatar
Praetorius, Simon committed
1 2 3 4 5 6 7 8
#include "Initfile.h"

#include <string>
#include <stdexcept>
#include <iostream>
#include <sstream>
using namespace std;

9 10
namespace AMDiS {

11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
  /// the small parser for the initfile. see description of read(Initfile&, istream&)
  struct Parser {
    Parser(const string& line) 
    {
      size_t pos = line.find(':');
      if (pos == string::npos)
	throw runtime_error("cannot find the delimiter ':' in line '" + line + "'");
      name = line.substr(0, pos);
      value = line.substr(pos + 1, line.length() - (pos + 1));

      // remove everything after the %
      pos = value.find('%');
      if (pos != string::npos)
	value = value.substr(0, pos);
    }
    string name;
    string value;
  };

  Initfile* Initfile::singlett= NULL;
  std::set<std::string> Initfile::fn_include_list;


  /// initialize singleton object an global parameters
  void Initfile::init(std::string in)
  {
    initIntern();
    singlett->clear();
    fn_include_list.clear();
    singlett->read(in);	
    singlett->getInternalParameters();
Praetorius, Simon's avatar
Praetorius, Simon committed
42
	
43 44 45 46 47 48 49 50 51 52 53 54 55 56
    // initialize global strcutures using parameters
    Global::init();
  }


  /// Fill an initfile from a file with filename fn
  void Initfile::read(std::string fn)
  {
    // read file if its not parsed already
    if (fn_include_list.find(fn) == fn_include_list.end()) {
      std::ifstream inputFile;
      inputFile.open(fn.c_str(), std::ios::in);
      if (!inputFile.is_open())
	throw runtime_error("init-file cannot be opened for reading");
Praetorius, Simon's avatar
Praetorius, Simon committed
57
		
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
      fn_include_list.insert(fn);
      read(inputFile);
    }
  }


  /// Fill an initfile from an input stream
  void Initfile::read(istream& in) 
  {
    unsigned line_length = 256;
    char swap[line_length];
    in.getline(swap, line_length);
    while (in.good()) {
      std::string whitespaces = " \t\r\f";
      std::string sw(swap);
      size_t pos0 = sw.find_first_not_of(whitespaces);
Praetorius, Simon's avatar
Praetorius, Simon committed
74
		
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
      if (pos0 != std::string::npos && sw[pos0] != '%' && sw[pos0] != '#' && sw[pos0] != 0) {
	// parse line and extract map: tag->value
	Parser parser(sw);
	operator[](parser.name) = parser.value;
      } else if (sw[pos0] == '#' && static_cast<size_t>(sw.find("#include")) == pos0) {
	// include file by '#include "filename"' or '#include <filename>'
	size_t pos = sw.find_first_not_of(whitespaces, std::string("#include").size() + 1);
	size_t epos = 0;
	std::string fn =  "";
	std::stringstream errorMsg;
	switch (char c= swap[pos++]) {
	case '<':
	  c= '>';
	case '\"':
	  whitespaces += c;
	  epos = sw.find_first_of(whitespaces, pos);
	  fn = sw.substr(pos, epos - pos);
Praetorius, Simon's avatar
Praetorius, Simon committed
92
			
93 94 95 96 97 98 99
	  if (sw[epos]!=c) {
	    errorMsg << "filename in #include not terminated by " << c;
	    throw std::runtime_error(errorMsg.str());
	  }
	  break;
	default:
	  throw std::runtime_error("no filename given for #include");
100
	}
101 102 103 104 105
	read(fn);
      }
      in.getline(swap, line_length);
    }
  }
106

107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124

  void Initfile::readArgv(int argc, char **argv)
  {
    for (int i = 0; i < argc; i++) {
      if (strcmp("-rs", argv[i]) == 0) {
	std::string input(argv[i + 1]);
	add("argv->rs", input, 0);
      }
    }
  }


  /// read standard values for output and information of parameter-values
  void Initfile::getInternalParameters() 
  {
    int val = 0;
    get("level of information", val, 0);
    msgInfo = val;
Praetorius, Simon's avatar
Praetorius, Simon committed
125
	
126 127 128
    val = 1;
    get("WAIT", val, 0);
    msgWait = val;
Praetorius, Simon's avatar
Praetorius, Simon committed
129
	
130 131 132
    val = 1;
    get("parameter information", val, 0);
    paramInfo = val;
Praetorius, Simon's avatar
Praetorius, Simon committed
133
	
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
    val = 0;
    get("break on missing tag", val, 0);
    breakOnMissingTag = val;

    if (msgInfo == 0)
      paramInfo = 0;
  }


  /// print all parameters to std::cout
  void Initfile::printParameters() 
  {
    initIntern();
    for (Initfile::iterator it = singlett->begin(); it != singlett->end(); it++)
      std::cout << (*it).first << " => " << (*it).second << std::endl;
  }


  /// Write data-map to initfile
  void Initfile::write(ostream& out)
  {
    for (Initfile::iterator it = begin() ; it!=end(); it++)
      out << (*it).first << ": " << (*it).second << std::endl;	
  }


  /// Write data-map to initfile
  void Initfile::write(std::string fn) 
  {
    std::ofstream outFile;
    outFile.open(fn.c_str(), std::ios::out);
    if (!outFile.is_open())
      throw runtime_error("init-file cannot be opened for writing");
Praetorius, Simon's avatar
Praetorius, Simon committed
167
	
168 169
    write(outFile);
  }
170 171

}