The following commit has been merged in the master branch:
commit a1aa32f1db75783f8644b46ae9238693d9c4e2b2
Author: Andrei Zavada <[email protected]>
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

_______________________________________________
debian-med-commit mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/debian-med-commit

Reply via email to