#include <iostream>
#include <sstream>
-#include <boost/regex.hpp>
-
#include "zypp/base/Logger.h"
#include "zypp/base/String.h"
#include "zypp/base/IOStream.h"
+#include "zypp/base/UserRequestException.h"
+#include "zypp/parser/ParseException.h"
#include "zypp/parser/IniParser.h"
#include "zypp/ProgressData.h"
namespace parser
{ /////////////////////////////////////////////////////////////////
+ namespace {
+ inline const std::string & keyGarbage()
+ {
+ static const std::string & _val( ",|/\\" );
+ return _val;
+ }
+ } //namespace
+
///////////////////////////////////////////////////////////////////
//
// METHOD NAME : IniParser::IniParser
void IniParser::endParse()
{}
-void dumpRegexpResults( const boost::smatch &what )
+void IniParser::garbageLine( const std::string §ion, const std::string &line )
{
- for ( unsigned int k=0; k < what.size(); k++)
- {
- DBG << "[match "<< k << "] [" << what[k] << "]" << std::endl;
- }
+ std::string msg = str::form("%s: Section [%s]: Line %d contains garbage (no '=' or '%s' in key)",
+ _inputname.c_str(), section.c_str(), _line_nr, keyGarbage().c_str());
+ ZYPP_THROW(ParseException(msg));
}
///////////////////////////////////////////////////////////////////
// METHOD NAME : IniParser::parse
// METHOD TYPE : void
//
-void IniParser::parse( const InputStream & input_r )
+void IniParser::parse( const InputStream & input_r, const ProgressData::ReceiverFnc & progress )
{
- boost::regex rxSection("^\\[(.+)\\]$");
- boost::regex rxKeyValue("^(.+)[[:space:]]*=[[:space:]]*(.+)$");
-
MIL << "Start parsing " << input_r << endl;
_inputname = input_r.name();
beginParse();
ProgressData ticks( makeProgressData( input_r ) );
+ ticks.sendTo(progress);
ticks.toMin();
iostr::EachLine line( input_r );
for ( ; line; line.next() )
{
std::string trimmed = str::trim(*line);
- const char *where = trimmed.c_str(); /* Skip leading spaces */
- if (*where==';' || *where=='#' || *where==0)
+
+ if (trimmed.empty() || trimmed[0] == ';' || trimmed[0] == '#')
continue ; /* Comment lines */
- else
+
+ if (trimmed[0] == '[')
{
- if (*where=='[' )
+ std::string::size_type pos = trimmed.find(']');
+ if ( pos != std::string::npos )
{
- boost::smatch what;
- if(boost::regex_match(trimmed, what, rxSection, boost::match_extra))
- {
- //dumpRegexpResults(what);
- std::string section = what[1];
- consume(section);
- section.swap(_current_section);
- }
+ std::string section = trimmed.substr(1, pos-1);
+ consume(section);
+ section.swap(_current_section);
}
else
{
- boost::smatch what;
- if(boost::regex_match(trimmed, what, rxKeyValue, boost::match_extra))
- {
- //dumpRegexpResults(what);
- consume( _current_section, what[1], what[2] );
- }
+ _line_nr = line.lineNo();
+ garbageLine( _current_section, trimmed );
}
+ continue;
+ }
+
+ std::string::size_type pos = trimmed.find('=');
+ if ( pos == std::string::npos || trimmed.find_first_of( keyGarbage() ) < pos )
+ {
+ _line_nr = line.lineNo();
+ garbageLine( _current_section, trimmed ); // may or may not throw
}
- ticks.set( input_r.stream().tellg() );
+ else
+ {
+ std::string key = str::rtrim(trimmed.substr(0, pos));
+ std::string value = str::ltrim(trimmed.substr(pos+1));
+ consume( _current_section, key, value);
+ }
+
+ // set progress and allow cancel
+ if ( ! ticks.set( input_r.stream().tellg() ) )
+ ZYPP_THROW(AbortRequestException());
}
ticks.toMax();