Commit 8698e7fe authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

Initfiles in AMDiS code style.

parent f025c9bb
......@@ -8,44 +8,48 @@ using namespace std;
namespace AMDiS {
/// the small parser for the initfile. see description of read(Initfile&, istream&)
struct Parser {
Parser(const string& line) {
size_t pos= line.find(':');
/// 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));
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);
}
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;
Initfile* Initfile::singlett= NULL;
std::set< std::string > Initfile::fn_include_list;
/// initialize singleton object an global parameters
void Initfile::init(std::string in) {
/// initialize singleton object an global parameters
void Initfile::init(std::string in)
{
initIntern();
singlett->clear();
fn_include_list.clear();
singlett->read(in);
singlett->getInternalParameters();
// 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()) {
/// 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())
......@@ -54,35 +58,37 @@ void Initfile::read(std::string fn) {
fn_include_list.insert(fn);
read(inputFile);
}
};
}
/// Fill an initfile from an input stream
void Initfile::read(istream& in) {
unsigned line_length= 256;
/// 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 whitespaces = " \t\r\f";
std::string sw(swap);
size_t pos0= sw.find_first_not_of(whitespaces);
size_t pos0 = sw.find_first_not_of(whitespaces);
if (pos0!=std::string::npos && sw[pos0]!='%' && sw[pos0]!='#' && sw[pos0]!=0) {
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) {
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= "";
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);
whitespaces += c;
epos = sw.find_first_of(whitespaces, pos);
fn = sw.substr(pos, epos - pos);
if (sw[epos]!=c) {
errorMsg << "filename in #include not terminated by " << c;
......@@ -96,65 +102,70 @@ void Initfile::read(istream& in) {
}
in.getline(swap, line_length);
}
};
}
void Initfile::readArgv(int argc, char **argv)
{
for (int i= 0; i<argc; ++i) {
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]);
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;
/// read standard values for output and information of parameter-values
void Initfile::getInternalParameters()
{
int val = 0;
get("level of information", val, 0);
msgInfo= val;
msgInfo = val;
val= 1;
val = 1;
get("WAIT", val, 0);
msgWait= val;
msgWait = val;
val= 1;
val = 1;
get("parameter information", val, 0);
paramInfo= val;
paramInfo = val;
val= 0;
val = 0;
get("break on missing tag", val, 0);
breakOnMissingTag= val;
breakOnMissingTag = val;
if (msgInfo == 0)
paramInfo = 0;
}
if (msgInfo==0)
paramInfo= 0;
};
/// print all parameters to std::cout
void Initfile::printParameters() {
/// print all parameters to std::cout
void Initfile::printParameters()
{
initIntern();
Initfile::iterator it;
for (it= singlett->begin(); it!=singlett->end(); it++)
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) {
Initfile::iterator it;
for (it= begin() ; it!=end(); it++)
/// 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) {
/// 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");
write(outFile);
};
}
}
......@@ -28,51 +28,109 @@ namespace AMDiS {
/// Exceptions
struct WrongVectorSize : std::runtime_error {
WrongVectorSize(std::string m):std::runtime_error(m) {}
WrongVectorSize(std::string m)
: std::runtime_error(m)
{}
};
struct NoDelim : std::runtime_error {
NoDelim(std::string m):std::runtime_error(m) {}
NoDelim(std::string m)
: std::runtime_error(m)
{}
};
struct WrongVectorFormat : std::runtime_error {
WrongVectorFormat(std::string m):std::runtime_error(m) {}
WrongVectorFormat(std::string m)
: std::runtime_error(m)
{}
};
template< typename T >
template<typename T>
struct WrongValueFormat : std::runtime_error {
static std::string name(int ) { return "int"; }
static std::string name(bool ) { return "bool"; }
static std::string name(double ) { return "double"; }
static std::string name(unsigned int ) { return "unsigned int"; }
template< typename G >
static std::string name(G ) { return std::string(typeid(G).name()); }
WrongValueFormat(std::string value): std::runtime_error(std::string("cannot convert '") + value + std::string("' into <")+ name(T())+">" )
static std::string name(int)
{
return "int";
}
static std::string name(bool)
{
return "bool";
}
static std::string name(double)
{
return "double";
}
static std::string name(unsigned int)
{
return "unsigned int";
}
template<typename G>
static std::string name(G)
{
return std::string(typeid(G).name());
}
WrongValueFormat(std::string value)
: std::runtime_error(std::string("cannot convert '") +
value + std::string("' into <") + name(T()) + ">")
{}
};
template< typename T >
template<typename T>
struct BadArithmeticExpression : std::runtime_error {
static std::string name(int ) { return "int"; }
static std::string name(bool ) { return "bool"; }
static std::string name(double ) { return "double"; }
static std::string name(unsigned int ) { return "unsigned int"; }
template< typename G >
static std::string name(G ) { return std::string(typeid(G).name()); }
BadArithmeticExpression(std::string m, std::string value): std::runtime_error(std::string("cannot evaluate expression '") + value + std::string("' into <")+ name(T())+">\nParser message: '" + m + "'" )
static std::string name(int)
{
return "int";
}
static std::string name(bool)
{
return "bool";
}
static std::string name(double)
{
return "double";
}
static std::string name(unsigned int)
{
return "unsigned int";
}
template<typename G>
static std::string name(G)
{
return std::string(typeid(G).name());
}
BadArithmeticExpression(std::string m, std::string value)
: std::runtime_error(std::string("cannot evaluate expression '") +
value + std::string("' into <") + name(T()) +
">\nParser message: '" + m + "'")
{}
};
/// trim std::string
inline std::string trim(const std::string& oldStr) {
inline std::string trim(const std::string& oldStr)
{
std::string swap(oldStr);
boost::algorithm::trim(swap);
return swap;
}
/// return the delimiter or throw an exception if there is no known delimiter in value
inline size_t checkDelim(const std::string& value, const std::string& delims) {
inline size_t checkDelim(const std::string& value, const std::string& delims)
{
size_t pos(std::string::npos);
for (unsigned i= 0; i<delims.length(); ++i) {
pos= value.find(delims[i]);
if (pos!=std::string::npos)
for (unsigned i = 0; i < delims.length(); i++) {
pos = value.find(delims[i]);
if (pos != std::string::npos)
return i;
}
throw NoDelim("cannot detect the delimiter in " + value);
......@@ -85,42 +143,42 @@ namespace AMDiS {
* - member function push_back
*/
template< typename Container >
inline void getContainer(const std::string val_, Container& c) {
inline void getContainer(const std::string val_, Container& c)
{
// accepted brackets and delimiters for vector input
std::string begBrackets= "{[(";
std::string endBrackets= "}])";
std::string delims= ",;";
c.clear();
std::string val= trim(val_);
size_t pos= begBrackets.find(val[0]);
if( pos == std::string::npos )
std::string val = trim(val_);
size_t pos = begBrackets.find(val[0]);
if (pos == std::string::npos)
throw WrongVectorFormat("cannot convert '" + val + "' into a list. No leading bracket found!");
if( val[val.length() - 1] != endBrackets[pos] )
if (val[val.length() - 1] != endBrackets[pos])
throw WrongVectorFormat("begin and end bracket are different in value '" + val + "'");
size_t oldPos= 1;
size_t curDelim= 0;
size_t oldPos = 1;
size_t curDelim = 0;
typedef typename Container::value_type ValueType;
ValueType swap;
try {
curDelim= checkDelim(val, delims);
pos= val.find(delims[curDelim], oldPos);
while( pos != std::string::npos ) {
std::string curWord= val.substr(oldPos, pos - oldPos);
oldPos= pos + 1;
curDelim = checkDelim(val, delims);
pos = val.find(delims[curDelim], oldPos);
while (pos != std::string::npos) {
std::string curWord = val.substr(oldPos, pos - oldPos);
oldPos = pos + 1;
convert(curWord, swap);
c.push_back(swap);
pos= val.find(delims[curDelim], oldPos);
}
//last entry
std::string curWord= val.substr(oldPos, val.length()-1 - oldPos);
std::string curWord = val.substr(oldPos, val.length() - 1 - oldPos);
convert(curWord, swap);
c.push_back(swap);
} catch (NoDelim nd) {
std::string curWord= val.substr(1, val.length()-2);
std::string curWord = val.substr(1, val.length() - 2);
curWord = trim(curWord);
if(curWord.length()>0) {
if (curWord.length() > 0) {
// container with one entry
convert(curWord, swap);
c.push_back(swap);
......@@ -128,16 +186,19 @@ namespace AMDiS {
}
}
/// convert string to string
inline void convert(const std::string valStr, std::string& value) {
value= trim(valStr);
inline void convert(const std::string valStr, std::string& value)
{
value = trim(valStr);
}
/// convert string to intrinsic type
template< typename T >
template<typename T>
inline void convert(const std::string valStr, T& value ,
typename boost::enable_if< boost::is_pod< T > >::type* p = NULL ,
typename boost::disable_if< boost::is_enum< T > >::type* p2 = NULL )
typename boost::enable_if<boost::is_pod<T> >::type* p = NULL ,
typename boost::disable_if<boost::is_enum<T> >::type* p2 = NULL)
{
using boost::lexical_cast;
using boost::numeric_cast;
......@@ -148,133 +209,164 @@ namespace AMDiS {
parser.DefineConst(_T("M_E"), m_e);
try {
parser.SetExpr(valStr);
// value = lexical_cast< T >(trim(valStr));
value= numeric_cast< T >(parser.Eval());
value = numeric_cast< T >(parser.Eval());
} catch(boost::bad_lexical_cast e) {
throw WrongValueFormat< T >(valStr);
} catch(boost::bad_numeric_cast e) {
throw WrongValueFormat< T >(valStr);
} catch (mu::Parser::exception_type &e) {
throw BadArithmeticExpression< T >(e.GetMsg(), valStr);
throw BadArithmeticExpression<T>(e.GetMsg(), valStr);
}
}
template< typename T >
template<typename T>
inline void convert(const std::string valStr, T& value,
typename boost::enable_if< boost::is_enum< T > >::type* p = NULL)
{
unsigned int swap= 0;
unsigned int swap = 0;
try {
swap = boost::lexical_cast< unsigned int >(trim(valStr));
}catch(boost::bad_lexical_cast e) {
swap = boost::lexical_cast<unsigned int>(trim(valStr));
} catch(boost::bad_lexical_cast e) {
throw WrongValueFormat< T >(valStr);
}
value = static_cast< T >(swap);
}
/// convert string to WorldVector
template< typename T >
inline void convert(const std::string valStr, WorldVector<T>& c) {
inline void convert(const std::string valStr, WorldVector<T>& c)
{
std::vector<T> temp_vec;
getContainer(valStr, temp_vec);
if (static_cast<int>(temp_vec.size())!=c.getSize())
if (static_cast<int>(temp_vec.size()) != c.getSize())
throw WrongVectorSize("wrong number of entries for WorldVector");
for (unsigned i= 0; i<temp_vec.size(); ++i)
c[i]= temp_vec[i];
for (unsigned i = 0; i < temp_vec.size(); i++)
c[i] = temp_vec[i];
}
/// convert string to std::list using begBrackets, endBrackets and delims
template< typename T >
inline void convert(const std::string valStr, std::list< T >& value) {
template<typename T>
inline void convert(const std::string valStr, std::list<T>& value)
{
getContainer(valStr, value);
}
/// convert string to std::vector using begBrackets, endBrackets and delims
template< typename T >
inline void convert(const std::string valStr, std::vector< T >& value) {
template<typename T>
inline void convert(const std::string valStr, std::vector<T>& value)
{
getContainer(valStr, value);
}
/// convert value of arbitrary type to string using stringstream and operator<< for type
template< typename T >
inline void convert(const T value, std::string& valStr) {
template<typename T>
inline void convert(const T value, std::string& valStr)
{
std::stringstream ss;
ss << value;
valStr= ss.str();
}
/// convert WorldVector to string
template< typename T >
inline void convert(const WorldVector<T>& c, std::string& valStr) {
template<typename T>
inline void convert(const WorldVector<T>& c, std::string& valStr)
{
std::vector<T> temp_vec(c.getSize());
for (unsigned i= 0; i<temp_vec.size(); ++i)
temp_vec[i]= c[i];
for (unsigned i = 0; i < temp_vec.size(); i++)
temp_vec[i] = c[i];
convert(temp_vec, valStr);
}
} // end namespace InitfileInternal
/** The entry in an initfile. This helper class was constructed to allow calls like
/** The entry in an initfile. This helper class was constructed to allow calls like
* val = data.get(tag)
* for arbitrary types of val. At current stage, only double and bool is supported
*/
struct InitEntry {
struct InitEntry {
///the value as string
std::string valStr;
/// initialize with value as string
InitEntry(std::string v= ""):
valStr(v) {}
InitEntry(std::string v = "")
: valStr(v)
{}
/// cast string to type T
template< typename T >
operator T() const { T t; convert(valStr, t); return t;}
};
template<typename T>
operator T() const
{
T t;
convert(valStr, t);
return t;
}
};
/// output-stream for std::list
template< typename T >
std::ostream& operator<<(std::ostream& o, const std::list< T >& l) {
typename std::list< T >::const_iterator it= l.begin();
/// output-stream for std::list
template<typename T>
std::ostream& operator<<(std::ostream& o, const std::list< T >& l)
{
typename std::list< T >::const_iterator it = l.begin();
o << "[";
for(unsigned i= 0; it!=l.end() && i<l.size(); ++i) {
o << *it << (i<l.size()-1?", ":"");
for (unsigned i = 0; it != l.end() && i < l.size(); i++) {
o << *it << (i < l.size() - 1 ? ", " : "");
++it;
}
o << "]";
return o;
}
/// output-stream for std::vector
template< typename T >