Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package belr for openSUSE:Factory checked in 
at 2021-10-27 22:21:13
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/belr (Old)
 and      /work/SRC/openSUSE:Factory/.belr.new.1890 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "belr"

Wed Oct 27 22:21:13 2021 rev:11 rq:927658 version:5.0.36

Changes:
--------
--- /work/SRC/openSUSE:Factory/belr/belr.changes        2021-07-21 
19:07:34.059415318 +0200
+++ /work/SRC/openSUSE:Factory/.belr.new.1890/belr.changes      2021-10-27 
22:21:29.983207703 +0200
@@ -1,0 +2,7 @@
+Tue Oct 19 23:24:28 UTC 2021 - Giacomo Comes <gcomes....@gmail.com> - 5.0.36
+
+- Update to version 5.0.36:
+  * Cast on assert to remove warning on x64
+  * Remove a useless usage shared_ptr<> in the Parser and Regognizers
+
+-------------------------------------------------------------------

Old:
----
  belr-4.5.20.tar.bz2

New:
----
  belr-5.0.36.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ belr.spec ++++++
--- /var/tmp/diff_new_pack.cLYxrt/_old  2021-10-27 22:21:30.487207962 +0200
+++ /var/tmp/diff_new_pack.cLYxrt/_new  2021-10-27 22:21:30.491207964 +0200
@@ -19,7 +19,7 @@
 %define soname  libbelr
 %define sover   1
 Name:           belr
-Version:        4.5.20
+Version:        5.0.36
 Release:        0
 Summary:        Language recognition library
 License:        GPL-3.0-or-later
@@ -31,9 +31,9 @@
 Patch0:         belr-fix-pkgconfig.patch
 BuildRequires:  cmake
 BuildRequires:  gcc-c++
-BuildRequires:  pkgconfig
-BuildRequires:  pkgconfig(bctoolbox) >= 4.5.0
 BuildRequires:  libudev-devel
+BuildRequires:  pkgconfig
+BuildRequires:  pkgconfig(bctoolbox) >= 5.0.0
 
 %description
 Belr parses input formatted according to a language defined by an
@@ -41,6 +41,7 @@
 
 %package -n %{soname}%{sover}
 Summary:        Language recognition library
+Group:          Development/Tools/Other
 
 %description -n %{soname}%{sover}
 Belr parses input formatted according to a language defined by an

++++++ belr-4.5.20.tar.bz2 -> belr-5.0.36.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/belr-4.5.20/CMakeLists.txt 
new/belr-5.0.36/CMakeLists.txt
--- old/belr-4.5.20/CMakeLists.txt      2020-10-22 16:31:51.000000000 +0200
+++ new/belr-5.0.36/CMakeLists.txt      2021-09-16 11:45:16.000000000 +0200
@@ -1,6 +1,6 @@
 ############################################################################
 # CMakeLists.txt
-# Copyright (C) 2010-2019 Belledonne Communications, Grenoble France
+# Copyright (C) 2010-2021 Belledonne Communications, Grenoble France
 #
 ############################################################################
 #
@@ -20,8 +20,12 @@
 #
 ############################################################################
 
-cmake_minimum_required(VERSION 3.1)
-project(BELR VERSION 4.5.0 LANGUAGES C CXX)
+
+# CMake 3.13 required for new Flexisip build process.
+# See [CMP077](https://cmake.org/cmake/help/v3.13/policy/CMP0077.html).
+cmake_minimum_required(VERSION 3.13)
+
+project(BELR VERSION 5.0.0 LANGUAGES C CXX)
 
 set(BELR_SO_VERSION "1")
 
