strtok fixed 01/18701/5
Cedric Delamarre [Mon, 21 Nov 2016 11:00:55 +0000 (12:00 +0100)]
Change-Id: I80ba0e2062213cde615e3feb48b09edf24cb84ab

scilab/modules/string/includes/string_gw.hxx
scilab/modules/string/sci_gateway/cpp/sci_strtok.cpp
scilab/modules/string/sci_gateway/cpp/string_gw.cpp
scilab/modules/string/src/c/os_wcstok.c
scilab/modules/string/tests/unit_tests/strtok.dia.ref
scilab/modules/string/tests/unit_tests/strtok.tst

index ac704f2..f53a2a0 100644 (file)
@@ -20,6 +20,7 @@
 #include "dynlib_string_gw.h"
 
 #include "cpp_gateway_prototype.hxx"
+#include "sci_malloc.h"
 
 class StringModule
 {
@@ -30,8 +31,13 @@ public :
     EXTERN_STRING_GW static int Load();
     EXTERN_STRING_GW static int Unload()
     {
+        deleteToken();
         return 1;
     }
+
+    static wchar_t* pwstToken;
+    static wchar_t* setToken(wchar_t* _base);
+    static void deleteToken();
 };
 
 CPP_GATEWAY_PROTOTYPE(sci_grep);
index b15eafc..04a101a 100644 (file)
@@ -15,6 +15,7 @@
 
 
 #include "function.hxx"
+#include "double.hxx"
 #include "string.hxx"
 #include "list.hxx"
 #include "funcmanager.hxx"
@@ -26,16 +27,15 @@ extern "C"
 #include "localization.h"
 #include "Scierror.h"
 #include "os_string.h"
+#include "os_wcstok.h"
 #include <stdio.h>
 }
 
-static wchar_t *pwstState = NULL;
-static /* const */ wchar_t EOS = 0;
-
 types::Function::ReturnValue sci_strtok(types::typed_list &in, int _iRetCount, types::typed_list &out)
 {
-    types::String* pOutString   = NULL;
-    wchar_t* pwstString         = NULL;
+    static wchar_t *pwstState  = NULL;
+    wchar_t *pwstString = NULL;
+
     wchar_t* pwstSeps           = NULL;
     int dims                    = 2;
     int dimsArray[2]            = {1, 1};
@@ -64,21 +64,19 @@ types::Function::ReturnValue sci_strtok(types::typed_list &in, int _iRetCount, t
         return types::Function::Error;
     }
 
-
     if (in.size() == 1)
     {
         pwstSeps    = in[0]->getAs<types::String>()->get(0);
     }
     else
     {
-        pwstString  = in[0]->getAs<types::String>()->get(0);
+        pwstString = StringModule::setToken(in[0]->getAs<types::String>()->get()[0]);
         pwstSeps    = in[1]->getAs<types::String>()->get(0);
         pwstState   = NULL;
+
         if (wcslen(pwstString) == 0)
         {
-            pOutString  = new types::String(dims, dimsArray);
-            pOutString->set(0, L"");
-            out.push_back(pOutString);
+            out.push_back(new types::String(L""));
             return types::Function::OK;
         }
     }
@@ -87,29 +85,23 @@ types::Function::ReturnValue sci_strtok(types::typed_list &in, int _iRetCount, t
     if (pwstString == NULL && pwstState == NULL)
     {
         // set an empty string
-        pwstToken = &EOS;
+        pwstToken = L"";
     }
     else
     {
-#ifndef _MSC_VER
-        pwstToken = wcstok(pwstString, pwstSeps, &pwstState);
-#else
-        pwstToken = wcstok_s(pwstString, pwstSeps, &pwstState);
-#endif
+        pwstToken = os_wcstok(pwstString, pwstSeps, &pwstState);
     }
 
-    pOutString  = new types::String(dims, dimsArray);
-
     if (pwstToken)
     {
-        pOutString->set(0, pwstToken);
+        out.push_back(new types::String(pwstToken));
     }
     else
     {
-        pOutString->set(0, L"");
+        StringModule::deleteToken();
+        out.push_back(new types::String(L""));
     }
 
-    out.push_back(pOutString);
     return types::Function::OK;
 }
 
index ce4d63a..87b038e 100644 (file)
@@ -26,6 +26,8 @@
 
 #define MODULE_NAME L"string"
 
+wchar_t* StringModule::pwstToken = NULL;
+
 int StringModule::Load()
 {
     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"grep", &sci_grep, MODULE_NAME));
