libzypp  17.14.0
IniParser.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 #include <sstream>
14 
15 #include "zypp/base/Logger.h"
16 #include "zypp/base/String.h"
17 #include "zypp/base/IOStream.h"
19 
21 #include "zypp/parser/IniParser.h"
22 #include "zypp/ProgressData.h"
23 
24 using std::endl;
25 
27 namespace zypp
28 {
29 
30 namespace parser
31 {
32 
33  namespace {
34  inline const std::string & keyGarbage()
35  {
36  static const std::string & _val( ":/?|,\\" );
37  return _val;
38  }
39  } //namespace
40 
42 //
43 // METHOD NAME : IniParser::IniParser
44 // METHOD TYPE : Ctor
45 //
47  : _line_nr(0)
48 {}
49 
51 //
52 // METHOD NAME : IniParser::~IniParser
53 // METHOD TYPE : Dtor
54 //
56 {}
57 
59 {}
60 
61 void IniParser::consume( const std::string &section, const std::string &key, const std::string &value )
62 {}
63 
64 void IniParser::consume( const std::string &section )
65 {}
66 
68 {}
69 
70 void IniParser::garbageLine( const std::string &section, const std::string &line )
71 {
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());
75 }
76 
78 //
79 // METHOD NAME : IniParser::parse
80 // METHOD TYPE : void
81 //
82 void IniParser::parse( const InputStream & input_r, const ProgressData::ReceiverFnc & progress )
83 {
84  MIL << "Start parsing " << input_r << endl;
85  _inputname = input_r.name();
86  beginParse();
87 
88  ProgressData ticks( makeProgressData( input_r ) );
89  ticks.sendTo(progress);
90  ticks.toMin();
91 
92  iostr::EachLine line( input_r );
93  for ( ; line; line.next() )
94  {
95  std::string trimmed = str::trim(*line);
96 
97  if (trimmed.empty() || trimmed[0] == ';' || trimmed[0] == '#')
98  continue ; /* Comment lines */
99 
100  if (trimmed[0] == '[')
101  {
102  std::string::size_type pos = trimmed.rfind(']');
103  if ( pos != std::string::npos )
104  {
105  std::string section = trimmed.substr(1, pos-1);
106  consume(section);
107  section.swap(_current_section);
108  }
109  else
110  {
111  _line_nr = line.lineNo();
112  garbageLine( _current_section, trimmed );
113  }
114  continue;
115  }
116 
117  std::string::size_type pos = trimmed.find('=');
118  if ( pos == std::string::npos || trimmed.find_first_of( keyGarbage() ) < pos )
119  {
120  _line_nr = line.lineNo();
121  garbageLine( _current_section, trimmed ); // may or may not throw
122  }
123  else
124  {
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);
128  }
129 
130  // set progress and allow cancel
131  if ( ! ticks.set( input_r.stream().tellg() ) )
132  ZYPP_THROW(AbortRequestException());
133  }
134  ticks.toMax();
135 
136  endParse();
137  _inputname.clear();
138  MIL << "Done parsing " << input_r << endl;
139 }
140 
142 } // namespace parser
145 } // namespace zypp