[med-svn] [SCM] aghermann branch, master, updated. 551e213a23b59b71cba6a9c3a282d1b60e21b854

Andrei Zavada johnhommer at gmail.com
Sun Apr 21 23:18:14 UTC 2013


The following commit has been merged in the master branch:
commit a1aa32f1db75783f8644b46ae9238693d9c4e2b2
Author: Andrei Zavada <johnhommer at gmail.com>
Date:   Sun Apr 21 00:16:25 2013 +0300

    agh::str enhancements: reentrant tokens, tokens_trimmed; wstring conv functions

diff --git a/src/common/libcommon.cc b/src/common/libcommon.cc
index be2e3a2..b3ce11e 100644
--- a/src/common/libcommon.cc
+++ b/src/common/libcommon.cc
@@ -18,6 +18,9 @@
 
 #include <unistd.h>
 #include <sys/time.h>
+#include <errno.h>
+#include <wchar.h>
+#include <iconv.h>
 
 #include "globals.hh"
 #include "string.hh"
@@ -64,14 +67,30 @@ pad( const string& r0, size_t to)
 
 list<string>
 agh::str::
-tokens( const string& s_, const char* sep)
+tokens_trimmed( const string& s_, const char* sep)
 {
 	string s {s_};
 	list<string> acc;
-	char *p = strtok( &s[0], sep);
+	char   *pp,
+	       *p = strtok_r( &s[0], sep, &pp);
 	while ( p ) {
 		acc.emplace_back( trim(p));
-		p = strtok( NULL, sep);
+		p = strtok_r( NULL, sep, &pp);
+	}
+	return acc;
+}
+
+list<string>
+agh::str::
+tokens( const string& s_, const char* sep)
+{
+	string s {s_};
+	list<string> acc;
+	char   *pp,
+	       *p = strtok_r( &s[0], sep, &pp);
+	while ( p ) {
+		acc.emplace_back( p);
+		p = strtok_r( NULL, sep, &pp);
 	}
 	return acc;
 }
@@ -210,6 +229,73 @@ dhms_colon( double seconds, int dd)
 
 
 
+wstring
+agh::str::
+to_wstring( const string& in, const char* charset)
+{
+        wstring out;
+
+        size_t sufficient = ((in.size() + 1) * sizeof(wchar_t));
+
+        iconv_t cd = iconv_open( "WCHAR_T", charset);
+        if ( cd == (iconv_t) -1 )
+                return out;
+
+        char    *inptr  = const_cast<char*> (&in[0]), // iconv doesn't touch input, or does it?
+                *wrptr  = (char*)malloc( sufficient),
+                *wrptr0 = wrptr;
+
+        size_t  insize = in.size(),
+                avail  = sufficient;
+        size_t  nconv  = iconv( cd, &inptr, &insize, &wrptr, &avail);
+        if ( nconv != (size_t) -1 ) {
+                if ( avail >= sizeof(wchar_t) ) {
+                        *((wchar_t*) wrptr) = L'\0';
+                        out.assign( (wchar_t*)wrptr0);
+                }
+        }
+
+        free( (void*)wrptr0);
+        if ( iconv_close( cd) != 0 )
+                perror ("iconv_close");
+
+        return out;
+}
+
+
+string
+agh::str::
+from_wstring( const wstring& in, const char* charset)
+{
+        string out;
+
+        size_t sufficient = (in.size() * 4 + 1);
+
+        iconv_t cd = iconv_open( charset, "WCHAR_T");
+        if ( cd == (iconv_t) -1 )
+                return out;
+
+        char    *inptr = (char*) const_cast<wchar_t*> (&in[0]), // yes we can!
+                *wrptr = (char*)malloc( sufficient),
+                *wrptr0 = wrptr;
+
+        size_t  insize = in.size() * sizeof(wchar_t),
+                avail  = sufficient;
+        size_t  nconv  = iconv( cd, &inptr, &insize, &wrptr, &avail);
+        if ( nconv != (size_t) -1 ) {
+                if ( avail > 0 ) {
+                        *wrptr = '\0';
+                        out.assign( wrptr0);
+                }
+        }
+
+        free( wrptr0);
+        iconv_close( cd);
+
+        return out;
+}
+
+
 
 // found to be of use elsewhere
 size_t	agh::fs::__n_edf_files;
diff --git a/src/common/string.hh b/src/common/string.hh
index 144f679..f678642 100644
--- a/src/common/string.hh
+++ b/src/common/string.hh
@@ -45,9 +45,18 @@ join( const C& l, const char* sep)
 
 list<string> tokens( const string& s_, const char* sep);
 inline
-list<string> tokens( const string& s_, char sep)
+list<string> tokens( const string& s_, char c)
 {
-	return tokens( s_, string (sep, 1).c_str());
+	char sep[2] = {c, '\0'};
+	return tokens( s_, sep);
+}
+
+list<string> tokens_trimmed( const string& s_, const char* sep);
+inline
+list<string> tokens_trimmed( const string& s_, char c)
+{
+	char sep[2] = {c, '\0'};
+	return tokens_trimmed( s_, sep);
 }
 
 