@@ -32,6 +36,10 @@
 option(ENABLE_TESTS "Enable compilation of unit tests." YES)
 option(ENABLE_PACKAGE_SOURCE "Create 'package_source' target for source 
archive making (CMake >= 3.11)" OFF)
 
+# Hidden non-cache options:
+# * DISABLE_BC_PACKAGE_SEARCH: skip find_package() for every BC package 
(bctoolbox, ortp, etc.)
+
+
 list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
 
 if(NOT CPACK_GENERATOR AND NOT CMAKE_INSTALL_RPATH AND CMAKE_INSTALL_PREFIX)
@@ -50,7 +58,9 @@
 
 # find_package should be invoked here to check for libraries - however do NOT
 # call include_directories here (see below)
-find_package(bctoolbox 0.0.5 REQUIRED OPTIONAL_COMPONENTS tester)
+if(NOT DISABLE_BC_PACKAGE_SEARCH)
+       find_package(bctoolbox 0.0.5 REQUIRED OPTIONAL_COMPONENTS tester)
+endif()
 
 set(LINK_FLAGS )
 
@@ -131,9 +141,11 @@
 set(EXPORT_TARGET_NAME belr)
 set(ConfigPackageLocation 
"${CMAKE_INSTALL_LIBDIR}/cmake/${EXPORT_TARGET_NAME}")
 
-export(EXPORT ${EXPORT_TARGET_NAME}Targets
-       FILE "${CMAKE_CURRENT_BINARY_DIR}/${EXPORT_TARGET_NAME}Targets.cmake"
-)
+if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
+       export(EXPORT ${EXPORT_TARGET_NAME}Targets
+               FILE 
"${CMAKE_CURRENT_BINARY_DIR}/${EXPORT_TARGET_NAME}Targets.cmake"
+       )
+endif()
 
 configure_package_config_file(cmake/BelrConfig.cmake.in
        "${CMAKE_CURRENT_BINARY_DIR}/${EXPORT_TARGET_NAME}Config.cmake"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/belr-4.5.20/include/belr/belr.h 
new/belr-5.0.36/include/belr/belr.h
--- old/belr-4.5.20/include/belr/belr.h 2020-10-22 16:31:51.000000000 +0200
+++ new/belr-5.0.36/include/belr/belr.h 2021-09-16 11:45:16.000000000 +0200
@@ -68,7 +68,7 @@
 
        void setName(const std::string &name);
        const std::string &getName()const;
-       BELR_PUBLIC size_t feed(const std::shared_ptr<ParserContextBase> &ctx, 
const std::string &input, size_t pos);
+       BELR_PUBLIC size_t feed(ParserContextBase &ctx, const std::string 
&input, size_t pos);
        unsigned int getId()const{
                return mId;
        }
@@ -84,7 +84,7 @@
        /*returns true if the transition map is complete, false otherwise*/
        virtual bool _getTransitionMap(TransitionMap *mask);
        virtual void _optimize(int recursionLevel)=0;
-       virtual size_t _feed(const std::shared_ptr<ParserContextBase> &ctx, 
const std::string &input, size_t pos) = 0;
+       virtual size_t _feed(ParserContextBase &ctx, const std::string &input, 
size_t pos) = 0;
 
        std::string mName;
        unsigned int mId = 0;
@@ -108,7 +108,7 @@
        CharRecognizer(int to_recognize, bool caseSensitive=false);
        CharRecognizer(BinaryGrammarBuilder &istr);
 private:
-       size_t _feed(const std::shared_ptr<ParserContextBase> &ctx, const 
std::string &input, size_t pos) override;
+       size_t _feed(ParserContextBase &ctx, const std::string &input, size_t 
pos) override;
        void _optimize(int recursionLevel) override;
        virtual void _serialize(BinaryOutputStream &fstr) override;
 
@@ -123,11 +123,11 @@
        Selector(BinaryGrammarBuilder &istr);
 protected:
        void _optimize(int recursionLevel) override;
-       size_t _feed(const std::shared_ptr<ParserContextBase> &ctx, const 
std::string &input, size_t pos) override;
+       size_t _feed(ParserContextBase &ctx, const std::string &input, size_t 
pos) override;
        bool _getTransitionMap(TransitionMap *mask) override;
        virtual void _serialize(BinaryOutputStream &fstr) override;
 
-       size_t _feedExclusive(const std::shared_ptr<ParserContextBase> &ctx, 
const std::string &input, size_t pos);
+       size_t _feedExclusive(ParserContextBase &ctx, const std::string &input, 
size_t pos);
 
        std::list<std::shared_ptr<Recognizer>> mElements;
        bool mIsExclusive = false;
@@ -139,7 +139,7 @@
        ExclusiveSelector();
        ExclusiveSelector(BinaryGrammarBuilder &istr);
 private:
-       size_t _feed(const std::shared_ptr<ParserContextBase> &ctx, const 
std::string &input, size_t pos) override;
+       size_t _feed(ParserContextBase &ctx, const std::string &input, size_t 
pos) override;
 };
 
 class Sequence : public Recognizer{
@@ -154,7 +154,7 @@
        void _optimize(int recursionLevel) override;
 
 private:
-       size_t _feed(const std::shared_ptr<ParserContextBase> &ctx, const 
std::string &input, size_t pos) override;
+       size_t _feed(ParserContextBase &ctx, const std::string &input, size_t 
pos) override;
 
        std::list<std::shared_ptr<Recognizer>> mElements;
 };
@@ -171,7 +171,7 @@
        void _optimize(int recursionLevel) override;
 
 private:
-       size_t _feed(const std::shared_ptr<ParserContextBase> &ctx, const 
std::string &input, size_t pos) override;
+       size_t _feed(ParserContextBase &ctx, const std::string &input, size_t 
pos) override;
 
        std::shared_ptr<Recognizer> mRecognizer;
        int mMin = 0;
@@ -195,7 +195,7 @@
 private:
        virtual void _serialize(BinaryOutputStream &fstr) override;
        void _optimize(int recursionLevel) override;
-       size_t _feed(const std::shared_ptr<ParserContextBase> &ctx, const 
std::string &input, size_t pos) override;
+       size_t _feed(ParserContextBase &ctx, const std::string &input, size_t 
pos) override;
 
        int mBegin;
        int mEnd;
@@ -210,7 +210,7 @@
 private:
        void _optimize(int recursionLevel) override;
        virtual void _serialize(BinaryOutputStream &fstr) override;
-       size_t _feed(const std::shared_ptr<ParserContextBase> &ctx, const 
std::string &input, size_t pos) override;
+       size_t _feed(ParserContextBase &ctx, const std::string &input, size_t 
pos) override;
 
        std::string mLiteral;
        size_t mLiteralSize;
@@ -237,7 +237,7 @@
 private:
        void _optimize(int recursionLevel) override;
        virtual void _serialize(BinaryOutputStream &fstr) override;
-       size_t _feed(const std::shared_ptr<ParserContextBase> &ctx, const 
std::string &input, size_t pos) override;
+       size_t _feed(ParserContextBase &ctx, const std::string &input, size_t 
pos) override;
 
        std::shared_ptr<Recognizer> mRecognizer;
 };
