- added helper struct NVRA
[platform/upstream/libzypp.git] / devel / devel.ma / Parse.cc
1 //http://www.boost.org/libs/libraries.htm
2 #include <iostream>
3 #include <list>
4 #include <string>
5
6 #include <zypp/base/Logger.h>
7 #include <zypp/base/Exception.h>
8 #include <zypp/base/PtrTypes.h>
9 #include <zypp/parser/tagfile/Tags.h>
10
11 #include <zypp/NVRA.h>
12
13 ///////////////////////////////////////////////////////////////////
14 namespace zypp
15 { /////////////////////////////////////////////////////////////////
16   ///////////////////////////////////////////////////////////////////
17   namespace parser
18   { /////////////////////////////////////////////////////////////////
19     ///////////////////////////////////////////////////////////////////
20     namespace tagfile
21     { /////////////////////////////////////////////////////////////////
22
23       void echoOn( std::ostream & str,
24                    iterator_t first, const iterator_t last,
25                    const char* s = "" )
26       {
27         //return;
28         str << first.get_position() << last.get_position();
29         str << s << ">>";
30         while ( first != last )
31           str << *first++;
32         str << "<< " << std::endl;
33       }
34
35       void echo( iterator_t first, const iterator_t last, const char* s = "" )
36       {
37         echoOn( DBG, first, last, s );
38       }
39       void xecho( const char * first, const char *const last, const char* s = "" )
40       {
41         DBG << ">>" << std::string(first,last) << "<< " << std::endl;
42       }
43       void mecho( iterator_t first, const iterator_t last, const char* s = "" )
44       {
45         echoOn( MIL, first, last, s );
46       }
47
48       /////////////////////////////////////////////////////////////////
49     } // namespace tagfile
50     ///////////////////////////////////////////////////////////////////
51     /////////////////////////////////////////////////////////////////
52   } // namespace parser
53   ///////////////////////////////////////////////////////////////////
54   /////////////////////////////////////////////////////////////////
55 } // namespace zypp
56 ///////////////////////////////////////////////////////////////////
57 ////////////////////////////////////////////////////////////////////////////
58 //
59 //  Types
60 //
61 ////////////////////////////////////////////////////////////////////////////
62 using std::endl;
63 using std::list;
64 using std::string;
65 using namespace zypp;
66 using namespace zypp::parser::tagfile;
67 typedef scanner<iterator_t>            scanner_t;
68 typedef rule<scanner_t>                rule_t;
69 ////////////////////////////////////////////////////////////////////////////
70 //
71 //  Just for the stats
72 //
73 ////////////////////////////////////////////////////////////////////////////
74 struct Measure
75 {
76   time_t _begin;
77   Measure()
78   : _begin( time(NULL) )
79   {
80     USR << "START MEASURE..." << endl;
81   }
82   ~Measure()
83   {
84     USR << "DURATION: " << (time(NULL)-_begin) << " sec." << endl;
85   }
86 };
87 ////////////////////////////////////////////////////////////////////////////
88
89 NVRA parseNVRA( const std::string & value )
90 {
91   std::string n;
92   std::string v;
93   std::string r;
94   std::string a;
95   parse_info<> info = parse( value.c_str(),
96
97        lexeme_d[(+~space_p)]                    [assign_a(n)]
98        >> lexeme_d[(+(~space_p & ~ch_p('-')))]  [assign_a(v)]
99        >> lexeme_d[(+(~space_p & ~ch_p('-')))]  [assign_a(r)]
100        >> lexeme_d[(+~space_p)]                 [assign_a(a)]
101        ,
102                              space_p );
103
104   NVRA data;
105   if ( info.full )
106     {
107       data = NVRA( n, Edition(v,r), Arch(a) );
108     }
109   else
110     {
111       ERR << "parseNVRA failed on " << value << std::endl;
112     }
113   INT << data << endl;
114   return data;
115 }
116
117
118 struct PConsume
119 {
120   static bool isTag( const Tag & tag_r, const std::string & ident_r )
121   {
122     return tag_r.ident == ident_r && tag_r.ext.empty();
123   }
124   static bool isLangTag( const Tag & tag_r, const std::string & ident_r )
125   {
126     return tag_r.ident == ident_r && ! tag_r.ext.empty();
127   }
128
129   bool newPkg( const std::string & value )
130   {
131     NVRA data( parseNVRA( value ) );
132     return true;
133   }
134
135
136   PConsume & operator=( const STag & stag_r )
137   {
138     if ( isTag( stag_r.stag, "Pkg" ) )
139       {
140         newPkg( stag_r.value );
141         MIL << stag_r << endl;
142       }
143     return *this;
144   }
145   PConsume & operator=( const MTag & mtag_r )
146   {
147     return *this;
148   }
149
150   scoped_ptr<NVRA> _nvra;
151 };
152
153 struct X
154 {
155   template <typename Item>
156     struct result
157     {
158       typedef rule_t type;
159     };
160
161   template <typename Item>
162     rule_t operator<<(  const Item & stag_r ) const
163     {
164       return eps_p;//error_report_p( "neither empty nor comment" );
165     }
166 };
167 //const phoenix::function<X_impl> XX = X_impl();
168
169 ////////////////////////////////////////////////////////////////////////////
170 //
171 //  Main
172 //
173 ////////////////////////////////////////////////////////////////////////////
174 int main( int argc, char* argv[] )
175 {
176   INT << "===[START]==========================================" << endl;
177   string infile( "p" );
178   if (argc >= 2 )
179     infile = argv[1];
180
181   // Create a file iterator for this file
182   fiterator_t first(infile);
183   if (!first)
184     {
185       ERR << "Unable to open file!\n";
186       return -1;
187     }
188   // Create an EOF iterator
189   fiterator_t last = first.make_end();
190
191   // Create position iterators
192   iterator_t begin( first, last, infile );
193   iterator_t end;
194
195   // Result var
196   SingleTag stag;
197   MultiTag  mtag;
198   STag      stagData;
199   MTag      mtagData;
200
201   PConsume  consume;
202   rule_t c = eps_p;
203   rule_t a = nothing_p;
204   rule_t x = error_report_p( "abort" );
205
206   rule_t file =   end_p
207                 | ( stag //[var(consume)=arg1]
208                     >> lazy_p(var(x))
209                   | mtag [var(consume)=arg1]
210                   | ( *blank_p
211                       >> !( ch_p('#')
212                             >> *(anychar_p - eol_p)
213                           )
214                       >> (eol_p|end_p)
215                     )
216                   | error_report_p( "neither empty nor comment" )
217                   )
218                   >> file;
219
220   // Parse
221   shared_ptr<Measure> duration( new Measure );
222   parse_info<iterator_t> info
223     = parse( begin, end, file );
224   duration.reset();
225
226   // Check for fail...
227   if ( info.full )
228     USR << "Parse succeeded!\n";
229   else if ( info.hit )
230     {
231       ERR << "Parse partial!\n";
232       ERR << " at pos " << info.length << endl;
233     }
234   else
235     {
236       ERR << "Parse failed!\n";
237       ERR << " at pos " << info.length << endl;
238     }
239
240   INT << "===[END]============================================" << endl;
241   return 0;
242 }