@@ -59,3 +61,22 @@ int StringModule::Load()
     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"csvIsnum", &sci_isnum, MODULE_NAME));
     return 1;
 }
+
+wchar_t* StringModule::setToken(wchar_t* _base)
+{
+    deleteToken();
+
+    // clone because strtok is destructive:
+    // it writes the L'\0' characters in the elements of the origin string.
+    pwstToken = os_wcsdup(_base);
+    return pwstToken;
+}
+
+void StringModule::deleteToken()
+{
+    if (pwstToken)
+    {
+        FREE(pwstToken);
+        pwstToken = NULL;
+    }
+}
index 618a106..19d66f5 100644 (file)
 #include "os_wcstok.h"
 
 
-wchar_t *os_wcstok(wchar_t *_pwstData, const wchar_t *_pwstDelim, wchar_t** _pswtState)
+wchar_t *os_wcstok(wchar_t *_pwstData, const wchar_t *_pwstDelim, wchar_t** _pwstState)
 {
 #ifndef _MSC_VER
-    return wcstok(_pwstData, _pwstDelim, _pswtState);
+    return wcstok(_pwstData, _pwstDelim, _pwstState);
 #else
-    return wcstok(_pwstData, _pwstDelim);
+    return wcstok_s(_pwstData, _pwstDelim, _pwstState);
 #endif
 }
index 7d37437..1355df8 100644 (file)
@@ -13,13 +13,15 @@ if strtok('','') <> '' then bugmes();quit;end
 if strtok('','a') <> '' then bugmes();quit;end
 if strtok('a') <> '' then bugmes();quit;end
 //=================================================
+REF = "A string of tokens and some more tokens ";
 TOKENS = [];
-token = strtok("A string of ,,tokens and some  more tokens"," ,");
-TOKENS = [TOKENS,token];
-while( token <> '' )
+A = "A string of ,,tokens and some  more tokens";
+token = strtok(A, " ,");
+TOKENS = [TOKENS token];
+while token <> ''
   token = strtok(" ,");
-  TOKENS = [TOKENS,token];
+  TOKENS = [TOKENS token];
 end
-REF = 'A string of tokens and some more tokens ';
-if strcat(TOKENS,' ')<> REF then bugmes();quit;end
+if strcat(TOKENS, " ")<> REF then bugmes();quit;end
+if A <> "A string of ,,tokens and some  more tokens" then bugmes();quit;end
 //=================================================
index 9225406..d150f5b 100644 (file)
@@ -15,13 +15,16 @@ if strtok('','') <> '' then pause,end
 if strtok('','a') <> '' then pause,end
 if strtok('a') <> '' then pause,end
 //=================================================
+REF = "A string of tokens and some more tokens ";
 TOKENS = [];
-token = strtok("A string of ,,tokens and some  more tokens"," ,");
-TOKENS = [TOKENS,token];
-while( token <> '' )
+
+A = "A string of ,,tokens and some  more tokens";
+token = strtok(A, " ,");
+TOKENS = [TOKENS token];
+while token <> ''
   token = strtok(" ,");
-  TOKENS = [TOKENS,token];
+  TOKENS = [TOKENS token];
 end
-REF = 'A string of tokens and some more tokens ';
-if strcat(TOKENS,' ')<> REF then pause,end
+if strcat(TOKENS, " ")<> REF then pause,end
+if A <> "A string of ,,tokens and some  more tokens" then pause, end
 //=================================================