@@ -259,7 +259,7 @@
 private:
        void _optimize(int recursionLevel) override;
        virtual void _serialize(BinaryOutputStream &fstr) override;
-       size_t _feed(const std::shared_ptr<ParserContextBase> &ctx, const 
std::string &input, size_t pos) override;
+       size_t _feed(ParserContextBase &ctx, const std::string &input, size_t 
pos) override;
        std::shared_ptr<Recognizer> mRecognizer;
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/belr-4.5.20/include/belr/parser.h 
new/belr-5.0.36/include/belr/parser.h
--- old/belr-4.5.20/include/belr/parser.h       2020-10-22 16:31:51.000000000 
+0200
+++ new/belr-5.0.36/include/belr/parser.h       2021-09-16 11:45:16.000000000 
+0200
@@ -46,6 +46,12 @@
        return std::static_pointer_cast<typename T::element_type>(sp);
 }
 
+
+//template <class T, class U>
+//inline std::shared_ptr<T> universal_pointer_cast(const std::shared_ptr<U>& 
sp){
+//     return std::static_pointer_cast<T>(sp);
+//}
+
 template <class T, class U>
 inline T universal_pointer_cast(U * p){
        return static_cast<T>(p);
@@ -85,7 +91,9 @@
        inline void _invokeWithChild(_parserElementT obj, typename 
std::enable_if<std::is_floating_point<_valueT>::value, _parserElementT>::type 
child){
        }
        template <typename _valueT>
-       inline void _invokeWithChild(_parserElementT obj, typename 
std::enable_if<std::is_convertible<_valueT, _parserElementT>::value, 
_parserElementT>::type child){
+       inline void _invokeWithChild(
+               typename std::enable_if< std::is_convertible<typename 
_functorT::first_argument_type, _parserElementT>::value, _parserElementT>::type 
obj, 
+               typename std::enable_if< std::is_convertible<_valueT, 
_parserElementT>::value, _parserElementT>::type child ){
                mFunc(universal_pointer_cast<typename 
std::remove_reference<typename _functorT::first_argument_type>::type>(obj), 
                        universal_pointer_cast<typename 
std::remove_reference<typename _functorT::second_argument_type>::type>(child));
        }
@@ -126,6 +134,7 @@
        std::shared_ptr<HandlerContext<_parserElementT>> mCachedContext;
 };
 
+
 template <typename _createElementFn, typename _parserElementT>
 class ParserHandler :  public ParserHandlerBase<_parserElementT>{
 public:
@@ -147,7 +156,6 @@
        }
        template <typename _funcT>
        typename std::enable_if<std::is_convertible<_funcT, 
std::function<_derivedParserElementT()>>::value, _derivedParserElementT>::type 
_invoke(const std::string &value, size_t begin, size_t count){
-               // Case where the create func accepts two strings for rulename 
and matched characters.
                return mHandlerCreateFunc();
        }
        _createElementFn mHandlerCreateFunc;
@@ -293,11 +301,11 @@
        BELR_PUBLIC std::shared_ptr<DebugElement> parseInput(const std::string 
&rulename, const std::string &input, size_t *parsed_size);
 };
 
-//Utility functions for handlers/collectors objects instantiation and 
properties accessors
-template <typename _retT>
-inline std::function< std::shared_ptr<_retT> ()> make_fn() {
-       return std::bind(&std::make_shared<_retT>);
-}
+//
+// Utility functions for handlers/collectors objects instantiation and 
properties accessors
+//
+
+/* For parser relying on raw pointers */
 
 template <typename _retT>
 inline std::function< _retT ()> make_fn(_retT (*arg)()){
@@ -329,6 +337,13 @@
        return std::function< void (_klassT*,_argT)>(std::mem_fn(arg));
 }
 
+/* For parsers using shared_ptr<> */
+
+template <typename _retT>
+inline std::function< std::shared_ptr<_retT> ()> make_fn() {
+       return std::bind(&std::make_shared<_retT>);
+}
+
 template <typename _klassT, typename _argT>
 inline std::function< void (std::shared_ptr<_klassT>,_argT)> make_sfn(void 
(_klassT::*arg)(_argT)){
        return std::function< void 
(std::shared_ptr<_klassT>,_argT)>(std::mem_fn(arg));
@@ -487,7 +502,7 @@
        if (mHandlerStack.empty()){
                fatal("Cannot parse when mHandlerStack is empty. You must 
define a top-level rule handler.");
        }
-       lctx.set(ctx,rec,mHandlerStack.back()->getLastIterator());
+       lctx.set(ctx, rec, mHandlerStack.back()->getLastIterator());
 }
 
 template <typename _parserElementT>
@@ -615,14 +630,21 @@
 _parserElementT Parser<_parserElementT>::parseInput(const std::string 
&rulename, const std::string &input, size_t *parsed_size){
        size_t parsed;
        std::shared_ptr<Recognizer> rec=mGrammar->getRule(rulename);
-       auto pctx=std::make_shared<ParserContext<_parserElementT>>(*this);
+       ParserContext<_parserElementT> pctx(*this);
+       
+       auto h=getHandler(rec->getId());
+       if (!h){
+               std::ostringstream str;
+               str<<"There is no handler for rule '"<<rulename<<"'.";
+               fatal(str.str().c_str());
+       }
 
        //auto t_start = std::chrono::high_resolution_clock::now();
        parsed=rec->feed(pctx, input, 0);
        //auto t_end = std::chrono::high_resolution_clock::now();
        //cout<<"Recognition done in "<<std::chrono::duration<double, 
std::milli>(t_end-t_start).count()<<" milliseconds"<<std::endl;
        if (parsed_size) *parsed_size=parsed;
-       auto ret= pctx->createRootObject(input, parsed);
+       auto ret= pctx.createRootObject(input, parsed);
        return ret;
 }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/belr-4.5.20/src/CMakeLists.txt 
new/belr-5.0.36/src/CMakeLists.txt
--- old/belr-4.5.20/src/CMakeLists.txt  2020-10-22 16:31:51.000000000 +0200
+++ new/belr-5.0.36/src/CMakeLists.txt  2021-09-16 11:45:16.000000000 +0200
@@ -60,7 +60,7 @@
                else()
                        set(MIN_OS ${CMAKE_OSX_DEPLOYMENT_TARGET})
                endif()
-               set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} 
"${CMAKE_SOURCE_DIR}/build/osx/")
+               set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} 
"${PROJECT_SOURCE_DIR}/build/osx/")
                set_target_properties(belr PROPERTIES
                        FRAMEWORK TRUE
                        MACOSX_FRAMEWORK_IDENTIFIER org.linphone.belr
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/belr-4.5.20/src/belr.cpp new/belr-5.0.36/src/belr.cpp
--- old/belr-4.5.20/src/belr.cpp        2020-10-22 16:31:51.000000000 +0200
+++ new/belr-5.0.36/src/belr.cpp        2021-09-16 11:45:16.000000000 +0200
@@ -30,6 +30,24 @@
        bctbx_fatal("%s", message);
 }
 
