Fix Werrors with GCC-14.1.0
[platform/upstream/libzypp.git] / zypp / parser / ProductFileReader.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/parser/ProductFileReader.cc
10  *
11 */
12 #include <iostream>
13 #include <zypp/base/Logger.h>
14 #include <zypp/base/Exception.h>
15 #include <zypp/base/Functional.h>
16
17 #include <zypp/PathInfo.h>
18
19 #include <zypp/parser/ProductFileReader.h>
20 #include <zypp/parser/xml/ParseDef.h>
21 #include <zypp/parser/xml/ParseDefConsume.h>
22 #include <zypp/parser/xml/Reader.h>
23
24 using std::endl;
25
26 ///////////////////////////////////////////////////////////////////
27 namespace zypp
28 { /////////////////////////////////////////////////////////////////
29   ///////////////////////////////////////////////////////////////////
30   namespace parser
31   { /////////////////////////////////////////////////////////////////
32
33     /////////////////////////////////////////////////////////////////
34     //
35     // class ProductFileData::Upgrade
36     //
37     /////////////////////////////////////////////////////////////////
38
39     struct ProductFileData::Upgrade::Impl
40     {
41       std::string                 _name;
42       std::string                 _summary;
43       std::string                 _repository;
44       std::string                 _product;
45       DefaultIntegral<bool,false> _notify;
46       std::string                 _status;
47     };
48
49     ProductFileData::Upgrade::Upgrade( Impl * allocated_r )
50       : _pimpl( allocated_r ? allocated_r : new Impl )
51     {}
52
53     std::string ProductFileData::Upgrade::name()       const { return _pimpl->_name; }
54     std::string ProductFileData::Upgrade::summary()    const { return _pimpl->_summary; }
55     std::string ProductFileData::Upgrade::repository() const { return _pimpl->_repository; }
56     std::string ProductFileData::Upgrade::product()    const { return _pimpl->_product; }
57     bool        ProductFileData::Upgrade::notify()     const { return _pimpl->_notify; }
58     std::string ProductFileData::Upgrade::status()     const { return _pimpl->_status; }
59
60     /////////////////////////////////////////////////////////////////
61     //
62     // class ProductFileData
63     //
64     /////////////////////////////////////////////////////////////////
65
66     struct ProductFileData::Impl
67     {
68       IdString    _vendor;
69       IdString    _name;
70       Edition     _edition;
71       Arch        _arch;
72
73       std::string _shortName;
74       std::string _summary;
75
76       std::string _productline;
77       std::string _registerTarget;
78       std::string _registerRelease;
79       std::string _registerFlavor;
80
81       std::string _updaterepokey;
82
83       Upgrades    _upgrades;
84     };
85
86     ProductFileData::ProductFileData( Impl * allocated_r )
87       : _pimpl( allocated_r ? allocated_r : new Impl )
88     {}
89
90     IdString    ProductFileData::vendor()  const { return _pimpl->_vendor; }
91     IdString    ProductFileData::name()    const { return _pimpl->_name; }
92     Edition     ProductFileData::edition() const { return _pimpl->_edition; }
93     Arch        ProductFileData::arch()    const { return _pimpl->_arch; }
94
95     std::string ProductFileData::shortName()    const { return _pimpl->_shortName; }
96     std::string ProductFileData::summary()      const { return _pimpl->_summary; }
97
98     std::string ProductFileData::productline()     const { return _pimpl->_productline; }
99     std::string ProductFileData::registerTarget()  const { return _pimpl->_registerTarget; }
100     std::string ProductFileData::registerRelease() const { return _pimpl->_registerRelease; }
101     std::string ProductFileData::registerFlavor()  const { return _pimpl->_registerFlavor; }
102
103     std::string ProductFileData::updaterepokey() const { return _pimpl->_updaterepokey; }
104
105     const ProductFileData::Upgrades & ProductFileData::upgrades() const { return _pimpl->_upgrades; }
106
107     std::ostream & operator<<( std::ostream & str, const ProductFileData & obj )
108     {
109       str << str::form( "|product|%s|%s|%s|%s|",
110                         obj.name().c_str(),
111                         obj.edition().c_str(),
112                         obj.arch().c_str(),
113                         obj.vendor().c_str() );
114       if ( ! obj.upgrades().empty() )
115       {
116         for_( it, obj.upgrades().begin(), obj.upgrades().end() )
117           str << endl << "    " << *it;
118       }
119       return str;
120     }
121
122     std::ostream & operator<<( std::ostream & str, const ProductFileData::Upgrade & obj )
123     {
124       str << str::form( "|upgrade|%s|%s|%s|%s|%s|",
125                         obj.name().c_str(),
126                         obj.repository().c_str(),
127                         obj.product().c_str(),
128                         obj.status().c_str(),
129                         (obj.notify() ? "notify" : "noNotify") );
130       return str;
131     }
132     /////////////////////////////////////////////////////////////////
133     //
134     // class ProductFileReader
135     //
136     /////////////////////////////////////////////////////////////////
137
138     struct ProductNode : public xml::ParseDef
139     {
140       ProductNode( ProductFileData::Impl & pdata_r )
141         : ParseDef( "product", MANDTAORY )
142         , _pdata( pdata_r )
143       {
144         (*this)
145             ("vendor",        OPTIONAL,   xml::parseDefAssign( _pdata._vendor ) )
146             ("name",          MANDTAORY,  xml::parseDefAssign( _pdata._name ) )
147             ("version",       MANDTAORY,  xml::parseDefAssign( _version ) )
148             ("release",       MANDTAORY,  xml::parseDefAssign( _release ) )
149             ("arch",          MANDTAORY,  xml::parseDefAssign( _pdata._arch ) )
150             ("shortsummary",  OPTIONAL,   xml::parseDefAssign( _pdata._shortName ) )
151             ("summary",       MULTIPLE_OPTIONAL, xml::parseDefAssign( _ttext )( "lang", _tlocale )
152                                           >>bind( &ProductNode::doneLocalizedDefault, this, _1, boost::ref(_pdata._summary) ))
153             ("productline",   OPTIONAL,   xml::parseDefAssign( _pdata._productline ) )
154             ("register",      OPTIONAL)
155             ("updaterepokey", OPTIONAL,   xml::parseDefAssign( _pdata._updaterepokey ) )
156             ("upgrades",      OPTIONAL)
157             ;
158
159         (*this)["register"]
160             ("target",        OPTIONAL,   xml::parseDefAssign( _pdata._registerTarget ) )
161             ("release",       OPTIONAL,   xml::parseDefAssign( _pdata._registerRelease ) )
162             ("flavor",        OPTIONAL,   xml::parseDefAssign( _pdata._registerFlavor ) )
163             ;
164
165         (*this)["upgrades"]
166             ("upgrade",       MULTIPLE_OPTIONAL, xml::parseDefAssign()
167                                                  >> bind( &ProductNode::doneUpgrade, this, _1 ))
168             ;
169
170         (*this)["upgrades"]["upgrade"]
171             ("name",          OPTIONAL,   xml::parseDefAssign( _upgrade._name ) )
172             ("summary",       OPTIONAL,   xml::parseDefAssign( _upgrade._summary ) )
173             ("repository",    OPTIONAL,   xml::parseDefAssign( _upgrade._repository ) )
174             ("product",       OPTIONAL,   xml::parseDefAssign( _upgrade._product ) )
175             ("notify",        OPTIONAL,   xml::parseDefAssign( _upgrade._notify ) )
176             ("status",        OPTIONAL,   xml::parseDefAssign( _upgrade._status ) )
177             ;
178
179         // </product> callback to build edition.
180         setConsumer( xml::parseDefAssign() >> bind( &ProductNode::done, this, _1 ) );
181         // xml::ParseDef::_debug = true;
182       }
183
184       /** collect _upgrade */
185       void doneUpgrade( const xml::Node & _node )
186       {
187         ProductFileData::Upgrade cdata( new ProductFileData::Upgrade::Impl( _upgrade ) );
188         _pdata._upgrades.push_back( cdata );
189         _upgrade = ProductFileData::Upgrade::Impl();
190       }
191       /** collect localized data */
192       void doneLocalizedDefault( const xml::Node & _node, std::string & store_r )
193       {
194         // take 1st or default
195         if ( store_r.empty() || _tlocale.empty() )
196           store_r = _ttext;
197       }
198
199       /** finaly */
200       void done( const xml::Node & _node )
201       {
202         _pdata._edition = Edition( _version, _release );
203       }
204
205       private:
206         ProductFileData::Impl & _pdata;
207
208         std::string             _version;
209         std::string             _release;
210
211         std::string             _ttext;
212         std::string             _tlocale;
213
214         ProductFileData::Upgrade::Impl _upgrade;
215     };
216
217     bool ProductFileReader::parse( const InputStream & input_r ) const
218     {
219       MIL << "+++" << input_r << endl;
220       bool ret = true;
221
222       ProductFileData::Impl * pdataImpl = 0;
223       ProductFileData pdata( (pdataImpl = new ProductFileData::Impl) );
224
225       try
226       {
227         xml::Reader reader( input_r );
228         ProductNode rootNode( *pdataImpl );
229         rootNode.take( reader );
230
231       }
232       catch ( const Exception & err )
233       {
234         // parse error
235         ERR << err << endl;
236         ERR << "---" << ret << " - " << input_r << endl;
237         return ret;
238       }
239
240       if ( _consumer )
241       {
242         ret = _consumer( pdata );
243       }
244
245       MIL << "---" << ret << " - " << input_r << endl;
246       return ret;
247     }
248
249     /////////////////////////////////////////////////////////////////
250
251     bool ProductFileReader::scanDir( const Consumer & consumer_r, const Pathname & dir_r )
252     {
253       std::list<Pathname> retlist;
254       int res = filesystem::readdir( retlist, dir_r, /*dots*/false );
255       if ( res != 0 )
256       {
257         WAR << "scanDir " << dir_r << " failed (" << res << ")" << endl;
258         return true;
259       }
260
261       ProductFileReader reader( consumer_r );
262       for_( it, retlist.begin(), retlist.end() )
263       {
264         if ( PathInfo( *it, PathInfo::LSTAT ).isFile() && ! reader.parse( *it ) )
265         {
266           return false; // consumer_r request to stop parsing.
267         }
268       }
269       return true;
270     }
271
272     ProductFileData ProductFileReader::scanFile( const Pathname & file_r )
273     {
274       if ( ! PathInfo( file_r ).isFile() )
275       {
276         WAR << "scanFile " << PathInfo( file_r ) << " is not a file." << endl;
277         return ProductFileData();
278       }
279
280       ProductFileData ret;
281       ProductFileReader reader( functor::getFirst( ret ), file_r );
282       return ret;
283    }
284
285     /////////////////////////////////////////////////////////////////
286   } // namespace parser
287   ///////////////////////////////////////////////////////////////////
288   /////////////////////////////////////////////////////////////////
289 } // namespace zypp
290 ///////////////////////////////////////////////////////////////////