From 14bfdb3df5e7536a7244ed26e94f756635530cfc Mon Sep 17 00:00:00 2001
From: Rene Brun <Rene.Brun@cern.ch>
Date: Tue, 4 Jul 2006 04:38:49 +0000
Subject: [PATCH] From Wim:  o) rewrote parsing of class names to locate and
 build scopes

git-svn-id: http://root.cern.ch/svn/root/trunk@15674 27541ba8-7e3a-0410-8455-c3a389f83636
---
 pyroot/src/RootWrapper.cxx | 41 ++++++++++++++++++++++----------------
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/pyroot/src/RootWrapper.cxx b/pyroot/src/RootWrapper.cxx
index dd3be4a94db..858a7a1ce27 100644
--- a/pyroot/src/RootWrapper.cxx
+++ b/pyroot/src/RootWrapper.cxx
@@ -1,4 +1,4 @@
-// @(#)root/pyroot:$Name:  $:$Id: RootWrapper.cxx,v 1.43 2006/04/06 05:38:31 brun Exp $
+// @(#)root/pyroot:$Name:  $:$Id: RootWrapper.cxx,v 1.44 2006/05/28 19:05:24 brun Exp $
 // Author: Wim Lavrijsen, Apr 2004
 
 // Bindings
@@ -459,21 +459,24 @@ PyObject* PyROOT::MakeRootClassFromString( const std::string& fullname, PyObject
 
 // locate the scope, if necessary, for building the class if not specified
    if ( ! scope ) {
-   // cut template part, if present
-      std::string genName = name.substr( 0, name.find( "<" ) );
-
-   // drop class name (i.e. only collect actual scopes here)
-      std::string::size_type last = genName.rfind( "::" );
-      if ( last != 0 && last != std::string::npos ) {
-         scName = genName.substr( 0, last );
-         name = name.substr( last + 2, std::string::npos );
-      }
+   // need to deal with template paremeters that can have scopes themselves
+      Int_t tpl_open = 0;
+      std::string::size_type last = 0;
+      for ( std::string::size_type pos = 0; pos < name.size(); ++pos ) {
+         std::string::value_type c = name[ pos ];
+
+      // count '<' and '>' to be able to skip template contents
+         if ( c == '<' )
+            ++tpl_open;
+         else if ( c == '>' )
+            --tpl_open;
+
+      // by only checking for "::" the last part (class name) is dropped
+         else if ( tpl_open == 0 &&\
+              c == ':' && pos+1 < name.size() && name[ pos+1 ] == ':' ) {
+         // found a new scope part
+            std::string part = name.substr( last, pos );
 
-      if ( scName != "" ) {
-         std::string::size_type pos = 0;
-         do {
-            last = scName.find( "::", pos );
-            std::string part = scName.substr( pos, last == std::string::npos ? last : last - pos );
             PyObject* next = PyObject_GetAttrString(
                scope ? scope : gRootModule, const_cast< char* >( part.c_str() ) );
 
@@ -486,9 +489,13 @@ PyObject* PyROOT::MakeRootClassFromString( const std::string& fullname, PyObject
             if ( ! next )             // create failed, give up
                return 0;
 
+         // found scope part
             scope = next;
-            pos = last + 2;
-         } while ( last != std::string::npos );
+
+         // done with part (note that pos is moved one ahead here)
+            last = pos+2; ++pos;
+         }
+
       }
    }
 
-- 
GitLab