+/* Dummy ParserContext, actually used for optimization phase, to let invoke 
the feed() function without
+ * instanciating anything.*/
+class DummyParserContext : public ParserContextBase{
+public:
+       virtual void beginParse(ParserLocalContext &ctx, const 
std::shared_ptr<Recognizer> &rec) override{
+       }
+       virtual void endParse(const ParserLocalContext &ctx, const std::string 
&input, size_t begin, size_t count) override{
+       }
+       virtual std::shared_ptr<HandlerContextBase> branch() override{
+               return nullptr;
+       }
+       virtual void merge(const std::shared_ptr<HandlerContextBase> &other) 
override{
+       }
+       virtual void removeBranch(const std::shared_ptr<HandlerContextBase> 
&other) override{
+       }
+};
+
+
 // 
=============================================================================
 
 TransitionMap::TransitionMap(){
@@ -170,7 +188,7 @@
        return mName;
 }
 
-size_t Recognizer::feed(const shared_ptr<ParserContextBase> &ctx, const string 
&input, size_t pos){
+size_t Recognizer::feed(ParserContextBase &ctx, const string &input, size_t 
pos){
        size_t match;
 
 #ifdef BELR_DEBUG
@@ -178,7 +196,7 @@
 #endif
 
        ParserLocalContext hctx;
-       if (ctx) ctx->beginParse(hctx, shared_from_this());
+       ctx.beginParse(hctx, shared_from_this());
        match=_feed(ctx, input, pos);
        if (match!=string::npos && match>0){
                #ifdef BELR_DEBUG
@@ -188,7 +206,7 @@
                        }
                #endif
        }
-       if (ctx) ctx->endParse(hctx, input, pos, match);
+       ctx.endParse(hctx, input, pos, match);
 
        return match;
 }
