Imported Upstream version 14.30.0
[platform/upstream/libzypp.git] / zypp / parser / IniParser.cc
index 3aa6b89..cdead1e 100644 (file)
 #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"
 
@@ -30,6 +30,14 @@ namespace zypp
 namespace parser
 { /////////////////////////////////////////////////////////////////
 
+  namespace {
+    inline const std::string & keyGarbage()
+    {
+      static const std::string & _val( ",|/\\" );
+      return _val;
+    }
+  } //namespace
+
 ///////////////////////////////////////////////////////////////////
 //
 //     METHOD NAME : IniParser::IniParser
@@ -59,12 +67,11 @@ void IniParser::consume( const std::string &section )
 void IniParser::endParse()
 {}
 
-void dumpRegexpResults( const boost::smatch &what )
+void IniParser::garbageLine( const std::string &section, 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));
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -72,49 +79,57 @@ void dumpRegexpResults( const boost::smatch &what )
 //     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();