Liebe Gitlab-Nutzer, lieber Gitlab-Nutzer, es ist nun möglich sich mittels des ZIH-Logins/LDAP an unserem Dienst anzumelden. Ein Anmelden über dieses erzeugt ein neues Konto. Das alte Konto ist über den Reiter "Standard" erreichbar. Die Administratoren

Dear Gitlab user, it is now possible to log in to our service using the ZIH login/LDAP. Logging in via this will create a new account. The old account can be accessed via the "Standard" tab. The administrators

Commit 00561533 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

new Initfile parser

parent 32af9a5a
......@@ -68,7 +68,7 @@ set(AMDIS_MINOR_VERSION @AMDIS_MINOR@)
if(AMDiS_NEED_UMFPACK)
#look for umfpack, we need the headers only
find_file(UMFPACK_H umfpack.h
HINTS /usr/include /usr/include/suitesparse
HINTS /usr/include /usr/include/suitesparse /usr/include/ufsparse
DOC "headerfile umfpack.h for UMFPACK")
if( UMFPACK_H )
#construct the include path
......@@ -125,6 +125,11 @@ if(AMDiS_NEED_UMFPACK)
list(APPEND AMDIS_LIBRARY_DIRS ${BLAS_LIBRARY_DIR})
endif(AMDiS_NEED_UMFPACK)
#add directories for reinit
list(APPEND AMDIS_INCLUDE_DIRS ${AMDIS_INCLUDE_DIR}/reinit)
list(APPEND AMDIS_INCLUDE_DIRS ${AMDIS_INCLUDE_DIR}/compositeFEM)
if(${AMDIS_FIND_COMPONENTS} MATCHES umfpack )
if( NOT AMDiS_NEED_UMFPACK )
set( AMDiS_umfpack_FOUND FALSE)
......
......@@ -100,6 +100,7 @@ SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc
${SOURCE_DIR}/Global.cc
${SOURCE_DIR}/GlobalDOFNumbering.cc
${SOURCE_DIR}/GlobalElementNumbering.cc
${SOURCE_DIR}/Initfile.cc
${SOURCE_DIR}/Lagrange.cc
${SOURCE_DIR}/LeafData.cc
${SOURCE_DIR}/Line.cc
......@@ -288,7 +289,7 @@ if(ENABLE_UMFPACK)
#look for umfpack, we need the headers only
find_file(UMFPACK_H umfpack.h
HINTS /usr/include /usr/include/suitesparse
HINTS /usr/include /usr/include/suitesparse /usr/include/ufsparse
DOC "headerfile umfpack.h for UMFPACK")
if( UMFPACK_H )
#construct the include path
......@@ -345,8 +346,9 @@ include_directories(${AMDiS_INCLUDE_DIRS})
add_library(amdis SHARED ${AMDIS_SRC} ${PARALLEL_DOMAIN_AMDIS_SRC})
add_library(compositeFEM SHARED ${COMPOSITE_FEM_SRC})
add_library(reinit STATIC ${REINIT_SRC})
target_link_libraries(compositeFEM amdis)
add_library(reinit SHARED ${REINIT_SRC})
#target_link_libraries(compositeFEM amdis)
#target_link_libraries(reinit amdis)
list(APPEND AMDiS_LIBS amdis ${Boost_LIBRARIES})
if(WIN32)
......@@ -361,9 +363,6 @@ if(ENABLE_MARMOT)
endif(ENABLE_MARMOT)
#dont change this destination. the GUI depends on it to guess the buildsystem
list(APPEND deb_add_dirs "lib/amdis")
install(TARGETS amdis compositeFEM
LIBRARY DESTINATION lib/amdis/ )
FILE(GLOB HEADERS "${SOURCE_DIR}/*.h")
INSTALL(FILES ${HEADERS}
......@@ -398,6 +397,20 @@ FILE(GLOB HEADERS "${SOURCE_DIR}/io/*.hh")
INSTALL(FILES ${HEADERS}
DESTINATION include/amdis/io)
FILE(GLOB HEADERS "${REINIT_SOURCE_DIR}/*.h")
INSTALL(FILES ${HEADERS}
DESTINATION include/amdis/reinit)
list(APPEND deb_add_dirs "include/amdis/reinit")
FILE(GLOB HEADERS "${COMPOSITE_SOURCE_DIR}/*.h")
INSTALL(FILES ${HEADERS}
DESTINATION include/amdis/compositeFEM)
list(APPEND deb_add_dirs "include/amdis/compositeFEM")
list(APPEND deb_add_dirs "lib/amdis")
install(TARGETS amdis compositeFEM reinit
LIBRARY DESTINATION lib/amdis/ )
configure_file(${AMDiS_SOURCE_DIR}/AMDiSConfig.cmake.in
${AMDiS_BINARY_DIR}/AMDISConfig.cmake
@ONLY
......
#include "Initfile.h"
#include <string>
#include <stdexcept>
#include <iostream>
#include <sstream>
using namespace std;
/// 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();
// 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");
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);
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);
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");
}
read(fn);
}
in.getline(swap, line_length);
}
};
/// read standard values for output and information of parameter-values
void Initfile::getInternalParameters()
{
int val= 10;
get("level of information", val, 0);
msgInfo= val;
val= 1;
get("WAIT", val, 0);
msgWait= val;
val= 1;
get("parameter information", val, 0);
paramInfo= val;
if (msgInfo==0)
paramInfo= 0;
};
/// print all parameters to std::cout
void Initfile::printParameters() {
initIntern();
Initfile::iterator it;
for (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++)
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");
write(outFile);
};
#ifndef INITFILE_H
#define INITFILE_H
#include <fstream>
#include <sstream>
#include <string>
#include <map>
#include <list>
#include <set>
#include <vector>
#include <stdexcept>
#include <iostream>
#include <typeinfo>
#include "FixVec.h"
#include <boost/algorithm/string/trim.hpp>
#include <boost/lexical_cast.hpp>
using namespace AMDiS;
namespace InitfileInternal {
/// Exceptions
struct WrongVectorSize : std::runtime_error {
WrongVectorSize(std::string m):std::runtime_error(m) {}
};
struct NoDelim : std::runtime_error {
NoDelim(std::string m):std::runtime_error(m) {}
};
struct WrongVectorFormat : std::runtime_error {
WrongVectorFormat(std::string m):std::runtime_error(m) {}
};
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())+">" )
{}
};
/// trim std::string
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
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)
return i;
}
throw NoDelim("cannot detect the delimiter in " + value);
return 0;
}
/** parse an container from tag tag. The Container must have the properties:
* - type value_type
* - member function push_back
*/
template< typename Container >
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 )
throw WrongVectorFormat("cannot convert '" + val + "' into a list. No leading bracket found!");
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;
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 - 1);
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() - oldPos-1);
convert(curWord, swap);
c.push_back(swap);
} catch (NoDelim nd) {
std::string curWord= val.substr(1, val.length()-2);
curWord = trim(curWord);
if(curWord.length()>0) {
// container with one entry
convert(curWord, swap);
c.push_back(swap);
}
}
}
/// convert string to string
inline void convert(const std::string valStr, std::string& value) {
value= trim(valStr);
}
/// convert string to intrinsic type
template< typename T >
inline void convert(const std::string valStr, T& value) {
using boost::lexical_cast;
try {
value = lexical_cast< T >(trim(valStr));
}catch(boost::bad_lexical_cast e) {
throw WrongValueFormat< T >(valStr);
}
}
/// convert string to WorldVector
template< typename T >
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())
throw WrongVectorSize("wrong number of entries for WorldVector");
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) {
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) {
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) {
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) {
std::vector<T> temp_vec(c.getSize());
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
* val = data.get(tag)
* for arbitrary types of val. At current stage, only double and bool is supported
*/
struct InitEntry {
///the value as string
std::string valStr;
/// initialize with value as string
InitEntry(std::string v= ""):
valStr(v) {}
/// cast string to type 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();
o << "[";
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 >
std::ostream& operator<<(std::ostream& o, const std::vector< T >& l) {
typename std::vector< T >::const_iterator it= l.begin();
o << "[";
for(unsigned i= 0; it!=l.end() && i<l.size(); ++i) {
o << *it << (i<l.size()-1?", ":"");
++it;
}
o << "]";
return o;
}
/** Basis data container as a map of tag on a value as strings. The container throws an exception, if the tag was not found.
*/
struct Initfile : public std::map< std::string, std::string > {
typedef std::map< std::string, std::string > super;
/// Exceptions
struct TagNotFound : std::invalid_argument {
TagNotFound(std::string m):std::invalid_argument(m) {}
};
/** initialize init-file from file with filename in, read data and save it to singleton-map
* @param in: filename string
*/
static void init(std::string in);
/** Static get routine for getting parameter-values from init-file initialized in init()-method.
* Cast the value to the desired type using std::stringstream.
* @param tag: The tag to look for
* @param value: The result.
* @param debug_info: msgInfo for current parameter. (0..no printing, 1..print missing parameter info, 2..print parameter value) [optional]
*/
template< typename T >
static void get(const std::string tag, T& value, int debug_info= -1) {
using namespace InitfileInternal;
initIntern();
if (debug_info==-1)
debug_info= singlett->getMsgInfo();
try {
std::string valStr(singlett->checkedGet(tag));
valStr= trim(valStr);
convert(valStr, value);
if (debug_info==2)
std::cout << "Parameter '" << tag << "' initialized with: " << value << std::endl;
} catch (TagNotFound ia) {
if (debug_info>=1)
std::cout << ia.what() << std::endl;
}
}
/// return InitEntry object for tag tag
static InitEntry get(const std::string tag) {
using namespace InitfileInternal;
int debug_info= singlett->getMsgInfo();
InitEntry result;
try {
std::string valStr(singlett->checkedGet(tag));
valStr= trim(valStr);
result= InitEntry(valStr);
} catch (TagNotFound ia) {
if (debug_info>=1)
std::cout << ia.what() << std::endl;
}
return result;
}
/// update map tag->value_old to tag->value in singleton
template< typename T >
static void set(const std::string tag, T& value, int debug_info= -1) {
using namespace InitfileInternal;
initIntern();
if (debug_info==-1)
debug_info= singlett->getMsgInfo();
std::string swap= "";
convert(value, swap);
(*singlett)[trim(tag)]= swap;
// update msg parameters msgInfo, msgWait, paramInfo
singlett->getInternalParameters();
if (debug_info==2)
std::cout << "Parameter '" << tag << "' set to: " << value << std::endl;
}
/// add map tag->value to data in singleton
template< typename T >
static void add(const std::string tag, T& value, int debug_info= -1) {
set(tag, value, debug_info);
}
/// Returns specified info level
static int getMsgInfo()
{
return (singlett!=NULL) ? singlett->msgInfo : 0;
}
/// Returns specified wait value
static int getMsgWait()
{
return (singlett!=NULL) ? singlett->msgWait : 0;
}
/// Checks whether parameters are initialized. if not, call init()
static bool initialized()
{
return (singlett!=NULL);
}
/// return pointer to singleton
static Initfile *getSingleton()
{
return singlett;
}
/// print all data in singleton to std::cout
static void printParameters();
/// clear data in singleton
static void clearData()
{
initIntern();
singlett->clear();
}
/// save singlett-data to file with filename fn
static void save(std::string fn)
{
initIntern();
singlett->write(fn);
}
protected:
Initfile() : msgInfo(10), msgWait(1), paramInfo(1) {}
static void initIntern() {
if (singlett == NULL)
singlett= new Initfile;
}
/// list of processed files
static std::set< std::string > fn_include_list;
/// pointer to the singleton that contains the data
static Initfile* singlett;
/// return the value of the given tag or throws an exception if the tag does not exist
std::string checkedGet(const std::string& tag) const {
super::const_iterator it= find(tag);
if (it==end())
throw TagNotFound("there is no tag '"+ tag + "'");
return it->second;
}
/** Fill the initfile from an input stream.
* @param in: the stream to fill the data from.
* Current dataformat: tag:value
* Comment char: percent '%'
* Include files: #include "filename" or #include <filename>
*/
void read(std::istream& in);
/// Fill the initfile from a file with filename fn
void read(std::string fn);
/** Write data-map to initfile
* @param out: the stream to fill the data in.
*/
void write(std::ostream& out);
/// Write data-map to initfile with filename fn
void write(std::string fn);
/// read parameters for msgInfo, msgWait, paramInfo
void getInternalParameters();
int msgInfo, msgWait, paramInfo;
};
#endif
......@@ -340,41 +340,41 @@ namespace AMDiS {
return(key);
if (s[pos] == '#') {
if (static_cast<int>(s.find("#include")) == pos) {
/****************************************************************************/
/* another init file has to be included */
/****************************************************************************/
pos += strlen("#include");
pos = s.find_first_not_of(" \t\f\r");
i = 0;
switch (c = s[pos++]) {
case '<':
c = '>';