7 #include <zypp/base/Logger.h>
8 #include <zypp/base/Exception.h>
9 #include <zypp/base/String.h>
10 #include <zypp/base/IOStream.h>
11 #include <zypp/base/PtrTypes.h>
13 #include <zypp/CapFactory.h>
14 #include <zypp/CapSet.h>
19 // work around flaw in y2logview
21 void printOnHack( const _Tp & obj )
26 ///////////////////////////////////////////////////////////////////
32 : _begin( time(NULL) )
34 USR << "START MEASURE..." << endl;
38 USR << "DURATION: " << (time(NULL)-_begin) << " sec." << endl;
42 ///////////////////////////////////////////////////////////////////
43 // Print stream status
44 ostream & operator<<( ostream & str, const istream & obj ) {
46 << (obj.good() ? 'g' : '_')
47 << (obj.eof() ? 'e' : '_')
48 << (obj.fail() ? 'F' : '_')
49 << (obj.bad() ? 'B' : '_');
52 ///////////////////////////////////////////////////////////////////
53 // Fits forEachLine. A simple 'do' function
54 void collect( const std::string & linre_r )
56 DBG << linre_r << endl;
58 ///////////////////////////////////////////////////////////////////
59 // Fits forEachLine. A simple 'do' functor counting lines as base.
61 Line processing is prepared by providing 'virtual void doConsume(std::string)'.
62 That's what a derived Collector will overload.
64 struct Collector : public std::unary_function<const std::string &, bool>
72 virtual void doConsume( const std::string & line_r )
74 bool operator()( const std::string & line_r )
77 if ( ! (_lineNo % 10000) )
78 DBG << "Got " << _lineNo << " lines..." << endl;
83 ///////////////////////////////////////////////////////////////////
84 // Fits forEachLine. An impatient collector ;)
85 struct ImpatientCollector : public Collector
87 virtual void doConsume( const std::string & line_r )
89 if ( _lineNo == 1234 )
90 ZYPP_THROW( Exception("takes to long") );
93 ///////////////////////////////////////////////////////////////////
94 // Fits forEachLine. Almost usefull collector.
96 Note that it's still a functor 'void operator()( const std::string & )'.
98 On every invocation the string is parsed into a Capability, and the
99 Capability is stored in a CapSet.
101 Exceptions building the Capability are caught and collected in a
102 Failure list. It's a matter of taste whether to immediately abort,
103 or to parse to the end check for collected errors then. Room for
106 see enhacedCollectorUsage().
108 struct EnhacedCollector : public Collector
110 // Stores line number, original string and Exception
116 Failure( unsigned lineNo_r,
117 const std::string & line_r, const Exception & excpt_r )
118 : _lineNo( lineNo_r ), _line( line_r ), _excpt( excpt_r )
122 typedef std::list<Failure> FailedList;
127 FailedList _failures;
134 void makeCap( const string & line_r )
136 ++_capLines; // count attempts
139 // bulid Package deps.
140 _caps.insert( _factory.parse( ResTraits<Package>::kind, line_r ) );
142 catch( Exception & excpt_r )
144 _failures.push_back( Failure(_lineNo, line_r, excpt_r) );
148 virtual void doConsume( const std::string & line_r )
155 ostream & operator<<( ostream & str, const EnhacedCollector::Failure & obj )
157 return str << str::form( "[%u] \"%s\" ==> %s",
160 obj._excpt.asString().c_str() );
163 // Print EnhacedCollector stats
164 ostream & operator<<( ostream & str, const EnhacedCollector & obj )
166 str << "Lines parsed : " << obj._lineNo << endl;
167 str << "Cap lines : " << obj._capLines << endl;
168 str << "Capabilites : " << obj._caps.size() << endl;
169 str << "Parse errors : " << obj._failures.size() << endl;
170 if ( obj._failures.size() )
172 copy( obj._failures.begin(), obj._failures.end(),
173 ostream_iterator<EnhacedCollector::Failure>(ERR,"\n") );
174 //-something-we-should-not-do-unless-....---------^^^
179 ///////////////////////////////////////////////////////////////////
182 Within a packages file, not every line defines a Capability. So
183 EnhacedCollector is refined to turn Capability collection on and
184 off, as appropriate. A dumb version simply storing all Capabilities
185 defined somewhere in the packages file.
187 struct PackageParseCollector : public EnhacedCollector
189 static std::string _rxStrDeps;
190 static str::regex _rxDepOn;
191 static str::regex _rxDepOff;
196 PackageParseCollector()
200 bool matches( const string & line_r, const str::regex & rx_r )
202 return str::regex_match( line_r.begin(), line_r.end(), rx_r );
205 virtual void doConsume( const std::string & line_r )
209 if ( matches( line_r, _rxDepOff ) )
215 EnhacedCollector::doConsume( line_r );
218 else if ( matches( line_r, _rxDepOn ) )
225 std::string PackageParseCollector::_rxStrDeps( "(Req|Prq|Prv|Con|Obs)" );
226 str::regex PackageParseCollector::_rxDepOn ( str::form( "\\+%s:", _rxStrDeps.c_str() ) );
227 str::regex PackageParseCollector::_rxDepOff( str::form( "-%s:", _rxStrDeps.c_str() ) );
229 /******************************************************************
231 ** FUNCTION NAME : enhacedCollectorUsage
234 void enhacedCollectorUsage()
236 // EnhacedCollector: Simply collect strings which are expected to
237 // be Capabilities. Error handling is delayed by collecting failures.
238 EnhacedCollector collector;
240 collector( "foo baa kaa" );
241 collector( "/bin/sh" );
242 collector( "/bin/sh" );
243 collector( "/bin/sh" );
244 collector( "/bin/sh" );
246 MIL << collector << endl;
247 MIL << "Capabilities found:" << endl;
248 for_each( collector._caps.begin(), collector._caps.end(),
249 printOnHack<Capability> );
252 /******************************************************************
254 ** FUNCTION NAME : main
255 ** FUNCTION TYPE : int
257 int main( int argc, char * argv[] )
263 cerr << "Usage: Example.createCapabilities <packages file>" << endl;
266 string file( argv[0] );
268 INT << "===[START]==========================================" << endl;
270 // dump PackageParseCollector: open the file, and build Capabilities
271 // from each appropriate line. Collecting failures.
273 ifstream str( file.c_str() );
274 (str?DBG:ERR) << file << ": " << str << endl;
275 shared_ptr<Measure> duration( new Measure );
277 PackageParseCollector datacollect;
280 iostr::forEachLine( str, datacollect );
282 catch ( Exception & excpt_r )
284 // Note: Exceptions building a Capability are caught. So this is
285 // something different. Maybe a bored ImpatientCollector.
286 ZYPP_CAUGHT( excpt_r );
287 ERR << "Parse error at line " << datacollect._lineNo << ": " << excpt_r << endl;
292 DBG << file << ": " << str << endl;
294 MIL << datacollect << endl;
295 MIL << "Capabilities found:" << endl;
296 for_each( datacollect._caps.begin(), datacollect._caps.end(),
297 printOnHack<Capability> );
299 INT << "===[END]============================================" << endl;