Merge branch 'master' of ssh://git@git.opensuse.org/projects/zypp/libzypp
authorJán Kupec <jkupec@suse.cz>
Thu, 22 Jan 2009 15:28:39 +0000 (16:28 +0100)
committerJán Kupec <jkupec@suse.cz>
Thu, 22 Jan 2009 15:28:39 +0000 (16:28 +0100)
tests/zypp/base/String_test.cc
zypp/base/String.h

index a17aa12..db76e07 100644 (file)
@@ -84,6 +84,30 @@ BOOST_AUTO_TEST_CASE(testsplitEscaped)
    BOOST_CHECK_EQUAL( s, str::joinEscaped( v.begin(), v.end(), 'o' ) );
 }
 
+BOOST_AUTO_TEST_CASE(testsplitEscapedWithEmpty)
+{
+  string s( "simple:non-escaped:string" );
+  vector<string> v;
+
+  BOOST_CHECK_EQUAL(splitFieldsEscaped(s, std::back_inserter(v)), 3);
+  BOOST_CHECK_EQUAL(v.size(), 3);
+
+  v.clear();
+  s = "non-escaped:with::spaces:";
+  BOOST_CHECK_EQUAL(splitFieldsEscaped(s, std::back_inserter(v)), 5);
+  BOOST_CHECK_EQUAL(v.size(), 5);
+
+  v.clear();
+  s = "::";
+  BOOST_CHECK_EQUAL(splitFieldsEscaped(s, std::back_inserter(v)), 3);
+  BOOST_CHECK_EQUAL(v.size(), 3);
+
+  v.clear();
+  s = ":escaped::with\\:spaces";
+  BOOST_CHECK_EQUAL(splitFieldsEscaped(s, std::back_inserter(v)), 4);
+  BOOST_CHECK_EQUAL(v.size(), 4);
+}
+
 BOOST_AUTO_TEST_CASE(test_escape)
 {
   string badass = "bad|ass\\|worse";
index a562f97..1c306a5 100644 (file)
@@ -372,19 +372,43 @@ namespace zypp
      * "quoted line" -> 1 element same as above
      * 'quoted line' -> 1 element same as above
      * "escaped quote\'" -> 1 element ( "escaped quote'" )
+     *
+     * \param line_r   The string to parse.
+     * \param result_r
+     * \param sepchars_r  String of separator characters.
+     * \param withEmpty   Whether to include empty fields between separators in the result.
+     *
      * \endcode
-    */
+     */
     template<class _OutputIterator>
       unsigned splitEscaped( const C_Str &   line_r,
                       _OutputIterator result_r,
-                      const C_Str &   sepchars_r = " \t" )
+                      const C_Str &   sepchars_r = " \t",
+                      bool withEmpty = false)
       {
         const char * beg = line_r;
         const char * cur = beg;
+        unsigned ret = 0;
+
         // skip leading sepchars
         while ( *cur && ::strchr( sepchars_r, *cur ) )
+        {
           ++cur;
-        unsigned ret = 0;
+          if (withEmpty)
+          {
+            *result_r = "";
+            ++ret;
+          }
+        }
+
+        // there were only sepchars in the string
+        if (!*cur && withEmpty)
+        {
+          *result_r = "";
+          return ++ret;
+        }
+
+        // after the leading sepchars
         for ( beg = cur; *beg; beg = cur, ++result_r, ++ret )
           {
             if ( *cur == '"'  || *cur == '\'' )
@@ -452,8 +476,23 @@ namespace zypp
               *result_r = s;
             }
             // skip sepchars
+            if ( *cur && ::strchr( sepchars_r, *cur ) )
+              ++cur;
             while ( *cur && ::strchr( sepchars_r, *cur ) )
+            {
               ++cur;
+              if (withEmpty)
+              {
+                *result_r = "";
+                ++ret;
+              }
+            }
+            // the last was a separator => one more field
+            if ( !*cur && withEmpty && ::strchr( sepchars_r, *(cur-1) ) )
+            {
+              *result_r = "";
+              ++ret;
+            }
           }
         return ret;
       }
@@ -471,7 +510,7 @@ namespace zypp
      * ":a:"     -> words 3  ||a||
      *
      * \endcode
-    *
+     *
      * \code
      * std::vector<std::string> words;
      * str::split( "some line", std::back_inserter(words) )
@@ -508,6 +547,22 @@ namespace zypp
           }
         return ret;
       }
+
+    /**
+     * Split \a line_r into fields handling also escaped separators.
+     *
+     * \see splitFields()
+     * \see splitEscaped()
+     */
+    template<class _OutputIterator>
+      unsigned splitFieldsEscaped( const C_Str &   line_r,
+                            _OutputIterator result_r,
+                            const C_Str &   sepchars_r = ":" )
+      {
+        return
+          splitEscaped( line_r, result_r, sepchars_r, true /* withEmpty */ );
+      }
+
     //@}
 
     ///////////////////////////////////////////////////////////////////