* Bug 15215 fixed: Wrong concatenation of empty strings 28/19428/3
Antoine ELIAS [Mon, 25 Sep 2017 13:04:47 +0000 (15:04 +0200)]
Change-Id: If23ad726408df324b6a7705e6a3501a58d705396

scilab/CHANGES.md
scilab/modules/string/sci_gateway/cpp/sci_strcat.cpp
scilab/modules/string/tests/unit_tests/strcat.dia.ref [deleted file]
scilab/modules/string/tests/unit_tests/strcat.tst

index 67bd6b4..86670fd 100644 (file)
@@ -463,6 +463,7 @@ the [development mailing list](dev@lists.scilab.org) for a particular toolbox.
 * [#15199](http://bugzilla.scilab.org/show_bug.cgi?id=15199): Scilab crashed when using `fsolve` for functions containing other functions.
 * [#15205](http://bugzilla.scilab.org/show_bug.cgi?id=15205): `get_scicos_version` returned the previous version.
 * [#15207](http://bugzilla.scilab.org/show_bug.cgi?id=15207): `xcos(scs_m)` did not work for sub-systems.
+* [#15215](http://bugzilla.scilab.org/show_bug.cgi?id=15215): `strcat` did not work correctly with empty strings.
 * [#15223](http://bugzilla.scilab.org/show_bug.cgi?id=15223): `call` crashed in some cases.
 * [#15228](http://bugzilla.scilab.org/show_bug.cgi?id=15228): `get` error message fixed.
 * [#15236](http://bugzilla.scilab.org/show_bug.cgi?id=15236): The `isglobal` help page was inaccurate. Examples were erroneous.
index ff165ed..e44a112 100644 (file)
@@ -91,7 +91,7 @@ types::Function::ReturnValue sci_strcat(types::typed_list &in, int _iRetCount, t
                 iMode = 2;
                 break;
             default :
-                Scierror(999, _("%s: Wrong type for input argument #%d: ''%s'' or ''%s'' expected.\n"), "strcat", 3, "c", "r");
+                Scierror(999, _("%s: Wrong type for input argument #%d: '%s' or '%s' expected.\n"), "strcat", 3, "c", "r");
                 return types::Function::Error;
         }
     }
@@ -115,28 +115,46 @@ types::Function::ReturnValue sci_strcat(types::typed_list &in, int _iRetCount, t
         case 0 : //"*"
         {
             pOut = new types::String(1, 1);
+
+            int size = pS->getSize();
+            wchar_t** s = pS->get();
+
+            int insertLen = 0;
+            if (pwstToInsert)
+            {
+                insertLen = (int)wcslen(pwstToInsert);
+            }
+
             /*compute final size*/
             int iLen = 1; //L'\0'
-            for (int i = 0 ; i < pS->getSize() ; i++)
+            for (int i = 0 ; i < size ; i++)
             {
-                iLen += (int)wcslen(pS->get(i));
+                iLen += (int)wcslen(s[i]);
             }
 
             if (pwstToInsert != NULL)
             {
-                iLen += (int)wcslen(pwstToInsert) * (pS->getSize() - 1);
+                iLen += insertLen * (size - 1);
             }
 
             wchar_t* pwstOut = (wchar_t*)MALLOC(sizeof(wchar_t) * iLen);
             pwstOut[0] = L'\0';
-            for (int i = 0 ; i < pS->getSize() ; i++)
+
+            wcscpy(pwstOut, s[0]);
+            if (pwstToInsert)
             {
-                size_t iOffset = wcslen(pwstOut);
-                if (iOffset != 0 && pwstToInsert != NULL)
+                for (int i = 1; i < size; ++i)
                 {
-                    wcscat(pwstOut + iOffset, pwstToInsert);
+                    wcscat(pwstOut, pwstToInsert);
+                    wcscat(pwstOut, s[i]);
+                }
+            }
+            else
+            {
+                for (int i = 1; i < size; ++i)
+                {
+                    wcscat(pwstOut, s[i]);
                 }
-                wcscat(pwstOut + iOffset, pS->get(i));
             }
 
             pOut->set(0, pwstOut);
@@ -145,33 +163,52 @@ types::Function::ReturnValue sci_strcat(types::typed_list &in, int _iRetCount, t
         break;
         case 1 : //"r"
         {
-            pOut = new types::String(1, pS->getCols());
+            wchar_t** s = pS->get();
+            int cols = pS->getCols();
+            int rows = pS->getRows();
+
+            pOut = new types::String(1, cols);
+
+            int insertLen = 0;
+            if (pwstToInsert)
+            {
+                insertLen = (int)wcslen(pwstToInsert);
+            }
+            
             /*compute final size*/
-            for (int i = 0 ; i < pS->getCols() ; i++)
+            for (int i = 0 ; i < cols ; ++i)
             {
                 int iLen = 1; //L'\0'
-                for (int j = 0 ; j < pS->getRows() ; j++)
+                for (int j = 0 ; j < rows; ++j)
                 {
-                    iLen += (int)wcslen(pS->get(j, i));
+                    iLen += (int)wcslen(s[i * rows + j]);
                 }
 
                 if (pwstToInsert != NULL)
                 {
-                    iLen += (int)wcslen(pwstToInsert) * (pS->getRows() - 1);
+                    iLen += insertLen * (rows - 1);
                 }
 
                 wchar_t* pwstOut = (wchar_t*)MALLOC(sizeof(wchar_t) * iLen);
                 pwstOut[0] = L'\0';
 
-                for (int j = 0 ; j < pS->getRows() ; j++)
+                wcscpy(pwstOut, s[i * rows]);
+                if (pwstToInsert)
                 {
-                    size_t iOffset = wcslen(pwstOut);
-                    if (iOffset != 0 && pwstToInsert != NULL)
+                    for (int j = 1; j < rows; ++j)
                     {
-                        wcscat(pwstOut + iOffset, pwstToInsert);
+                        wcscat(pwstOut, pwstToInsert);
+                        wcscat(pwstOut, s[i * rows + j]);
                     }
-                    wcscat(pwstOut + iOffset, pS->get(j, i));
                 }
+                else
+                {
+                    for (int j = 1; j < rows; ++j)
+                    {
+                        wcscat(pwstOut, s[i * rows + j]);
+                    }
+                }
+
                 pOut->set(0, i, pwstOut);
                 FREE(pwstOut);
             }
@@ -179,33 +216,52 @@ types::Function::ReturnValue sci_strcat(types::typed_list &in, int _iRetCount, t
         }
         case 2 : //"c"
         {
-            pOut = new types::String(pS->getRows(), 1);
+            wchar_t** s = pS->get();
+            int cols = pS->getCols();
+            int rows = pS->getRows();
+
+            pOut = new types::String(rows, 1);
+
+            int insertLen = 0;
+            if (pwstToInsert)
+            {
+                insertLen = (int)wcslen(pwstToInsert);
+            }
+
             /*compute final size*/
-            for (int i = 0 ; i < pS->getRows() ; i++)
+            for (int i = 0 ; i < rows ; ++i)
             {
                 int iLen = 1; //L'\0'
-                for (int j = 0 ; j < pS->getCols() ; j++)
+                for (int j = 0 ; j < cols ; ++j)
                 {
-                    iLen += (int)wcslen(pS->get(i, j));
+                    iLen += (int)wcslen(s[j * rows + i]);
                 }
 
                 if (pwstToInsert != NULL)
                 {
-                    iLen += (int)wcslen(pwstToInsert) * (pS->getCols() - 1);
+                    iLen += insertLen * (cols - 1);
                 }
 
                 wchar_t* pwstOut = (wchar_t*)MALLOC(sizeof(wchar_t) * iLen);
                 pwstOut[0] = L'\0';
 
-                for (int j = 0 ; j < pS->getCols() ; j++)
+                wcscpy(pwstOut, s[i]);
+                if (pwstToInsert)
                 {
-                    size_t iOffset = wcslen(pwstOut);
-                    if (iOffset != 0 && pwstToInsert != NULL)
+                    for (int j = 1; j < cols; ++j)
                     {
-                        wcscat(pwstOut + iOffset, pwstToInsert);
+                        wcscat(pwstOut, pwstToInsert);
+                        wcscat(pwstOut, s[j * rows + i]);
                     }
-                    wcscat(pwstOut + iOffset, pS->get(i, j));
                 }
+                else
+                {
+                    for (int j = 1; j < cols; ++j)
+                    {
+                        wcscat(pwstOut, s[j * rows + i]);
+                    }
+                }
+
                 pOut->set(i, 0, pwstOut);
                 FREE(pwstOut);
             }
diff --git a/scilab/modules/string/tests/unit_tests/strcat.dia.ref b/scilab/modules/string/tests/unit_tests/strcat.dia.ref
deleted file mode 100644 (file)
index d232f66..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-// =============================================================================
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2007-2008 - INRIA
-//
-//  This file is distributed under the same license as the Scilab package.
-// =============================================================================
-// <-- CLI SHELL MODE -->
-//===============================
-// unit tests strcat
-//===============================
-if strcat(['abc','abd','aa','bxe'])<>'abcabdaabxe' then bugmes();quit;end
-//===============================
-if strcat(['abc','abd';'aa','bxe'])<>'abcaaabdbxe' then bugmes();quit;end
-//===============================
-if strcat(['abc';'abd';'aa';'bxe'])<>'abcabdaabxe' then bugmes();quit;end
-//===============================
-if strcat(['abc','abd','aa','bxe'],',')<>'abc,abd,aa,bxe' then bugmes();quit;end
-//===============================
-if strcat('abc')<>'abc' then bugmes();quit;end
-//===============================
-if strcat('abc','sd')<>'abc' then bugmes();quit;end
-//===============================
-if strcat('') <> '' then bugmes();quit;end
-//===============================
-if strcat(['','']) <> '' then bugmes();quit;end
-//===============================
-if strcat('','')<>'' then bugmes();quit;end
-//===============================
-if strcat([])<>[] then bugmes();quit;end
-//===============================
-if strcat([],'')<>[] then bugmes();quit;end
-//===============================
-if execstr('strcat([],3)','errcatch') == 0  then bugmes();quit;end
-//===============================
-if strcat([],'3') <> [] then bugmes();quit;end
-//===============================
-if strcat(['abc','abd','aa','bxe']) <> 'abc'+'abd'+'aa'+'bxe' then bugmes();quit;end
-//===============================
-if strcat(['abc','abd','aa','bxe'],'')<>'abcabdaabxe' then bugmes();quit;end
-//===============================
-fd = mopen(SCI+'/modules/string/tests/unit_tests/text.txt','r');
-txt = mgetl( fd );
-mclose( fd );
-NEW_TXT_A = strcat(txt);
-NEW_TXT = strcat(NEW_TXT_A,'END OF FILE');
-if ( length(NEW_TXT) <>length(NEW_TXT_A) ) then bugmes();quit;end
-//===============================
-if strcat(['abc','abd','aa','bxe'],'| , |')<>'abc| , |abd| , |aa| , |bxe' then bugmes();quit;end
-if length(strcat(['abc','abd','aa','bxe'],'| , |')) <> 26 then bugmes();quit;end
-//===============================
index 2cc3261..12892a2 100644 (file)
@@ -6,47 +6,47 @@
 // =============================================================================
 
 // <-- CLI SHELL MODE -->
+// <-- ENGLISH IMPOSED -->
+// <-- NO CHECK REF -->
 
 //===============================
 // unit tests strcat
 //===============================
-if strcat(['abc','abd','aa','bxe'])<>'abcabdaabxe' then pause,end
-//===============================
-if strcat(['abc','abd';'aa','bxe'])<>'abcaaabdbxe' then pause,end
-//===============================
-if strcat(['abc';'abd';'aa';'bxe'])<>'abcabdaabxe' then pause,end
-//===============================
-if strcat(['abc','abd','aa','bxe'],',')<>'abc,abd,aa,bxe' then pause,end
-//===============================
-if strcat('abc')<>'abc' then pause,end
-//===============================
-if strcat('abc','sd')<>'abc' then pause,end
-//===============================
-if strcat('') <> '' then pause,end
-//===============================
-if strcat(['','']) <> '' then pause,end
-//===============================
-if strcat('','')<>'' then pause,end
-//===============================
-if strcat([])<>[] then pause,end
-//===============================
-if strcat([],'')<>[] then pause,end
-//===============================
-if execstr('strcat([],3)','errcatch') == 0  then pause,end
-//===============================
-if strcat([],'3') <> [] then pause,end
-//===============================
-if strcat(['abc','abd','aa','bxe']) <> 'abc'+'abd'+'aa'+'bxe' then pause,end
-//===============================
-if strcat(['abc','abd','aa','bxe'],'')<>'abcabdaabxe' then pause,end
-//===============================
-fd = mopen(SCI+'/modules/string/tests/unit_tests/text.txt','r');
-txt = mgetl( fd );
-mclose( fd );
-NEW_TXT_A = strcat(txt);
-NEW_TXT = strcat(NEW_TXT_A,'END OF FILE');
-if ( length(NEW_TXT) <>length(NEW_TXT_A) ) then pause,end
-//===============================
-if strcat(['abc','abd','aa','bxe'],'| , |')<>'abc| , |abd| , |aa| , |bxe' then pause,end
-if length(strcat(['abc','abd','aa','bxe'],'| , |')) <> 26 then pause,end
-//===============================
+msg = sprintf(_("%s: Wrong number of input arguments: %d or %d expected.\n"), "strcat", 1, 3);
+assert_checkerror("strcat()", msg);
+
+msg = sprintf(_("%s: Wrong type for input argument #%d: String expected.\n"), "strcat", 1);
+assert_checkerror("strcat(%f)", msg);
+
+msg = sprintf(_("%s: Wrong type for input argument #%d: ''%s'' or ''%s'' expected.\n"), "strcat", 3, "c", "r");
+assert_checkerror("strcat(""test"", """", ""f"")", msg);
+
+msg = sprintf(_("%s: Wrong type for input argument #%d: Matrix of strings expected.\n"), "strcat", 2);
+assert_checkerror("strcat([],3)", msg);
+
+assert_checkequal(strcat(["abc" "abd","aa" "bxe"]), "abcabdaabxe");
+assert_checkequal(strcat(["abc";"abd";"aa";"bxe"]), "abcabdaabxe");
+assert_checkequal(strcat(["abc" "abd";"aa" "bxe"]), "abcaaabdbxe");
+
+assert_checkequal(strcat(["abc","abd","aa","bxe"],","), "abc,abd,aa,bxe");
+assert_checkequal(strcat("abc"), "abc");
+
+assert_checkequal(strcat("abc","sd"), "abc");
+assert_checkequal(strcat(""), "");
+assert_checkequal(strcat(["" ""]), "");
+assert_checkequal(strcat(["";""]), "");
+
+assert_checkequal(strcat([]), []);
+assert_checkequal(strcat([], ""), []);
+assert_checkequal(strcat([], "3"), []);
+
+assert_checkequal(strcat(["abc","abd","aa","bxe"],"--"), "abc--abd--aa--bxe");
+
+assert_checkequal(strcat(["abc" "abd";"aa" "bxe"], '-', 'r'), ["abc-aa" "abd-bxe"]);
+assert_checkequal(strcat(["abc" "abd";"aa" "bxe"], '-', 'c'), ["abc-abd";"aa-bxe"]);
+
+assert_checkequal(strcat(["" "A" "" "B" ""], ","), [",A,,B,"]);
+assert_checkequal(strcat(["";"A";"";"B";""], ","), [",A,,B,"]);
+
+assert_checkequal(strcat(["" "A" "";"B" "" "C"], ",", "r"), [",B" "A," ",C"]);
+assert_checkequal(strcat(["" "A" "";"B" "" "C"], ",", "c"), [",A,";"B,,C"]);