Skip to content
Snippets Groups Projects
Select Git revision
  • 29c5bb02a904e4ed61144ccb8b4c4c12389bb774
  • master default protected
  • develop protected
  • feature/triangulation-qhull
  • jst
  • ti_lab_build
  • features/splines_and_piecewise_polynomials
  • ma_2018/erraji
  • fabian
  • ITABase_v2024a
  • VA_v2023b
  • VA_v2023a
  • VA_v2022a
  • before_cmake_rework
  • v2021.a
  • v2020.a
  • v2019.a
  • v2018.b
  • v2018.a
  • v2017.d
  • v2017.c
  • v2017.b
  • v2017.a
  • v2016.a
24 results

ITAStringUtilsPCRE.cpp

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    ITAStringUtilsPCRE.cpp 22.19 KiB
    #include <ITAStringUtils.h>
    
    #include <assert.h>
    #include <algorithm>
    #include <cctype>
    #include <cmath>
    #include <cstdio>
    #include <iomanip>
    #include <numeric>
    #include <sstream>
    
    #include <ITAConstants.h>
    #include <ITAException.h>
    #include <ITANumericUtils.h>
    
    #ifdef WIN32
    #include <ITAHPT.h>
    #endif
    
    #include <pcrecpp.h>
    
    // Diese Makro aktiviert die String-Überprüfungen mittels Regex für String->Typ Konvertierungen
    #define VERIFY_STRING_CONVERSIONS
    
    // Definition der regul�ren Ausdr�cke f�r die �berpr�fung
    #define RE_BOOL_TRUE				"^\\s*(yes|true)\\s*$"
    #define RE_BOOL_FALSE				"^\\s*(no|false)\\s*$"
    #define RE_INT						"^\\s*([\\+\\-]?\\d+)\\s*$"
    #define RE_UINT						"^\\s*(\\+?\\d+)\\s*$"		// Kein Minus erlaubt!
    #define RE_FLOAT					"^\\s*((\\+|-)?([0-9]+\\.?[0-9]*|\\.[0-9]+)([eE](\\+|-)?[0-9]+)?)\\s*$"
    #define RE_AMP_FACTOR				"^\\s*(\\d+|\\d*\\.\\d+)\\s*$"
    #define RE_AMP_DECIBEL				"^\\s*((\\+|\\-)?(\\d+|\\d*\\.\\d+))\\s*db\\s*$"
    #define RE_AMP_DECIBEL_MINUS_INF	"^\\s*\\-inf\\s*db\\s*$"
    
    // Optionen f�r das Parsing
    static pcrecpp::RE_Options REOpts( PCRE_CASELESS | PCRE_MULTILINE );
    
    // Regul�re Ausdr�cke (Instanzen) f�r die �berpr�fung
    static pcrecpp::RE* REBoolTrue = NULL;
    static pcrecpp::RE* REBoolFalse = NULL;
    static pcrecpp::RE* REInt = NULL;
    static pcrecpp::RE* REUInt = NULL;
    static pcrecpp::RE* REFloat = NULL;
    static pcrecpp::RE* REAmpFactor = NULL;
    static pcrecpp::RE* REAmpDecibel = NULL;
    static pcrecpp::RE* REAmpDecibelMinusInf = NULL;
    
    // Standard Konvertierungen (wie früher mit Exceptions)
    ITAConversion g_oDefaultConversion( ITAConversion::STRICT_MODE | ITAConversion::THROW_EXCEPTIONS );
    
    // --------------------------------------------------------------------------
    
    std::string nTimes( std::string s, unsigned int n )
    {
    	std::string result;
    	for( unsigned int i = 0; i < n; i++ ) result += s;
    	return result;
    }
    
    std::string BoolToString( bool bValue ) 
    {
    	std::stringstream ssStream;
    	ssStream << bValue;
    	return ssStream.str();
    }
    
    std::string IntToString( int iValue )
    {
    	std::stringstream ssStream;
    	ssStream << iValue;
    	return ssStream.str();
    }
    
    std::string UIntToString( unsigned int uiValue )
    {
    	std::stringstream ssStream;
    	ssStream << uiValue;
    	return ssStream.str();
    }
    
    std::string LongToString( unsigned int lValue )
    {
    	std::stringstream ssStream;
    	ssStream << lValue;
    	return ssStream.str();
    }
    
    std::string Int64ToString( int64_t i64Value )
    {
    	std::stringstream ssStream;
    	ssStream << i64Value;
    	return ssStream.str();
    }
    
    std::string UInt64ToString( uint64_t ui64Value ) {
    	std::stringstream ssStream;
    	ssStream << ui64Value;
    	return ssStream.str();
    }
    
    std::string FloatToString( float fValue, int iPrecision )
    {
    	std::stringstream ssStream;
    	if( iPrecision != -1 ) {
    		ssStream.setf( std::ios_base::fixed, std::ios_base::floatfield );
    		ssStream.precision( iPrecision );
    	}
    	ssStream << fValue;
    	return ssStream.str();
    }
    
    std::string DoubleToString( double dValue, int iPrecision ) {
    	std::stringstream ssStream;
    	if( iPrecision != -1 ) {
    		ssStream.setf( std::ios_base::fixed, std::ios_base::floatfield );
    		ssStream.precision( iPrecision );
    	}
    	ssStream << dValue;
    	return ssStream.str();
    }
    
    std::string BitmaskToString( int iMask, int iNumBits ) {
    	std::stringstream ssStream;
    	for( int i = iNumBits - 1; i >= 0; i-- )
    		ssStream << ( ( iMask & ( 1 << i ) ) ? "1" : "0" );
    	return ssStream.str();
    }
    
    std::string DecibelToString( double dDecibelValue, std::string sMinusInfinity, std::string sUnit )
    {
    	if( dDecibelValue == -std::numeric_limits< double >::infinity() )
    		return sMinusInfinity + std::string( " " ) + sUnit;
    
    	std::stringstream ssStream;
    	ssStream.setf( std::ios_base::fixed, std::ios_base::floatfield );
    	ssStream.precision( 1 );
    	// F�r Werte gr��er Null auch immer das Vorzeichen ("+") ausgeben
    	if( dDecibelValue > 0 ) ssStream << "+";
    	ssStream << dDecibelValue << " " << sUnit.c_str();
    	return ssStream.str();
    }
    
    std::string IntVecToString( std::vector<int> viValues, std::string sSeparator ) {
    	std::string s;
    	if( !viValues.empty() ) {
    		s += IntToString( viValues.front() );
    		for( unsigned int i = 1; i < viValues.size(); i++ )
    			s += sSeparator + IntToString( viValues[ i ] );
    	}
    	return s;
    }
    
    std::string UIntVecToString( std::vector<unsigned int> vuiValues, std::string sSeparator ) {
    	std::string s;
    	if( !vuiValues.empty() ) {
    		s += UIntToString( vuiValues.front() );
    		for( unsigned int i = 1; i < vuiValues.size(); i++ )
    			s += sSeparator + UIntToString( vuiValues[ i ] );
    	}
    	return s;
    }
    
    std::string FloatVecToString( std::vector<float> vfValues, int iPrecision, std::string sSeparator ) {
    	std::string s;
    	if( !vfValues.empty() ) {
    		s += FloatToString( vfValues.front() );
    		for( unsigned int i = 1; i < vfValues.size(); i++ )
    			s += sSeparator + FloatToString( vfValues[ i ], iPrecision );
    	}
    	return s;
    }
    
    std::string DoubleVecToString( std::vector<double> vdValues, int iPrecision, std::string sSeparator ) {
    	std::string s;
    	if( !vdValues.empty() ) {
    		s += DoubleToString( vdValues.front() );
    		for( unsigned int i = 1; i < vdValues.size(); i++ )
    			s += sSeparator + DoubleToString( vdValues[ i ], iPrecision );
    	}
    	return s;
    }
    
    std::string StringVecToString( std::vector<std::string> vsValues, std::string sSeparator ) {
    	std::string s;
    	if( !vsValues.empty() ) {
    		s += vsValues.front();
    		for( unsigned int i = 1; i < vsValues.size(); i++ )
    			s += sSeparator + vsValues[ i ];
    	}
    	return s;
    }
    
    std::string IntArrayToString( const int* piValues, size_t count, std::string sSeparator ) {
    	std::string s;
    	if( count > 0 ) {
    		s += IntToString( piValues[ 0 ] );
    		for( size_t i = 1; i < count; i++ )
    			s += sSeparator + IntToString( piValues[ i ] );
    	}
    	return s;
    }
    
    std::string UIntArrayToString( const unsigned int* puiValues, size_t count, std::string sSeparator ) {
    	std::string s;
    	if( count > 0 ) {
    		s += UIntToString( puiValues[ 0 ] );
    		for( size_t i = 1; i < count; i++ )
    			s += sSeparator + UIntToString( puiValues[ i ] );
    	}
    	return s;
    }
    
    std::string FloatArrayToString( const float* pfValues, size_t count, int iPrecision, std::string sSeparator ) {
    	std::string s;
    	if( count > 0 ) {
    		s += FloatToString( pfValues[ 0 ] );
    		for( size_t i = 1; i < count; i++ )
    			s += sSeparator + FloatToString( pfValues[ i ], iPrecision );
    	}
    	return s;
    }
    
    std::string ComplexFloatArrayToString( const float* pfValues, size_t count, int iPrecision, std::string sSeparator ) {
    	std::string s;
    	if( count > 0 ) {
    		for( size_t i = 0; i < count; i++ ) {
    			if( i>0 ) s += sSeparator;
    			s += FloatToString( pfValues[ 2 * i ], iPrecision );
    			if( pfValues[ 2 * i + 1 ] < 0 )
    				s += FloatToString( pfValues[ 2 * i + 1 ], iPrecision ) + "i";
    			if( pfValues[ 2 * i + 1 ] > 0 )
    				s += "+" + FloatToString( pfValues[ 2 * i + 1 ], iPrecision ) + "i";
    		}
    	}
    	return s;
    }
    
    std::string DoubleArrayToString( const double* pdValues, size_t count, int iPrecision, std::string sSeparator ) {
    	std::string s;
    	if( count > 0 ) {
    		s += DoubleToString( pdValues[ 0 ] );
    		for( size_t i = 1; i < count; i++ )
    			s += sSeparator + DoubleToString( pdValues[ i ], iPrecision );
    	}
    	return s;
    }
    
    std::string StringArrayToString( const char** ppcValues, size_t count, std::string sSeparator ) {
    	std::string s;
    	if( count > 0 ) {
    		s += ppcValues[ 0 ];
    		for( size_t i = 1; i < count; i++ )
    			s += sSeparator + ppcValues[ i ];
    	}
    	return s;
    }
    
    std::string toLowercase( const std::string& s ) {
    	std::string result = s;
    	std::transform( result.begin(), result.end(), result.begin(), ( int( *)( int ) ) ::tolower );
    	return result;
    }
    
    std::string toUppercase( const std::string& s ) {
    	std::string result = s;
    	std::transform( result.begin(), result.end(), result.begin(), ( int( *)( int ) ) ::toupper );
    	return result;
    }
    
    std::string stripSpaces( const std::string& s ) {
    	// fwe: Bugfix. Crash unten, im Fall von s=""
    	if( s.empty() ) return s;
    
    	/* Neuer Code: Erkennt auch Tabulatoren als Leerraum */
    	int n = ( int ) s.length();
    	int a = 0;
    	do {
    		if( ( s[ a ] != ' ' ) && ( s[ a ] != '\t' ) ) break;
    	} while( ++a < n );
    
    	int b = n - 1;
    	do {
    		if( ( s[ b ] != ' ' ) && ( s[ b ] != '\t' ) ) break;
    	} while( --b > 0 );
    
    	return s.substr( a, b - a + 1 );
    }
    
    bool StringToBool( const std::string& s ) {
    	bool b;
    	g_oDefaultConversion.StringToBool( s, b );
    	return b;
    }
    
    int StringToInt( const std::string& s ) {
    	int i;
    	g_oDefaultConversion.StringToInt( s, i );
    	return i;
    }
    
    unsigned int StringToUInt( const std::string& s ) {
    	unsigned int i;
    	g_oDefaultConversion.StringToUInt( s, i );
    	return i;
    }
    
    int64_t StringToInt64( const std::string& s ) {
    	int64_t i;
    	g_oDefaultConversion.StringToInt64( s, i );
    	return i;
    }
    
    uint64_t StringToUInt64( const std::string& s ) {
    	uint64_t i;
    	g_oDefaultConversion.StringToUInt64( s, i );
    	return i;
    }
    
    float StringToFloat( const std::string& s ) {
    	float x;
    	g_oDefaultConversion.StringToFloat( s, x );
    	return x;
    }
    
    double StringToDouble( const std::string& s ) {
    	double x;
    	g_oDefaultConversion.StringToDouble( s, x );
    	return x;
    }
    
    std::vector<int> StringToIntVec( const std::string& s, std::string sSeparatorRegex, bool bMatchCase ) {
    	std::vector<int> v;
    	g_oDefaultConversion.StringToIntVec( s, v, sSeparatorRegex, bMatchCase );
    	return v;
    }
    
    std::vector<unsigned int> StringToUIntVec( const std::string& s, std::string sSeparatorRegex, bool bMatchCase ) {
    	std::vector<unsigned int> v;
    	g_oDefaultConversion.StringToUIntVec( s, v, sSeparatorRegex, bMatchCase );
    	return v;
    }
    
    std::vector<float> StringToFloatVec( const std::string& s, std::string sSeparatorRegex, bool bMatchCase ) {
    	std::vector<float> v;
    	g_oDefaultConversion.StringToFloatVec( s, v, sSeparatorRegex, bMatchCase );
    	return v;
    }
    
    std::vector<double> StringToDoubleVec( const std::string& s, std::string sSeparatorRegex, bool bMatchCase ) {
    	std::vector<double> v;
    	g_oDefaultConversion.StringToDoubleVec( s, v, sSeparatorRegex, bMatchCase );
    	return v;
    }
    
    std::vector< std::string > StringToStringVec( const std::string& s, std::string sSeparatorRegex, bool bMatchCase ) {
    	std::vector< std::string > v;
    	g_oDefaultConversion.StringToStringVec( s, v, sSeparatorRegex, bMatchCase );
    	return v;
    }
    
    std::vector< std::string > splitString( const std::string& s, char cSeparator ) {
    	std::vector< std::string > v;
    	size_t i, j = 0;
    	for( i = 0; i < s.size(); i++ ) {
    		if( s[ i ] == cSeparator ) {
    			v.push_back( s.substr( j, i - j ) );
    			j = i + 1;
    		}
    	}
    
    	// push remainder
    	if( j < s.size() )
    		v.push_back( s.substr( j, i - j ) );
    	else
    		v.push_back( "" ); // String ends with seperator, ergo remainder empty
    
    	return v;
    }
    
    std::vector< std::string > splitString( const std::string& s, const std::string& sSeparator )
    {
    	std::vector< std::string > v;
    
    	if( sSeparator.size() == 1 )
    		return splitString( s, char( sSeparator[ 0 ] ) );
    	else
    		ITA_EXCEPT0( NOT_IMPLEMENTED ); // TODO: Implement for strings
    }
    
    void regexSplitString( const std::string& src, std::vector< std::string >& dest, const std::string& regex, bool bMatchCase )
    {
    	dest.clear();
    	if( src.empty() ) return;
    
    	pcrecpp::RE_Options re_opts;
    	re_opts.set_multiline( true );
    	re_opts.set_caseless( !bMatchCase );
    	pcrecpp::RE re( std::string( "(" + regex + std::string( ")" ) ) );
    
    	pcrecpp::StringPiece input( src );
    	std::string u, v;
    
    	int i = 0;
    	int l = input.size();
    	// DEBUG: printf("%d\n", input.size());
    	while( re.FindAndConsume( &input, &u ) ) {
    		v = src.substr( i, ( l - input.size() ) - u.size() );
    		i += ( l - input.size() );
    		l = input.size();
    		dest.push_back( v );
    	}
    
    	v = src.substr( i, src.length() - i );
    	dest.push_back( v );
    }
    
    bool ITAConversion::StringToBool( const std::string& s, bool& b ) {
    	if( m_iOpts | STRICT_MODE ) {
    		if( REBoolTrue == NULL ) {
    			// Reguläre Ausdrücke bei erster Benutzung erzeugen
    			REBoolTrue = new pcrecpp::RE( RE_BOOL_TRUE, REOpts );
    			REBoolFalse = new pcrecpp::RE( RE_BOOL_FALSE, REOpts );
    		}
    
    		if( REBoolTrue->FullMatch( s ) ) {
    			b = true;
    			return true;
    		}
    
    		if( REBoolFalse->FullMatch( s ) ) {
    			b = false;
    			return true;
    		}
    	}
    	else {
    		std::stringstream ssStream( s, std::ios_base::in );
    		if( ssStream >> b ) return true;
    	}
    
    	if( m_iOpts & THROW_EXCEPTIONS )
    		ITA_EXCEPT1( PARSE_ERROR, "The string \"" + s + "\" cannot be interpreted as a boolean value." );
    	return false;
    }
    
    bool ITAConversion::StringToInt( const std::string& s, int& i ){
    	bool bValid( true );
    
    	// Vorprüfung mittels Regex
    	if( m_iOpts | STRICT_MODE ) {
    		if( REInt == NULL ) {
    			// Reguläre Ausdrücke bei erster Benutzung erzeugen
    			REInt = new pcrecpp::RE( RE_INT, REOpts );
    		}
    
    		if( !REInt->FullMatch( s ) ) bValid = false;
    	}
    
    	if( bValid ) {
    		std::stringstream ssStream( s, std::ios_base::in );
    		bValid = !( ssStream >> i ).fail();
    	}
    
    	if( !bValid && ( m_iOpts & THROW_EXCEPTIONS ) )
    		ITA_EXCEPT1( PARSE_ERROR, "The string \"" + s + "\" cannot be interpreted as an integer value." );
    
    	return bValid;
    }
    
    bool ITAConversion::StringToUInt( const std::string& s, unsigned int& i ) {
    	bool bValid( true );
    
    	// Vorprüfung mittels Regex
    	if( m_iOpts | STRICT_MODE ) {
    		if( REUInt == NULL ) {
    			// Reguläre Ausdrücke bei erster Benutzung erzeugen
    			REUInt = new pcrecpp::RE( RE_UINT, REOpts );
    		}
    
    		if( !REUInt->FullMatch( s ) ) bValid = false;
    	}
    
    	if( bValid ) {
    		std::stringstream ssStream( s, std::ios_base::in );
    		bValid = !( ssStream >> i ).fail();
    	}
    
    	if( !bValid && ( m_iOpts & THROW_EXCEPTIONS ) )
    		ITA_EXCEPT1( PARSE_ERROR, "The string \"" + s + "\" cannot be interpreted as an non-negative integer value." );
    
    	return bValid;
    }
    
    bool ITAConversion::StringToInt64( const std::string& s, int64_t& i ) {
    	bool bValid( true );
    
    	// Vorprüfung mittels Regex
    	if( m_iOpts | STRICT_MODE ) {
    		if( REInt == NULL ) {
    			// Reguläre Ausdrücke bei erster Benutzung erzeugen
    			REInt = new pcrecpp::RE( RE_INT, REOpts );
    		}
    
    		if( !REInt->FullMatch( s ) ) bValid = false;
    	}
    
    	if( bValid ) {
    		std::stringstream ssStream( s, std::ios_base::in );
    		bValid = !( ssStream >> i ).fail();
    	}
    
    	if( !bValid && ( m_iOpts & THROW_EXCEPTIONS ) )
    		ITA_EXCEPT1( PARSE_ERROR, "The string \"" + s + "\" cannot be interpreted as an integer value." );
    
    	return bValid;
    }
    
    bool ITAConversion::StringToUInt64( const std::string& s, uint64_t& i ) {
    	bool bValid( true );
    
    	// Vorprüfung mittels Regex
    	if( m_iOpts | STRICT_MODE ) {
    		if( REUInt == NULL ) {
    			// Reguläre Ausdrücke bei erster Benutzung erzeugen
    			REUInt = new pcrecpp::RE( RE_UINT, REOpts );
    		}
    
    		if( !REUInt->FullMatch( s ) ) bValid = false;
    	}
    
    	if( bValid ) {
    		std::stringstream ssStream( s, std::ios_base::in );
    		bValid = !( ssStream >> i ).fail();
    	}
    
    	if( !bValid && ( m_iOpts & THROW_EXCEPTIONS ) )
    		ITA_EXCEPT1( PARSE_ERROR, "The string \"" + s + "\" cannot be interpreted as an non-negative integer value." );
    
    	return bValid;
    }
    
    bool ITAConversion::StringToFloat( const std::string& s, float& f ) {
    	bool bValid( true );
    
    	// Vorprüfung mittels Regex
    	if( m_iOpts | STRICT_MODE ) {
    		if( REFloat == NULL ) {
    			// Reguläre Ausdrücke bei erster Benutzung erzeugen
    			REFloat = new pcrecpp::RE( RE_FLOAT, REOpts );
    		}
    
    		if( !REFloat->FullMatch( s ) ) bValid = false;
    	}
    
    	if( bValid ) {
    		std::stringstream ssStream( s, std::ios_base::in );
    		bValid = !( ssStream >> f ).fail();
    	}
    
    	if( !bValid && ( m_iOpts & THROW_EXCEPTIONS ) )
    		ITA_EXCEPT1( PARSE_ERROR, "The string \"" + s + "\" cannot be interpreted as a floating point value." );
    
    	return bValid;
    }
    
    bool ITAConversion::StringToDouble( const std::string& s, double& d ) {
    	bool bValid( true );
    
    	// Vorprüfung mittels Regex
    	if( m_iOpts | STRICT_MODE ) {
    		if( REFloat == NULL ) {
    			// Reguläre Ausdrücke bei erster Benutzung erzeugen
    			REFloat = new pcrecpp::RE( RE_FLOAT, REOpts );
    		}
    
    		if( !REFloat->FullMatch( s ) ) bValid = false;
    	}
    
    	if( bValid ) {
    		std::stringstream ssStream( s, std::ios_base::in );
    		bValid = !( ssStream >> d ).fail();
    	}
    
    	if( !bValid && ( m_iOpts & THROW_EXCEPTIONS ) )
    		ITA_EXCEPT1( PARSE_ERROR, "The string \"" + s + "\" cannot be interpreted as a floating point value." );
    
    	return bValid;
    }
    
    bool ITAConversion::StringToIntVec( const std::string& s, std::vector<int>& v, std::string sSeparatorRegex, bool bMatchCase )
    {
    	// [fwe 2008-07-09] TODO: Diese Implementierung ist mal eben gebaut und hemdsärmelig! Verbessern!
    	pcrecpp::RE_Options re_opts;
    	re_opts.set_multiline( true );
    	re_opts.set_caseless( !bMatchCase );
    	pcrecpp::RE re( "(\\s*([+-]?\\d+)\\s*)" );
    
    	pcrecpp::StringPiece input( s );
    	std::string part;
    
    	v.clear();
    	while( re.FindAndConsume( &input, &part ) )
    	{
    		int i;
    		if( !StringToInt( part, i ) )
    		{
    			v.clear();
    			return false;
    		}
    		v.push_back( i );
    	}
    
    	std::string e = re.error();
    	return true;
    }
    
    bool ITAConversion::StringToUIntVec( const std::string& s, std::vector<unsigned int>& v, std::string sSeparatorRegex, bool bMatchCase )
    {
    	// [fwe 2008-07-09] TODO: Diese Implementierung ist mal eben gebaut und hemdsärmelig! Verbessern!
    	pcrecpp::RE_Options re_opts;
    	re_opts.set_multiline( true );
    	re_opts.set_caseless( !bMatchCase );
    	pcrecpp::RE re( "(\\s*([+-]?\\d+)\\s*)" );
    
    	pcrecpp::StringPiece input( s );
    	std::string part;
    
    	v.clear();
    	while( re.FindAndConsume( &input, &part ) )
    	{
    		unsigned int i;
    		if( !StringToUInt( part, i ) )
    		{
    			v.clear();
    			return false;
    		}
    		v.push_back( i );
    	}
    
    	return true;
    }
    
    bool ITAConversion::StringToFloatVec( const std::string& s, std::vector<float>& v, std::string sSeparatorRegex, bool bMatchCase ) {
    	// [fwe 2008-07-09] TODO: Diese Implementierung ist mal eben gebaut und hemdsärmelig! Verbessern!
    	pcrecpp::RE_Options re_opts;
    	re_opts.set_multiline( true );
    	re_opts.set_caseless( !bMatchCase );
    	pcrecpp::RE re( "(\\s*([+-]?\\d+)\\s*)" );
    
    	pcrecpp::StringPiece input( s );
    	std::string part;
    
    	v.clear();
    	while( re.FindAndConsume( &input, &part ) ) {
    		float f;
    		if( !StringToFloat( part, f ) ) {
    			v.clear();
    			return false;
    		}
    		v.push_back( f );
    	}
    
    	return true;
    }
    
    bool ITAConversion::StringToDoubleVec( const std::string& s, std::vector<double>& v, std::string sSeparatorRegex, bool bMatchCase ) {
    	// [fwe 2008-07-09] TODO: Diese Implementierung ist mal eben gebaut und hemdsärmelig! Verbessern!
    	pcrecpp::RE_Options re_opts;
    	re_opts.set_multiline( true );
    	re_opts.set_caseless( !bMatchCase );
    	pcrecpp::RE re( "(\\s*([+-]?\\d+)\\s*)" );
    
    	pcrecpp::StringPiece input( s );
    	std::string part;
    
    	v.clear();
    	while( re.FindAndConsume( &input, &part ) ) {
    		double d;
    		if( !StringToDouble( part, d ) ) {
    			v.clear();
    			return false;
    		}
    		v.push_back( d );
    	}
    
    	return true;
    }
    
    bool ITAConversion::StringToStringVec( const std::string& s, std::vector< std::string >& v, std::string sSeparatorRegex, bool bMatchCase ) {
    	regexSplitString( s, v, sSeparatorRegex, bMatchCase );
    	return true;
    }
    
    std::string ratio_to_db_str_internal( double db, std::string sSuffix )
    {
    	std::string s;
    	char buf[ 128 ];
    	if( db == -std::numeric_limits< double >::infinity() )
    	{
    		s = "-inf";
    	}
    	else
    	{
    		// Auf eine Nachkommastelle runden, Aufrunden bei 0.05 -> 0.1
    		db = round( db * 10.0 ) * 0.1;
    		if( db == 0 )
    		{
    			s = "0";
    		}
    		else
    		{
    			if( db < 0 )
    				sprintf( buf, "%0.1f", db );
    			else
    				sprintf( buf, "+%0.1f", db );
    
    			s = buf;
    		}
    	}
    
    	return s + std::string( " dB" ) + sSuffix;
    }
    
    std::string ratio_to_db10_str( double r, std::string sSuffix ) {
    	return ratio_to_db_str_internal( ratio_to_db10( r ), sSuffix );
    }
    
    std::string ratio_to_db20_str( double r, std::string sSuffix ) {
    	return ratio_to_db_str_internal( ratio_to_db20( r ), sSuffix );
    }
    
    double str_to_amp_ratio_db10( const std::string& s ) {
    	if( !REAmpFactor ) {
    		// Regul�re Ausdr�cke bei erster Benutzung erzeugen
    		REAmpFactor = new pcrecpp::RE( RE_AMP_FACTOR, REOpts );
    		REAmpDecibel = new pcrecpp::RE( RE_AMP_DECIBEL, REOpts );
    		REAmpDecibelMinusInf = new pcrecpp::RE( RE_AMP_DECIBEL_MINUS_INF, REOpts );
    	}
    
    	std::string u;
    
    	if( REAmpFactor->FullMatch( s, &u ) ) {
    		return StringToDouble( u );
    	}
    
    	if( REAmpDecibel->FullMatch( s, &u ) ) {
    		return db10_to_ratio( StringToDouble( u ) );
    	}
    
    	if( REAmpDecibelMinusInf->FullMatch( s ) ) {
    		return 0;
    	}
    
    	ITA_EXCEPT1( INVALID_PARAMETER, "Invalid amplification factor specification" );
    	return 0;
    }
    
    double str_to_amp_ratio_db20( const std::string& s ) {
    	if( !REAmpFactor ) {
    		// Regul�re Ausdr�cke bei erster Benutzung erzeugen
    		REAmpFactor = new pcrecpp::RE( RE_AMP_FACTOR, REOpts );
    		REAmpDecibel = new pcrecpp::RE( RE_AMP_DECIBEL, REOpts );
    		REAmpDecibelMinusInf = new pcrecpp::RE( RE_AMP_DECIBEL_MINUS_INF, REOpts );
    	}
    
    	std::string u;
    
    	if( REAmpFactor->FullMatch( s, &u ) ) {
    		return StringToDouble( u );
    	}
    
    	if( REAmpDecibel->FullMatch( s, &u ) ) {
    		return db20_to_ratio( StringToDouble( u ) );
    	}
    
    	if( REAmpDecibelMinusInf->FullMatch( s ) ) {
    		return 0;
    	}
    
    	ITA_EXCEPT1( INVALID_PARAMETER, "Invalid amplification factor specification" );
    	return 0;
    }
    
    std::string timeToString( const double dSeconds )
    {
    #ifdef WIN32
    	// ITAHPT Implementierung benutzten
    	return convertTimeToHumanReadableString( dSeconds );
    #else
    	// Kein ITAHPT unter Linux, deshalb Code kopiert:
    	char buf[255];
    
    	if (dSeconds < 1e-12) { // Kleiner als 1 fs -> as
    		sprintf(buf, "%0.3f as", dSeconds * 1e18);
    		return std::string(buf);
    	}
    
    	if (dSeconds < 1e-12) { // Kleiner als 1 ps -> fs
    		sprintf(buf, "%0.3f fs", dSeconds*1e15);
    		return std::string(buf);
    	}
    
    	if (dSeconds < 1e-9) { // Kleiner als 1 ns -> ps
    		sprintf(buf, "%0.3f ps", dSeconds*1e12);
    		return std::string(buf);
    	}
    
    	if (dSeconds < 1e-6) { // Kleiner als 1 us -> ns
    		sprintf(buf, "%0.3f ns", dSeconds*1e9);
    		return std::string(buf);
    	}
    
    	if (dSeconds < 1e-3) { // Kleiner als 1 ms -> us
    		sprintf(buf, "%0.3f us", dSeconds*1e6);
    		return std::string(buf);
    	}
    
    	if (dSeconds < 1e0) { // Kleiner als 1 s -> ms
    		sprintf(buf, "%0.3f ms", dSeconds*1e3);
    		return std::string(buf);
    	}
    
    	if (dSeconds < 60.0f) {
    		sprintf(buf, "%0.1f s ", dSeconds);
    		return std::string(buf);
    	}
    
    	/* Da geht noch mehr ...
    	if (dSeconds < 60.0f*60.0f) {
    	sprintf(buf, "%i min %0.1f s ", (int) dSeconds, fmodf((float) dSeconds, 60.0f));
    	return std::string(buf);
    	}
    	*/
    
    	sprintf(buf, "%i min %0.1f s ", (int) dSeconds, fmodf((float) dSeconds, 60.0f));
    	return std::string( buf );
    #endif // WIN32
    }
    
    std::string SubstituteMacro( const std::string& sInput, const std::string& sMacroName, const std::string& sMacroValue )
    {
    	std::string sOutput( sInput );
    
    	size_t pos = 0;
    	if( ( pos = sOutput.find( sMacroName, pos ) ) != std::string::npos ) {
    		// $(sMacroName) -> sMacroValue
    		assert( pos >= 2 && pos < sOutput.length() );
    		sOutput = sInput.substr( 0, pos - 2 ) + sMacroValue + sInput.substr( pos + sMacroName.length() + 1, sInput.length() - 1 );
    	}
    
    	return sOutput;
    }