--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/parser/tagfile/Grammar.h
+ *
+*/
+#ifndef ZYPP_PARSER_TAGFILE_GRAMMAR_H
+#define ZYPP_PARSER_TAGFILE_GRAMMAR_H
+
+#include <iosfwd>
+
+#include "zypp/parser/tagfile/Tags.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace parser
+ { /////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace tagfile
+ { /////////////////////////////////////////////////////////////////
+
+ typedef scanner<iterator_t> scanner_t;
+ typedef rule<scanner_t> rule_t;
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Closures
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ struct TagClosure : public spirit::closure<TagClosure, Tag>
+ {
+ member1 val;
+ };
+ typedef TagClosure::context_t TagVal;
+
+ struct STagClosure : public spirit::closure<STagClosure, STag>
+ {
+ member1 val;
+ };
+ typedef STagClosure::context_t STagVal;
+
+ struct MTagClosure : public spirit::closure<MTagClosure, MTag, std::string>
+ {
+ member1 val;
+ member2 expect;
+ };
+ typedef MTagClosure::context_t MTagVal;
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // SingleTag Grammar
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ struct SingleTag : public grammar<SingleTag, STagVal>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition( const SingleTag & self )
+ {
+ first =
+ (
+ line
+ = stag [bind(&STag::stag)(self.val)=arg1]
+ >> *blank_p
+ >> (!data) [bind(&STag::data)(self.val)=construct_<Range>(arg1,arg2)]
+ [bind(&STag::value)(self.val)=construct_<std::string>(arg1,arg2)]
+ >> *blank_p
+ >> (eol_p|end_p)
+ ,
+ stag
+ = ( ch_p('=')
+ >> (+alpha_p) [bind(&Tag::ident)(stag.val)=construct_<std::string>(arg1,arg2)]
+ >> !( '.'
+ >> (+alpha_p) [bind(&Tag::ext)(stag.val)=construct_<std::string>(arg1,arg2)]
+ )
+ >> ':'
+ ) [bind(&Tag::range)(stag.val)=construct_<Range>(arg1,arg2)]
+ ,
+ data
+ = +~space_p
+ >> *( +blank_p
+ >> +~space_p
+ )
+ );
+ }
+
+ subrule<0> line;
+ subrule<1,TagVal> stag;
+ subrule<2> data;
+
+ rule<ScannerT> first;
+ const rule<ScannerT> & start() const
+ { return first; }
+ };
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // MultiTag Grammar
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ struct MultiTag : public grammar<MultiTag, MTagVal>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition( const MultiTag & self )
+ {
+ first =
+ (
+ line
+ = stag [bind(&MTag::stag)(self.val)=arg1]
+ >> *(anychar_p - eol_p)
+ >> eol_p
+ >> data [bind(&MTag::data)(self.val)=construct_<Range>(arg1,arg2)]
+ >> ( etag [bind(&MTag::etag)(self.val)=arg1]
+ | error_report_p( "Missing end tag" )
+ )
+ >> *(anychar_p - eol_p)
+ >> (eol_p|end_p)
+ ,
+ stag
+ = ( ch_p('+')
+ >> ( (+alpha_p) [bind(&Tag::ident)(stag.val)=construct_<std::string>(arg1,arg2)]
+ >> !( '.'
+ >> (+alpha_p) [bind(&Tag::ext)(stag.val)=construct_<std::string>(arg1,arg2)]
+ )
+ ) [self.expect=construct_<std::string>(arg1,arg2)]
+ >> ':'
+ ) [bind(&Tag::range)(stag.val)=construct_<Range>(arg1,arg2)]
+ ,
+ data
+ = while_p( ~eps_p(dataend) )
+ [
+ ( !( *blank_p >> +~space_p
+ >> *( +blank_p >> +~space_p )
+ )
+ ) [push_back(bind(&MTag::value)(self.val),construct_<std::string>(arg1,arg2))]
+ >> *blank_p
+ >> eol_p
+ ]
+ ,
+ dataend
+ = ( ch_p('-') | ch_p('+') )
+ >> f_str_p(self.expect)
+ >> ':'
+ ,
+ etag
+ = ( ch_p('-')
+ >> f_str_p(self.expect)
+ >> ':'
+ ) [bind(&Tag::range)(etag.val)=construct_<Range>(arg1,arg2)]
+
+ );
+ }
+
+ subrule<0> line;
+ subrule<1,TagVal> stag;
+ subrule<2> data;
+ subrule<3> dataend;
+ subrule<4,TagVal> etag;
+
+ rule<ScannerT> first;
+ const rule<ScannerT> & start() const
+ { return first; }
+ };
+ };
+
+ /////////////////////////////////////////////////////////////////
+ } // namespace tagfile
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////
+ } // namespace parser
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_PARSER_TAGFILE_GRAMMAR_H
## ##################################################
include_HEADERS = \
- Tags.h
+ ParseException.h\
+ Tags.h \
+ Grammar.h \
+ Parser.h
noinst_LTLIBRARIES = lib@PACKAGE@_parser_tagfile.la
## ##################################################
lib@PACKAGE@_parser_tagfile_la_SOURCES = \
- Tags.cc
+ ParseException.cc\
+ Tags.cc \
+ Parser.cc
lib@PACKAGE@_parser_tagfile_la_LIBADD =
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/parser/tagfile/ParseException.cc
+ *
+*/
+#include <iostream>
+//#include "zypp/base/Logger.h"
+
+#include "zypp/parser/tagfile/ParseException.h"
+
+using std::endl;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace parser
+ { /////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace tagfile
+ { /////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // METHOD NAME : ParseException::ParseException
+ // METHOD TYPE : Ctor
+ //
+ ParseException::ParseException()
+ : Exception( "Parse exception" )
+ {}
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // METHOD NAME : ParseException::ParseException
+ // METHOD TYPE : Ctor
+ //
+ ParseException::ParseException( const std::string & msg_r )
+ : Exception( msg_r )
+ {}
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // METHOD NAME : ParseException::~ParseException
+ // METHOD TYPE : Dtor
+ //
+ ParseException::~ParseException() throw()
+ {}
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // METHOD NAME : ParseException::dumpOn
+ // METHOD TYPE : std::ostream &
+ //
+ std::ostream & ParseException::dumpOn( std::ostream & str ) const
+ {
+ return Exception::dumpOn( str );
+ }
+
+ /////////////////////////////////////////////////////////////////
+ } // namespace tagfile
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////
+ } // namespace parser
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/parser/tagfile/ParseException.h
+ *
+*/
+#ifndef ZYPP_PARSER_TAGFILE_PARSEEXCEPTION_H
+#define ZYPP_PARSER_TAGFILE_PARSEEXCEPTION_H
+
+#include <iosfwd>
+#include <string>
+
+#include "zypp/base/Exception.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace parser
+ { /////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace tagfile
+ { /////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ParseException
+ //
+ /** */
+ class ParseException : public Exception
+ {
+ public:
+ /** Default ctor */
+ ParseException();
+ /** Ctor */
+ ParseException( const std::string & msg_r );
+ /** Dtor */
+ virtual ~ParseException() throw();
+ protected:
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+ };
+ ///////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////
+ } // namespace tagfile
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////
+ } // namespace parser
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_PARSER_TAGFILE_PARSEEXCEPTION_H
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/parser/tagfile/Parser.cc
+ *
+*/
+#include <iostream>
+#include "zypp/base/Logger.h"
+#include "zypp/base/PtrTypes.h"
+
+#include "zypp/parser/tagfile/Parser.h"
+#include "zypp/parser/tagfile/Grammar.h"
+
+using std::endl;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace parser
+ { /////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace tagfile
+ { /////////////////////////////////////////////////////////////////
+
+ // translate operator= into Parser::consume calls
+ struct ParserConnect
+ {
+ ParserConnect( Parser & consumer_r )
+ : _consumer( consumer_r )
+ {}
+
+ const ParserConnect & operator=( const STag & stag_r ) const
+ { _consumer.consume( stag_r ); return *this; }
+
+ const ParserConnect & operator=( const MTag & mtag_r ) const
+ { _consumer.consume( mtag_r ); return *this; }
+
+ Parser & _consumer;
+ };
+
+ static void doParse( iterator_t begin_r, iterator_t end_r,
+ const ParserConnect & consumer_r );
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // METHOD NAME : Parser::parse
+ // METHOD TYPE : void
+ //
+ void Parser::parse( const Pathname & file_r )
+ {
+ // Create a file iterator for this file
+ fiterator_t first( file_r.asString() );
+ if (!first)
+ {
+ ZYPP_THROW( ParseException( std::string("Unable to open file ")
+ + file_r.asString() ) );
+ }
+ // Create an EOF iterator
+ fiterator_t last = first.make_end();
+
+ // Create position iterators
+ iterator_t begin( first, last, file_r.asString() );
+ iterator_t end;
+
+ // go
+ doParse( begin, end, *this );
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ // Just for the stats
+ struct Measure
+ {
+ time_t _begin;
+ Measure()
+ : _begin( time(NULL) )
+ {
+ USR << "START MEASURE..." << endl;
+ }
+ ~Measure()
+ {
+ USR << "DURATION: " << (time(NULL)-_begin) << " sec." << endl;
+ }
+ };
+ ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // doParse
+ //
+ ///////////////////////////////////////////////////////////////////
+
+ static void doParse( iterator_t begin_r,
+ iterator_t end_r,
+ const ParserConnect & consumer_r )
+ {
+ SingleTag stag;
+ MultiTag mtag;
+
+ rule_t file = end_p
+ | ( stag [var(consumer_r)=arg1]
+ | mtag [var(consumer_r)=arg1]
+ | ( *blank_p
+ >> !( ch_p('#')
+ >> *(anychar_p - eol_p)
+ )
+ >> (eol_p|end_p)
+ )
+ | error_report_p( "illegal line" )
+ )
+ >> file
+ ;
+
+ shared_ptr<Measure> duration( new Measure );
+ parse_info<iterator_t> info = parse( begin_r, end_r, file );
+ duration.reset();
+
+ if ( info.full )
+ USR << "Parse succeeded!\n";
+ else
+ {
+ if ( info.hit )
+ {
+ ERR << "Parse partial!\n";
+ ERR << " at pos " << info.length << endl;
+ }
+ else
+ {
+ ERR << "Parse failed!\n";
+ ERR << " at pos " << info.length << endl;
+ }
+ ZYPP_THROW( ParseException("Parse failed") );
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////
+ } // namespace tagfile
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////
+ } // namespace parser
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/parser/tagfile/Parser.h
+ *
+*/
+#ifndef ZYPP_PARSER_TAGFILE_PARSER_H
+#define ZYPP_PARSER_TAGFILE_PARSER_H
+
+#include <iosfwd>
+
+#include "zypp/parser/tagfile/Tags.h"
+#include "zypp/parser/tagfile/ParseException.h"
+
+#include "zypp/Pathname.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace parser
+ { /////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace tagfile
+ { /////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : Parser
+ //
+ /** Tagfile parser. */
+ struct Parser
+ {
+ virtual ~Parser()
+ {}
+
+ /* Overload to consume SingleTag data. */
+ virtual void consume( const STag & stag_r )
+ {}
+ /* Overload to consume MulitTag data. */
+ virtual void consume( const MTag & mtag_r )
+ {}
+
+ /* Parse file and invoke consume on each tag found.
+ * \throw ParseException
+ * \todo more doc on Ecaptions.
+ */
+ void parse( const Pathname & file_r );
+ };
+ ///////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////
+ } // namespace tagfile
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////
+ } // namespace parser
+ ///////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_PARSER_TAGFILE_PARSER_H
/** \relates MTag Stream output.*/
std::ostream & operator<<( std::ostream & str, const MTag & obj );
- ////////////////////////////////////////////////////////////////////////////
- //
- // Closures
- //
- ////////////////////////////////////////////////////////////////////////////
-
- struct TagClosure : public spirit::closure<TagClosure, Tag>
- {
- member1 val;
- };
- typedef TagClosure::context_t TagVal;
-
- struct STagClosure : public spirit::closure<STagClosure, STag>
- {
- member1 val;
- };
- typedef STagClosure::context_t STagVal;
-
- struct MTagClosure : public spirit::closure<MTagClosure, MTag, std::string>
- {
- member1 val;
- member2 expect;
- };
- typedef MTagClosure::context_t MTagVal;
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // SingleTag Grammar
- //
- ////////////////////////////////////////////////////////////////////////////
-
- struct SingleTag : public grammar<SingleTag, STagVal>
- {
- template <typename ScannerT>
- struct definition
- {
- definition( const SingleTag & self )
- {
- first =
- (
- line
- = stag [bind(&STag::stag)(self.val)=arg1]
- >> *blank_p
- >> (!data) [bind(&STag::data)(self.val)=construct_<Range>(arg1,arg2)]
- [bind(&STag::value)(self.val)=construct_<std::string>(arg1,arg2)]
- >> *blank_p
- >> (eol_p|end_p)
- ,
- stag
- = ( ch_p('=')
- >> (+alpha_p) [bind(&Tag::ident)(stag.val)=construct_<std::string>(arg1,arg2)]
- >> !( '.'
- >> (+alpha_p) [bind(&Tag::ext)(stag.val)=construct_<std::string>(arg1,arg2)]
- )
- >> ':'
- ) [bind(&Tag::range)(stag.val)=construct_<Range>(arg1,arg2)]
- ,
- data
- = +~space_p
- >> *( +blank_p
- >> +~space_p
- )
- );
- }
-
- subrule<0> line;
- subrule<1,TagVal> stag;
- subrule<2> data;
-
- rule<ScannerT> first;
- const rule<ScannerT> & start() const
- { return first; }
- };
- };
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // MultiTag Grammar
- //
- ////////////////////////////////////////////////////////////////////////////
-
- struct MultiTag : public grammar<MultiTag, MTagVal>
- {
- template <typename ScannerT>
- struct definition
- {
- definition( const MultiTag & self )
- {
- first =
- (
- line
- = stag [bind(&MTag::stag)(self.val)=arg1]
- >> *(anychar_p - eol_p)
- >> eol_p
- >> data [bind(&MTag::data)(self.val)=construct_<Range>(arg1,arg2)]
- >> ( etag [bind(&MTag::etag)(self.val)=arg1]
- | error_report_p( "Missing end tag" )
- )
- >> *(anychar_p - eol_p)
- >> (eol_p|end_p)
- ,
- stag
- = ( ch_p('+')
- >> ( (+alpha_p) [bind(&Tag::ident)(stag.val)=construct_<std::string>(arg1,arg2)]
- >> !( '.'
- >> (+alpha_p) [bind(&Tag::ext)(stag.val)=construct_<std::string>(arg1,arg2)]
- )
- ) [self.expect=construct_<std::string>(arg1,arg2)]
- >> ':'
- ) [bind(&Tag::range)(stag.val)=construct_<Range>(arg1,arg2)]
- ,
- data
- = while_p( ~eps_p(dataend) )
- [
- ( !( *blank_p >> +~space_p
- >> *( +blank_p >> +~space_p )
- )
- ) [push_back(bind(&MTag::value)(self.val),construct_<std::string>(arg1,arg2))]
- >> *blank_p
- >> eol_p
- ]
- ,
- dataend
- = ( ch_p('-') | ch_p('+') )
- >> f_str_p(self.expect)
- >> ':'
- ,
- etag
- = ( ch_p('-')
- >> f_str_p(self.expect)
- >> ':'
- ) [bind(&Tag::range)(etag.val)=construct_<Range>(arg1,arg2)]
-
- );
- }
-
- subrule<0> line;
- subrule<1,TagVal> stag;
- subrule<2> data;
- subrule<3> dataend;
- subrule<4,TagVal> etag;
-
- rule<ScannerT> first;
- const rule<ScannerT> & start() const
- { return first; }
- };
- };
-
/////////////////////////////////////////////////////////////////
} // namespace tagfile
///////////////////////////////////////////////////////////////////