* Bug #5291 fixed - strtod returned 0 when no real number was detected. 67/10467/5
Charlotte HECQUET [Wed, 13 Feb 2013 14:53:04 +0000 (15:53 +0100)]
Change-Id: I2f033516a6e45781accc8c68838bef819ae40571

scilab/CHANGES_5.4.X
scilab/modules/string/sci_gateway/c/sci_strtod.c
scilab/modules/string/tests/nonreg_tests/bug_5291.dia.ref [new file with mode: 0644]
scilab/modules/string/tests/nonreg_tests/bug_5291.tst [new file with mode: 0644]

index c1d2d64..8ec4201 100644 (file)
@@ -178,6 +178,8 @@ Bug fixes
 * Bug #3313 fixed - In the documentation, the title of a link was using the
                     id instead of the title of the page.
 
+* Bug #5291 fixed - strtod returned 0 when no real number was detected.
+
 * Bug #6583 fixed - jmat() was poorly documented.
 
 * Bug #7058 fixed - There was an error in mathml formula in beta function help.
index 8ab6a4b..a03bffa 100644 (file)
 /*
- * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) INRIA - Allan CORNET
- * 
- * This file must be used under the terms of the CeCILL.
- * This source file is licensed as described in the file COPYING, which
- * you should have received as part of this distribution.  The terms
- * are also available at    
- * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
- *
- */
+* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+* Copyright (C) INRIA - Allan CORNET
+*
+* This file must be used under the terms of the CeCILL.
+* This source file is licensed as described in the file COPYING, which
+* you should have received as part of this distribution.  The terms
+* are also available at
+* http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+*
+*/
 
 /*----------------------------------------------------------------------------*/
-#include <string.h>
 #include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
 #include "gw_string.h"
-#include "stack-c.h"
 #include "MALLOC.h"
 #include "Scierror.h"
 #include "localization.h"
-#include "freeArrayOfString.h"
-#include "stringsstrrchr.h"
+#include "api_scilab.h"
 /*----------------------------------------------------------------------------*/
