1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/parser/IniParser.cc
15 #include "zypp/base/Logger.h"
16 #include "zypp/base/String.h"
17 #include "zypp/base/IOStream.h"
18 #include "zypp/base/UserRequestException.h"
20 #include "zypp/parser/ParseException.h"
21 #include "zypp/parser/IniParser.h"
22 #include "zypp/ProgressData.h"
26 ///////////////////////////////////////////////////////////////////
28 { /////////////////////////////////////////////////////////////////
29 ///////////////////////////////////////////////////////////////////
31 { /////////////////////////////////////////////////////////////////
34 inline const std::string & keyGarbage()
36 static const std::string & _val( ",|/\\" );
41 ///////////////////////////////////////////////////////////////////
43 // METHOD NAME : IniParser::IniParser
46 IniParser::IniParser()
50 ///////////////////////////////////////////////////////////////////
52 // METHOD NAME : IniParser::~IniParser
55 IniParser::~IniParser()
58 void IniParser::beginParse()
61 void IniParser::consume( const std::string §ion, const std::string &key, const std::string &value )
64 void IniParser::consume( const std::string §ion )
67 void IniParser::endParse()
70 void IniParser::garbageLine( const std::string §ion, const std::string &line )
72 std::string msg = str::form("%s: Section [%s]: Line %d contains garbage (no '=' or '%s' in key)",
73 _inputname.c_str(), section.c_str(), _line_nr, keyGarbage().c_str());
74 ZYPP_THROW(ParseException(msg));
77 ///////////////////////////////////////////////////////////////////
79 // METHOD NAME : IniParser::parse
82 void IniParser::parse( const InputStream & input_r, const ProgressData::ReceiverFnc & progress )
84 MIL << "Start parsing " << input_r << endl;
85 _inputname = input_r.name();
88 ProgressData ticks( makeProgressData( input_r ) );
89 ticks.sendTo(progress);
92 iostr::EachLine line( input_r );
93 for ( ; line; line.next() )
95 std::string trimmed = str::trim(*line);
97 if (trimmed.empty() || trimmed[0] == ';' || trimmed[0] == '#')
98 continue ; /* Comment lines */
100 if (trimmed[0] == '[')
102 std::string::size_type pos = trimmed.find(']');
103 if ( pos != std::string::npos )
105 std::string section = trimmed.substr(1, pos-1);
107 section.swap(_current_section);
111 _line_nr = line.lineNo();
112 garbageLine( _current_section, trimmed );
117 std::string::size_type pos = trimmed.find('=');
118 if ( pos == std::string::npos || trimmed.find_first_of( keyGarbage() ) < pos )
120 _line_nr = line.lineNo();
121 garbageLine( _current_section, trimmed ); // may or may not throw
125 std::string key = str::rtrim(trimmed.substr(0, pos));
126 std::string value = str::ltrim(trimmed.substr(pos+1));
127 consume( _current_section, key, value);
130 // set progress and allow cancel
131 if ( ! ticks.set( input_r.stream().tellg() ) )
132 ZYPP_THROW(AbortRequestException());
138 MIL << "Done parsing " << input_r << endl;
141 /////////////////////////////////////////////////////////////////
142 } // namespace parser
143 ///////////////////////////////////////////////////////////////////
144 /////////////////////////////////////////////////////////////////
146 ///////////////////////////////////////////////////////////////////