Author: jreidinger
Date: Fri Apr 4 13:57:54 2008
New Revision: 9373
URL: http://svn.opensuse.org/viewcvs/zypp?rev=9373&view=rev
Log:
add split with respect to escaped delimeters and also for quotes
Added:
trunk/libzypp/tests/zypp/base/String_test.cc
Modified:
trunk/libzypp/tests/zypp/base/CMakeLists.txt
trunk/libzypp/zypp/base/String.h
Modified: trunk/libzypp/tests/zypp/base/CMakeLists.txt
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/tests/zypp/base/CMakeLists.txt?rev=9373&r1=9372&r2=9373&view=diff
==============================================================================
--- trunk/libzypp/tests/zypp/base/CMakeLists.txt (original)
+++ trunk/libzypp/tests/zypp/base/CMakeLists.txt Fri Apr 4 13:57:54 2008
@@ -1,3 +1,4 @@
ADD_TESTS(Sysconfig )
+ADD_TESTS(String )
ADD_TESTS( InterProcessMutex InterProcessMutex2 )
Added: trunk/libzypp/tests/zypp/base/String_test.cc
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/tests/zypp/base/String_test.cc?rev=9373&view=auto
==============================================================================
--- trunk/libzypp/tests/zypp/base/String_test.cc (added)
+++ trunk/libzypp/tests/zypp/base/String_test.cc Fri Apr 4 13:57:54 2008
@@ -0,0 +1,47 @@
+#include <string>
+#include <vector>
+#include <iterator>
+
+#include
+
+#include "zypp/base/String.h"
+
+using boost::unit_test::test_suite;
+using boost::unit_test::test_case;
+using namespace boost::unit_test;
+
+using namespace std;
+using namespace zypp;
+using namespace zypp::str;
+
+BOOST_AUTO_TEST_CASE(testsplitEscaped)
+{
+ string s( "simple non-escaped string" );
+ vector<string> v;
+
+ insert_iterator ii (v,v.end());
+ splitEscaped( s, ii );
+ BOOST_CHECK_EQUAL( v.size(), 3 );
+
+ v.clear();
+ s = string( "\"escaped sentence \"" );
+ ii = insert_iterator( v, v.end() );
+ splitEscaped( s, ii );
+ BOOST_CHECK_EQUAL( v.size(), 1 );
+ BOOST_CHECK_EQUAL( v.front(), string( "escaped sentence " ) );
+
+ v.clear();
+ s = string( "\"escaped \\\\sent\\\"ence \\\\\"" );
+ ii = insert_iterator( v, v.end() );
+ splitEscaped( s, ii );
+ BOOST_CHECK_EQUAL( v.size(), 1 );
+ BOOST_CHECK_EQUAL( v.front(), string( "escaped \\sent\"ence \\" ) );
+
+
+ v.clear();
+ s = string( "escaped sentence\\ with\\ space" );
+ ii = insert_iterator( v, v.end() );
+ splitEscaped( s, ii );
+ BOOST_CHECK_EQUAL( v.size(), 2 );
+ BOOST_CHECK_EQUAL( v[1], string( "sentence with space" ) );
+}
Modified: trunk/libzypp/zypp/base/String.h
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/zypp/base/String.h?rev=9373&r1=9372&r2=9373&view=diff
==============================================================================
--- trunk/libzypp/zypp/base/String.h (original)
+++ trunk/libzypp/zypp/base/String.h Fri Apr 4 13:57:54 2008
@@ -16,6 +16,8 @@
#include <string>
#include
+#include
+
#include "zypp/base/PtrTypes.h"
///////////////////////////////////////////////////////////////////
@@ -321,6 +323,108 @@
}
return ret;
}
+
+ /** Split \a line_r into words with respect to escape delimeters.
+ * Any sequence of characters in \a sepchars_r is treated as
+ * delimiter if not inside "" or "" or escaped by \, but not \\.
+ * The words are passed to OutputIterator \a result_r.
+ * \code
+ * std::vectorstd::string words;
+ * str::splitEscaped( "some line", std::back_inserter(words) )
+ * \endcode
+ *
+ * \code
+ * example splitted strings
+ * normal line -> 2 elements ( "normal", "line" )
+ * escaped\ line -> 1 element( "escaped line" )
+ * "quoted line" -> 1 element same as above
+ * 'quoted line' -> 1 element same as above
+ * "escaped quote\'" -> 1 element ( "escaped quote'" )
+ * \endcode
+ */
+ template<class _OutputIterator>
+ unsigned splitEscaped( const C_Str & line_r,
+ _OutputIterator result_r,
+ const C_Str & sepchars_r = " \t" )
+ {
+ const char * beg = line_r;
+ const char * cur = beg;
+ // skip leading sepchars
+ while ( *cur && ::strchr( sepchars_r, *cur ) )
+ ++cur;
+ unsigned ret = 0;
+ for ( beg = cur; *beg; beg = cur, ++result_r, ++ret )
+ {
+ if ( *cur == '"' || *cur == '\'' )
+ {
+ char closeChar = *cur;
+ ++cur;
+ bool cont = true;
+ while (cont)
+ {
+ while ( *cur && *cur != closeChar)
+ ++cur;
+ if ( *cur == '\0' )
+ {
+ return ret; //TODO parsing exception no closing quote
+ }
+ int escCount = 0;
+ const char * esc = cur-1;
+ while ( esc != beg && *esc == '\\' )
+ {
+ escCount++;
+ --esc;
+ }
+ cont = (escCount % 2 == 1); // find some non escaped escape char
+ cur++; //skip quote
+ }
+
+ std::string s( beg+1, cur-beg-2 ); //without quotes
+ //transform escaped escape
+ boost::replace_all( s, "\\\\", "\\" );
+ //transform escaped quotes (only same as open
+ char tmpn[2] = { closeChar, 0 };
+ char tmpo[3] = { '\\', closeChar, 0 };
+ boost::replace_all( s, tmpo, tmpn );
+
+ *result_r = s;
+ }
+ else
+ {
+ // skip non sepchars
+ while( *cur && !::strchr( sepchars_r, *cur ) )
+ {
+ //ignore char after backslash
+ if ( *cur == '\\' )
+ {
+ ++cur;
+ }
+ ++cur;
+ }
+ // build string
+ std::string s( beg, cur-beg );
+ //transform escaped escape
+ boost::replace_all( s, "\\\\", "\\" );
+
+ const char *delimeter = sepchars_r;
+ while ( *delimeter )
+ {
+ std::string ds("\\");
+ const char tmp[2] = { *delimeter, '\0' };
+ std::string del(tmp);
+ ds+= del;
+ boost::replace_all( s, ds, del );
+ ++delimeter;
+ }
+
+ *result_r = s;
+ }
+ // skip sepchars
+ while ( *cur && ::strchr( sepchars_r, *cur ) )
+ ++cur;
+ }
+ return ret;
+ }
//@}
///////////////////////////////////////////////////////////////////
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org