-int sci_strtod(char *fname,unsigned long fname_len)
+int sci_strtod(char *fname, unsigned long fname_len)
 {
-       CheckRhs(1,1);
-       CheckLhs(1,2);
-
-       if (GetType(1) == sci_strings)
-       {
-               int m1 = 0, n1 = 0;
-               char **Input_StringMatrix_1 = NULL;
-               int m1n1 = 0;
-
-               int x = 0;
-
-               GetRhsVar(1,MATRIX_OF_STRING_DATATYPE,&m1,&n1,&Input_StringMatrix_1);
-               m1n1 = m1 * n1 ;
-
-               if (Lhs == 2)
-               {
-                       double *OutputDoubles = NULL;
-                       char **OutputStrings = NULL;
-
-                       OutputStrings = (char **)MALLOC(sizeof(char*)*m1n1);
-                       if (OutputStrings == NULL)
-                       {
-                               freeArrayOfString(Input_StringMatrix_1,m1n1);
-                               Scierror(999,_("%s: No more memory.\n"),fname);
-                               return 0;
-                       }
-
-                       OutputDoubles = (double*)MALLOC(sizeof(double)*m1n1);
-                       if (OutputDoubles == NULL)
-                       {
-                               FREE(OutputStrings); OutputStrings = NULL;
-                               freeArrayOfString(Input_StringMatrix_1,m1n1);
-                               Scierror(999,_("%s: No more memory.\n"),fname);
-                               return 0;
-                       }
-
-                       for ( x = 0 ; x < m1n1 ; x++ )
-                       {
-                               char *stopstring = NULL;
-                               OutputDoubles[x] = (double)strtod( Input_StringMatrix_1[x], &stopstring);
-
-                               if (stopstring) OutputStrings[x] = (char*)MALLOC(sizeof(char)*(strlen(stopstring)+1));
-                               else OutputStrings[x] = (char*)MALLOC(sizeof(char)*(strlen("")+1));
-
-                               if (OutputStrings[x] == NULL)
-                               {
-                                       freeArrayOfString(Input_StringMatrix_1,m1n1);
-                                       freeArrayOfString(OutputStrings,m1n1);
-                                       if (OutputDoubles) {FREE(OutputDoubles); OutputDoubles = NULL;}
-                                       Scierror(999,_("%s: No more memory.\n"),fname);
-                                       return 0;
-                               }
-
-                               if (stopstring) strcpy(OutputStrings[x],stopstring);
-                               else strcpy(OutputStrings[x],"");
-                       }
-                       CreateVarFromPtr(Rhs+1,MATRIX_OF_DOUBLE_DATATYPE,&m1,&n1,&OutputDoubles);
-                       CreateVarFromPtr(Rhs+2,MATRIX_OF_STRING_DATATYPE,&m1,&n1,OutputStrings);
-
-                       LhsVar(1) = Rhs+1 ;
-                       LhsVar(2) = Rhs+2 ;
-
-                       freeArrayOfString(OutputStrings,m1n1);
-                       if (OutputDoubles) {FREE(OutputDoubles); OutputDoubles = NULL;}
-               }
-               else /* Lhs == 1 */
-               {
-                       int outIndex = 0;
-                       CreateVar(Rhs+1,MATRIX_OF_DOUBLE_DATATYPE,&m1,&n1,&outIndex);
-                       for ( x = 0 ; x < m1n1 ; x++ )
-                       {
-                               char  *stopstring = NULL;
-                               stk(outIndex)[x] = (double)strtod( Input_StringMatrix_1[x], &stopstring);
-                       
-                       }
-                       LhsVar(1) = Rhs+1 ;
-               }
-
-               freeArrayOfString(Input_StringMatrix_1,m1n1);
-               PutLhsVar();
-       }
-       else
-       {
-               Scierror(999,_("%s: Wrong type for input argument #%d: Matrix of strings or empty matrix expected.\n"),fname,1);
-       }
-       return 0;
+    SciErr sciErr;
+    int* piAddr = NULL;
+    int iRows = 0, iCols = 0;
+    int iRowsiCols = 0;
+    char **Input_StringMatrix_1 = NULL;
+    int first_nb = 0;
+    int x, y; //loop indexes
+    char keys[] = "1234567890";
+    unsigned long long raw = 0x7ff8000000000000;
+    double not_a_number = *( double* )&raw;
+    int flag = 0;
+
+    CheckInputArgument(pvApiCtx, 1, 1);
+    CheckOutputArgument(pvApiCtx, 1, 2);
+
+    //get variable address
+    sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
+    if (sciErr.iErr)
+    {
+        printError(&sciErr, 0);
+        Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 3);
+        return 0;
+    }
+
+    if (isStringType(pvApiCtx, piAddr) == 0) //Check type
+    {
+        Scierror(999, _("%s: Wrong type for input argument #%d: Matrix of strings or empty matrix expected.\n"), fname, 1);
+        return 0;
+    }
+
+    if (getAllocatedMatrixOfString(pvApiCtx, piAddr, &iRows, &iCols, &Input_StringMatrix_1))
+    {
+        return 0;
+    }
+
+    iRowsiCols = iRows * iCols;
+
+    if (nbOutputArgument(pvApiCtx) == 2)
+    {
+        double *OutputDoubles = NULL;
+        char **OutputStrings = NULL;
+
+        OutputStrings = (char **)MALLOC(sizeof(char*)*iRowsiCols);
+        if (OutputStrings == NULL)
+        {
+            freeAllocatedMatrixOfString(iRows, iCols, Input_StringMatrix_1);
+            Scierror(999, _("%s: No more memory.\n"), fname);
+            return 0;
+        }
+
+        OutputDoubles = (double*)MALLOC(sizeof(double) * iRowsiCols);
+        if (OutputDoubles == NULL)
+        {
+            FREE(OutputStrings);
+            OutputStrings = NULL;
+            freeAllocatedMatrixOfString(iRows, iCols, Input_StringMatrix_1);
+            Scierror(999, _("%s: No more memory.\n"), fname);
+            return 0;
+        }
+
+        for ( x = 0 ; x < iRowsiCols ; x++ )
+        {
+            //Double part
+            char *stopstring = NULL;
+            first_nb = (int)strcspn(Input_StringMatrix_1[x], keys);
+
+            //Check if there is a number in the string
+            if (first_nb != 0)
+            {
+                flag = 0;
+                for ( y = 0; y < first_nb; y++)
+                {
+                    if (Input_StringMatrix_1[x][y] != ' ')
+                    {
+                        OutputDoubles[x] = not_a_number;
+                        flag = 1;
+                        stopstring = Input_StringMatrix_1[x];
+                    }
+                }
+
+                if (flag == 0)
+                {
+                    OutputDoubles[x] = (double)strtod(Input_StringMatrix_1[x], &stopstring);
+                }
+            }
+            else
+            {
+                OutputDoubles[x] = (double)strtod(Input_StringMatrix_1[x], &stopstring);
+            }
+
+            //String part
+            if (stopstring)
+            {
+                OutputStrings[x] = (char*)MALLOC(sizeof(char) * (strlen(stopstring) + 1));
+            }
+            else
+            {
+                OutputStrings[x] = (char*)MALLOC(sizeof(char) * (strlen("") + 1));
+            }
+
+            if (OutputStrings[x] == NULL)
+            {
+                freeAllocatedMatrixOfString(iRows, iCols, Input_StringMatrix_1);
+                freeAllocatedMatrixOfString(iRows, iCols, OutputStrings);
+                FREE(OutputDoubles);
+                OutputDoubles = NULL;
+                Scierror(999, _("%s: No more memory.\n"), fname);
+                return 0;
+            }
+
+            if (stopstring)
+            {
+                strcpy(OutputStrings[x], stopstring);
+            }
+            else
+            {
+                strcpy(OutputStrings[x], "");
+            }
+        }
+
+        sciErr = createMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, iRows, iCols, OutputDoubles);
+        if (sciErr.iErr)
+        {
+            printError(&sciErr, 0);
+            Scierror(999, _("%s: Memory allocation error.\n"), fname);
+            return 0;
+        }
+
+        sciErr = createMatrixOfString(pvApiCtx, nbInputArgument(pvApiCtx) + 2, iRows, iCols, (char**)OutputStrings);
+        if (sciErr.iErr)
+        {
+            printError(&sciErr, 0);
+            Scierror(999, _("%s: Memory allocation error.\n"), fname);
+            return 0;
+        }
+
+        AssignOutputVariable(pvApiCtx, 1) = nbInputArgument(pvApiCtx) + 1;
+        AssignOutputVariable(pvApiCtx, 2) = nbInputArgument(pvApiCtx) + 2;
+
+        freeAllocatedMatrixOfString(iRows, iCols, OutputStrings);
+        FREE(OutputDoubles);
+    }
+    else /* nbOutputArgument(pvApiCtx) == 1 */
+    {
+        double* pdblOutIndex = NULL;
+
+        sciErr = allocMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, iRows, iCols, &pdblOutIndex);
+        if (sciErr.iErr)
+        {
+            printError(&sciErr, 0);
+            Scierror(999, _("%s: Memory allocation error.\n"), fname);
+            return 0;
+        }
+
+        for ( x = 0 ; x < iRowsiCols ; x++ )
+        {
+            char  *stopstring = NULL;
+            first_nb = (int)strcspn(Input_StringMatrix_1[x], keys);
+
+            //Check if there is a number in the string
+            if (first_nb != 0)
+            {
+                flag = 0;
+                for ( y = 0 ; y < first_nb ; y++)
+                {
+                    if (Input_StringMatrix_1[x][y] != ' ')
+                    {
+                        pdblOutIndex[x] = not_a_number;
+                        flag = 1;
+                    }
+                }
+
+                if (flag == 0)
+                {
+                    pdblOutIndex[x] = (double)strtod( Input_StringMatrix_1[x], &stopstring);
+                }
+            }
+            else
+            {
+                pdblOutIndex[x] = (double)strtod( Input_StringMatrix_1[x], &stopstring);
+            }
+
+        }
+
+        AssignOutputVariable(pvApiCtx, 1) = nbInputArgument(pvApiCtx) + 1 ;
+    }
+
+    freeAllocatedMatrixOfString(iRows, iCols, Input_StringMatrix_1);
+    ReturnArguments(pvApiCtx);
+    return 0;
 }
 /*--------------------------------------------------------------------------*/