@@ -64,6 +73,13 @@ string  tilda2homedir( const string& v);
 string dhms( double seconds, int decimal_digits = 0) __attribute__ ((pure));
 string dhms_colon( double seconds, int decimal_digits = 0) __attribute__ ((pure));
 
+
+// unicode/wcs
+
+wstring to_wstring( const string&, const char* charset = "UTF-8");
+string from_wstring( const wstring&, const char* charset = "UTF-8");
+
+
 }
 }
 
diff --git a/src/tools/edfcat.cc b/src/tools/edfcat.cc
index 108810f..26c4b65 100644
--- a/src/tools/edfcat.cc
+++ b/src/tools/edfcat.cc
@@ -89,7 +89,7 @@ parse_op( int argc, const char* argv[]) throw (invalid_argument)
 		if ( argc != 4 )
 			throw invalid_argument ("Usage: split FILE POS1[,POS2,...]");
 		operands.emplace_back( argv[2]);
-		operands.back().figure_timepoints( agh::str::tokens( argv[3], ","));
+		operands.back().figure_timepoints( agh::str::tokens_trimmed( argv[3], ","));
 
 	} else if ( strcmp( p, "cat")   == 0 ) {
 		operation = TKind::Split;
@@ -116,7 +116,7 @@ parse_op( int argc, const char* argv[]) throw (invalid_argument)
 		if ( argc != 4 )
 			throw invalid_argument ("Usage: prune FILE N1[N2,...]");
 		operands.emplace_back( argv[2]);
-		operands.back().figure_channels( agh::str::tokens( argv[3], ","));
+		operands.back().figure_channels( agh::str::tokens_trimmed( argv[3], ","));
 
 	} else if ( strcmp( p, "merge") == 0 ) {
 		operation = TKind::Merge;
diff --git a/src/ui/mw/simulations.cc b/src/ui/mw/simulations.cc
index 0dae1aa..2f37680 100644
--- a/src/ui/mw/simulations.cc
+++ b/src/ui/mw/simulations.cc
@@ -105,7 +105,7 @@ populate_2()
 							  &virgin);
 				if ( retval ) {
 					gtk_tree_store_set( mSimulations, &iter_h,
-							    1, agh::str::tokens( agh::CProfile::explain_status( retval), ";").front().c_str(),
+							    1, agh::str::tokens_trimmed( agh::CProfile::explain_status( retval), ";").front().c_str(),
 							    msimulations_modref_col, NULL,
 							    -1);
 				} else {
diff --git a/src/ui/mw/simulations_cb.cc b/src/ui/mw/simulations_cb.cc
index 0e62f1c..805e996 100644
--- a/src/ui/mw/simulations_cb.cc
+++ b/src/ui/mw/simulations_cb.cc
@@ -80,9 +80,9 @@ iSimulationsRunBatch_activate_cb( GtkMenuItem*, gpointer userdata)
 		ED.populate_2();
 
 		list<string>
-			use_subjects = agh::str::tokens( gtk_entry_get_text( ED.eBatchSetupSubjects), ";"),
-			use_sessions = agh::str::tokens( gtk_entry_get_text( ED.eBatchSetupSessions), ";"),
-			use_channels = agh::str::tokens( gtk_entry_get_text( ED.eBatchSetupChannels), ";");
+			use_subjects = agh::str::tokens_trimmed( gtk_entry_get_text( ED.eBatchSetupSubjects), ";"),
+			use_sessions = agh::str::tokens_trimmed( gtk_entry_get_text( ED.eBatchSetupSessions), ";"),
+			use_channels = agh::str::tokens_trimmed( gtk_entry_get_text( ED.eBatchSetupChannels), ";");
 		double	freq_from  = gtk_spin_button_get_value( ED.eBatchSetupRangeFrom),
 			freq_width = gtk_spin_button_get_value( ED.eBatchSetupRangeWidth),
 			freq_inc   = gtk_spin_button_get_value( ED.eBatchSetupRangeInc);
diff --git a/src/ui/sm/sm.cc b/src/ui/sm/sm.cc
index 4ffa3ea..91c57e9 100644
--- a/src/ui/sm/sm.cc
+++ b/src/ui/sm/sm.cc
@@ -253,7 +253,7 @@ read_sessionrc()
 		string entries_;
 		conf.lookupValue( "SessionList", entries_);
 
-		list<string> entries {agh::str::tokens( &entries_[0], ";")};
+		list<string> entries {agh::str::tokens_trimmed( &entries_[0], ";")};
 		if ( entries.empty() )
 			throw runtime_error ("add a cwd then");
 		for ( auto &E : entries ) {

-- 
Sleep experiment manager



More information about the debian-med-commit mailing list