@@ -212,7 +230,8 @@
        input.resize(2,'\0');
        for(int i=0;i<256;++i){
                input[0]=i;
-               if (feed(nullptr,input,0)==1)
+               DummyParserContext pctx;
+               if (feed(pctx,input,0)==1)
                        mask->mPossibleChars[i]=true;
        }
        return true;
@@ -237,7 +256,7 @@
        }
 }
 
-size_t CharRecognizer::_feed(const shared_ptr<ParserContextBase> &ctx, const 
string &input, size_t pos){
+size_t CharRecognizer::_feed(ParserContextBase &ctx, const string &input, 
size_t pos){
        int c = (unsigned char)input[pos];
        if (mCaseSensitive){
                return c == mToRecognize ? 1 : string::npos;
@@ -278,7 +297,7 @@
        return true;
 }
 
-size_t Selector::_feedExclusive(const shared_ptr<ParserContextBase> &ctx, 
const string &input, size_t pos){
+size_t Selector::_feedExclusive(ParserContextBase &ctx, const string &input, 
size_t pos){
        size_t matched=0;
 
        for (auto it=mElements.begin(); it!=mElements.end(); ++it){
@@ -290,7 +309,7 @@
        return string::npos;
 }
 
-size_t Selector::_feed(const shared_ptr<ParserContextBase> &ctx, const string 
&input, size_t pos){
+size_t Selector::_feed(ParserContextBase &ctx, const string &input, size_t 
pos){
        if (mIsExclusive) return _feedExclusive(ctx, input, pos);
 
        size_t matched=0;
@@ -299,20 +318,19 @@
 
        for (auto it=mElements.begin(); it!=mElements.end(); ++it){
                shared_ptr<HandlerContextBase> br;
-               if (ctx) br=ctx->branch();
+               br = ctx.branch();
                matched=(*it)->feed(ctx, input, pos);
                if (matched!=string::npos && matched>bestmatch) {
                        bestmatch=matched;
-                       if (bestBranch) ctx->removeBranch(bestBranch);
+                       if (bestBranch) ctx.removeBranch(bestBranch);
                        bestBranch=br;
                }else{
-                       if (ctx)
-                               ctx->removeBranch(br);
+                       ctx.removeBranch(br);
                }
        }
        if (bestmatch==0) return string::npos;
-       if (ctx && bestmatch!=string::npos){
-               ctx->merge(bestBranch);
+       if (bestmatch!=string::npos){
+               ctx.merge(bestBranch);
        }
        return bestmatch;
 }
@@ -341,6 +359,11 @@
 }
 
 
+/* The purpose of the optimization is to determine if a selector is exclusive, 
ie that only a single branch can match.
+ * This is done by examining if the character transitions to jump to each 
branch (sub-recognizers) do intersect.
+ * If no, it means that the first branch that will match during the parsing 
will necessarily be the good one, so that there is no need to 
+ * examine others.
+ */
 void Selector::_optimize(int recursionLevel){
        for (auto it=mElements.begin(); it!=mElements.end(); ++it){
                (*it)->optimize(recursionLevel);
@@ -373,7 +396,7 @@
 ExclusiveSelector::ExclusiveSelector(BinaryGrammarBuilder &istr) : 
Selector(istr){
 }
 
-size_t ExclusiveSelector::_feed(const shared_ptr<ParserContextBase> &ctx, 
const string &input, size_t pos){
+size_t ExclusiveSelector::_feed(ParserContextBase &ctx, const string &input, 
size_t pos){
        return Selector::_feedExclusive(ctx, input, pos);
 }
 
@@ -395,7 +418,7 @@
 }
 
 
-size_t Sequence::_feed(const shared_ptr<ParserContextBase> &ctx, const string 
&input, size_t pos){
+size_t Sequence::_feed(ParserContextBase &ctx, const string &input, size_t 
pos){
        size_t matched=0;
        size_t total=0;
 
@@ -442,7 +465,7 @@
        return static_pointer_cast<Loop>(shared_from_this());
 }
 
-size_t Loop::_feed(const shared_ptr<ParserContextBase> &ctx, const string 
&input, size_t pos){
+size_t Loop::_feed(ParserContextBase &ctx, const string &input, size_t pos){
        size_t matched=0;
        size_t total=0;
        int repeat;
@@ -482,7 +505,7 @@
 CharRange::CharRange(int begin, int end) : mBegin(begin), mEnd(end){
 }
 
-size_t CharRange::_feed(const shared_ptr<ParserContextBase> &ctx, const string 
&input, size_t pos){
+size_t CharRange::_feed(ParserContextBase &ctx, const string &input, size_t 
pos){
        int c = (unsigned char)input[pos];
        if (c >= mBegin && c <= mEnd) return 1;
        return string::npos;
@@ -530,7 +553,7 @@
 
 }
 
-size_t Literal::_feed(const shared_ptr< ParserContextBase >& ctx, const 
string& input, size_t pos){
+size_t Literal::_feed(ParserContextBase &ctx, const string& input, size_t pos){
        size_t i;
        for(i=0;i<mLiteralSize;++i){
                if (::tolower(input[pos+i])!=mLiteral[i]) return string::npos;
@@ -569,7 +592,7 @@
        return mRecognizer;
 }
 
-size_t RecognizerPointer::_feed(const shared_ptr<ParserContextBase> &ctx, 
const string &input, size_t pos){
+size_t RecognizerPointer::_feed(ParserContextBase &ctx, const string &input, 
size_t pos){
        if (mRecognizer){
                return mRecognizer->feed(ctx, input, pos);
        }else{
@@ -601,7 +624,7 @@
        return mRecognizer;
 }
 
-size_t RecognizerAlias::_feed(const shared_ptr<ParserContextBase> &ctx, const 
string &input, size_t pos){
+size_t RecognizerAlias::_feed(ParserContextBase &ctx, const string &input, 
size_t pos){
        if (mRecognizer){
                return mRecognizer->feed(ctx, input, pos);
        }else{
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/belr-4.5.20/tester/grammar-tester.cpp 
new/belr-5.0.36/tester/grammar-tester.cpp
--- old/belr-4.5.20/tester/grammar-tester.cpp   2020-10-22 16:31:51.000000000 
+0200
+++ new/belr-5.0.36/tester/grammar-tester.cpp   2021-09-16 11:45:16.000000000 
+0200
@@ -108,7 +108,7 @@
        shared_ptr<DebugElement> elem = parser->parseInput("sip-message", 
sipmessage, &pos);
        BC_ASSERT_TRUE(elem != nullptr);
        if (!elem) return;
-       BC_ASSERT_EQUAL(pos, sipmessage.size(), int, "%i");
+       BC_ASSERT_EQUAL((int)pos, (int)sipmessage.size(), int, "%i");
        BC_ASSERT_TRUE(sipmessage == elem->getValue());
        list<shared_ptr<DebugElement>> headerNames;
        elem->findChildren("header-name", headerNames);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/belr-4.5.20/tester/parser.cpp 
new/belr-5.0.36/tester/parser.cpp
--- old/belr-4.5.20/tester/parser.cpp   2020-10-22 16:31:51.000000000 +0200
+++ new/belr-5.0.36/tester/parser.cpp   2021-09-16 11:45:16.000000000 +0200
@@ -109,7 +109,7 @@
        BC_ASSERT_PTR_NOT_NULL(elem);
        if (!elem) return;
        
-       BC_ASSERT_EQUAL(pos, sipmessage.size(), int, "%i");
+       BC_ASSERT_EQUAL((int)pos, (int)sipmessage.size(), int, "%i");
        
        sip_response_t *resp = (sip_response_t*)elem;
        sip_uri_t *from = resp->from;
@@ -127,10 +127,171 @@
        sip_response_destroy(resp);
 }
 
+//
+// Parser with inheritance. 
+//
+
+/* Base class for all parser elements*/
+class Object{
+public:
+       virtual ~Object() = default;
+};
+
+/* Base class for SIP headers */
+class SipHeader : public Object{
+public:
+       SipHeader(const string &headerName) : mHeaderName(headerName){}
+       const string &getName()const{
+               return mHeaderName;
+       }
+protected:
+       void setHeaderName(const string &headerName){
+               mHeaderName = headerName;
+       }
+private:
+       string mHeaderName;
+};
+
+/*
+ * The SipHeaderHolder is a kind of container for all possible types of SIP 
headers.
+ * This special type is needed so that it is possible to parse headers in an 
unitary way (not in a full message).
+ * It does not have to be part of the parser API. Keep it internal as an 
utility.
+ */
+class SipHeaderHolder : public Object{
+public:
+       SipHeaderHolder(){};
+       void setHeader(const shared_ptr<SipHeader> &header){
+               mHeader = header;
+       }
+       shared_ptr<SipHeader> getHeader()const{
+               return mHeader;
+       }
+private:
+       shared_ptr<SipHeader> mHeader;
+};
+
+/*
+ * SIP From
+ */
+class SipFrom : public SipHeader{
+public:
+       SipFrom() : SipHeader("From"){};
+       void setUri(const string& uri){
+               mUri = uri;
+       }
+       const string &getUri()const{
+               return mUri;
+       }
+private:
+       string mUri;
+};
+
+/*
+ * Extension header
+ */
+class ExtensionHeader : public SipHeader{
+public:
+       ExtensionHeader() : SipHeader("generic"){};
+       void setName(const string &headerName){
+               SipHeader::setHeaderName(headerName);
+       }
+       void setValue(const string &headerValue){
+               mHeaderValue = headerValue;
+       }
+       const string &getValue()const{
+               return mHeaderValue;
+       }
+private:
+       string mHeaderValue;
+};
+
+/*
+ * SIP request. Contains headers.
+ */
+class SipRequest : public Object{
+public:
+       SipRequest(){};
+       void addHeader(const shared_ptr<SipHeader> &header){
+               mHeaders.push_back(header);
+       }
+       shared_ptr <SipHeader> getHeader(const string &name){
+               for (auto h : mHeaders){
+                       if (strcasecmp(h->getName().c_str(), name.c_str()) == 
0) return h;
+               }
+               return nullptr;
+       }
+       
+       /* Hide this from the API documentation */
+       void addHeaderHolder(const shared_ptr<SipHeaderHolder> &holder){
+               if (holder->getHeader())
+                       addHeader(holder->getHeader());
+       }
+private:
+       list<shared_ptr<SipHeader>> mHeaders;
+};
+
+
+static void parser_with_inheritance(void){
+       string grammarToParse = bcTesterRes("sipgrammar.txt");
+       string sipmessage = openFile(bcTesterRes("register.txt"));
+       size_t pos = 0;
+       
+       BC_ASSERT_TRUE(sipmessage.size() > 0);
+
+       ABNFGrammarBuilder builder;
+
+       //Read grammar put it in object grammar
+       shared_ptr<Grammar> grammar=builder.createFromAbnfFile(grammarToParse, 
make_shared<CoreRules>());
+
+       BC_ASSERT_FALSE(!grammar);
+       
+       if (!grammar) return;
+       
+       shared_ptr<Parser<shared_ptr<Object>>> parser = 
make_shared<Parser<shared_ptr<Object>>>(grammar);
+       /* The request collects headers in a generic way, thanks to the 
SipHeaderHolder. */
+       parser->setHandler("request", make_fn<SipRequest>())
+               ->setCollector("message-header", 
make_sfn(&SipRequest::addHeaderHolder));
+       parser->setHandler("from", make_fn<SipFrom>())
+               ->setCollector("sip-uri", make_sfn(&SipFrom::setUri));
+       parser->setHandler("extension-header", make_fn<ExtensionHeader>())
+               ->setCollector("header-name", 
make_sfn(&ExtensionHeader::setName))
+               ->setCollector("header-value", 
make_sfn(&ExtensionHeader::setValue));
+               
+       /* The message-header rule (representing all sub-rules of SIP headers) 
is handled by the SipHeaderHolder.
+        * It requires explicit collectors for all sub-rules. */
+       parser->setHandler("message-header", make_fn<SipHeaderHolder>())
+               ->setCollector("from", make_sfn(&SipHeaderHolder::setHeader))
+               ->setCollector("extension-header", 
make_sfn(&SipHeaderHolder::setHeader));
+       
+       // Parse the full message
+       shared_ptr<Object> elem = parser->parseInput("request", sipmessage, 
&pos);
+       BC_ASSERT_TRUE(elem != nullptr);
+       if (!elem) return;
+       
+       BC_ASSERT_EQUAL(pos, sipmessage.size(), size_t, "%zu");
+       shared_ptr<SipRequest> request = dynamic_pointer_cast<SipRequest>(elem);
+       BC_ASSERT_TRUE(request != nullptr);
+       if (!request) return;
+       
+       BC_ASSERT_TRUE(request->getHeader("from") != nullptr);
+       BC_ASSERT_TRUE(request->getHeader("CustomHeader") != nullptr);
+       
+       // Parse a single sip header
+       
+       elem = parser->parseInput("message-header", "From: 
<sip:b...@example.net>\r\n", &pos);
+       BC_ASSERT_TRUE(elem != nullptr);
+       if (!elem) return;
+       auto holder = dynamic_pointer_cast<SipHeaderHolder>(elem);
+       BC_ASSERT_TRUE(holder != nullptr);
+       if (!holder) return;
+       BC_ASSERT_TRUE(dynamic_pointer_cast<SipFrom>(holder->getHeader()) != 
nullptr);
+}
+
 
 
 static test_t tests[] = {
        TEST_NO_TAG("Parser connected to C functions", 
parser_connected_to_c_functions),
+       TEST_NO_TAG("Parser with inheritance", parser_with_inheritance)
 };
 
 test_suite_t parser_suite = {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/belr-4.5.20/tester/res/register.txt 
new/belr-5.0.36/tester/res/register.txt
--- old/belr-4.5.20/tester/res/register.txt     2020-10-22 16:31:51.000000000 
+0200
+++ new/belr-5.0.36/tester/res/register.txt     2021-09-16 11:45:16.000000000 
+0200
@@ -9,6 +9,7 @@
 Contact: 
<sip:smorlat2@78.220.48.77:41076;transport=tls>;+sip.instance="<urn:uuid:2d839989-0bf2-49ba-80b7-2146037f729a>"
 Expires: 3600
 User-Agent: Linphone/3.7.0 (belle-sip/1.3.3)
+CustomHeader: some-custom-value
 Content-Length: 0
 Authorization:  Digest realm="siptest.linphone.org", 
nonce="f5Zb2AAAAABXkU1AAAD253sZEAsAAAAA", algorithm=MD5, opaque="+GNywA==", 
username="smorlat2",  uri="sip:siptest.linphone.org", 
response="f86327204e4c826f47d761c9ad3afdb3", cnonce="faaa9595", nc=00000001, 
qop=auth
 

Reply via email to