+
diff --git a/scilab/modules/string/tests/nonreg_tests/bug_5291.dia.ref b/scilab/modules/string/tests/nonreg_tests/bug_5291.dia.ref
new file mode 100644 (file)
index 0000000..a7c80cc
--- /dev/null
@@ -0,0 +1,22 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Charlotte HECQUET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+//
+// <-- Non-regression test for bug 5291 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=5291
+//
+// <-- Short Description -->
+// [R,F]=strtod(S) should return %nan instead of 0 as interpreted real number when
+// no real number can be detected at the beginning of processed strings.
+//
+[R, F]=strtod([ "123" "+i"]);
+assert_checkequal(R(1), 123);
+assert_checktrue(isnan(R(2)));
+assert_checkequal(F, ['' '+i']);
diff --git a/scilab/modules/string/tests/nonreg_tests/bug_5291.tst b/scilab/modules/string/tests/nonreg_tests/bug_5291.tst
new file mode 100644 (file)
index 0000000..dadaefb
--- /dev/null
@@ -0,0 +1,23 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2013 - Scilab Enterprises - Charlotte HECQUET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+//
+// <-- Non-regression test for bug 5291 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=5291
+//
+// <-- Short Description -->
+// [R,F]=strtod(S) should return %nan instead of 0 as interpreted real number when
+// no real number can be detected at the beginning of processed strings.
+//
+
+[R, F]=strtod([ "123" "+i"]);
+assert_checkequal(R(1), 123);
+assert_checktrue(isnan(R(2)));
+assert_checkequal(F, ['' '+i']);