I dunno that this makes it any easier...
I tried splitting up the sources to speed up some compiling... but it didn't help. I dunno that it's more readable this way. I'm checkpointing this just in case.
This commit is contained in:
73
ConfigFile.h
73
ConfigFile.h
@ -3,8 +3,6 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <optional>
|
||||
|
||||
namespace Config::inline Hydrogen {}
|
||||
|
||||
@ -20,77 +18,10 @@ namespace Config::Hydrogen ::detail:: ConfigFile_m
|
||||
private:
|
||||
std::map< std::string, std::string > config;
|
||||
|
||||
struct EoF {};
|
||||
|
||||
std::string
|
||||
readLine( std::istream &input )
|
||||
{
|
||||
std::string rv;
|
||||
std::getline( input, rv );
|
||||
if( not input ) throw EoF{};
|
||||
|
||||
// SStrip trailing '#' comments...
|
||||
const auto endComment= std::find( begin( rv ), end( rv ), '#' );
|
||||
rv.erase( endComment, end( rv ) );
|
||||
return rv;
|
||||
}
|
||||
|
||||
std::string
|
||||
trimWhitespace( std::string s )
|
||||
{
|
||||
// Trim from the front
|
||||
std::reverse( begin( s ), end( s ) );
|
||||
while( not s.empty() and s.back() == ' ' ) s.pop_back();
|
||||
|
||||
// Trim from the back
|
||||
std::reverse( begin( s ), end( s ) );
|
||||
while( not s.empty() and s.back() == ' ' ) s.pop_back();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
auto
|
||||
parseLine( const std::string &line )
|
||||
{
|
||||
const auto split= std::find( begin( line ), end( line ), '=' );
|
||||
if( split == end( line ) ) throw std::runtime_error{ "Unable to parse configuration line: `" + line + "`" };
|
||||
const auto key= trimWhitespace( { begin( line ), split } );
|
||||
const auto value= trimWhitespace( { split + 1, end( line ) } );
|
||||
|
||||
return std::tuple{ key, value };
|
||||
}
|
||||
|
||||
public:
|
||||
explicit
|
||||
ConfigFile( std::istream &&input, const std::map< std::string, std::string > &schema )
|
||||
{
|
||||
config= schema;
|
||||
while( input )
|
||||
try
|
||||
{
|
||||
const std::string line= trimWhitespace( readLine( input ) );
|
||||
if( line.empty() ) continue; // Skip blank lines.
|
||||
|
||||
const auto [ key, value ]= parseLine( line );
|
||||
explicit ConfigFile( std::istream &&input, const std::map< std::string, std::string > &schema );
|
||||
|
||||
if( not schema.contains( key ) )
|
||||
{
|
||||
std::cerr << "Unrecognized key in config file: `" << key << "`" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
config.at( key )= value;
|
||||
}
|
||||
catch( const EoF & ) { break; }
|
||||
|
||||
std::cerr << "Configuration parsed:" << std::endl;
|
||||
for( const auto &[ key, value ]: config )
|
||||
{
|
||||
std::cerr << key << " = " << value << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::string get( const std::string &name ) const { return config.at( name ); }
|
||||
std::string get( const std::string &name ) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user