bug 4833 fixed - msprintf() interpreted '\n' as a carriage return even if '\n' is... 91/3091/4
Allan CORNET [Wed, 2 Feb 2011 11:01:28 +0000 (12:01 +0100)]
Change-Id: Id72350ed562f519fdb05ea7fe7fd83ed0117a8f2

scilab/CHANGES_5.4.X
scilab/modules/output_stream/help/en_US/msprintf.xml
scilab/modules/output_stream/sci_gateway/c/sci_msprintf.c
scilab/modules/output_stream/src/c/api_scilab_Import.def
scilab/modules/output_stream/tests/nonreg_tests/bug_4833.dia.ref [new file with mode: 0644]
scilab/modules/output_stream/tests/nonreg_tests/bug_4833.tst [new file with mode: 0644]

index a806e98..a3f106a 100644 (file)
@@ -5,6 +5,9 @@
 Bug Fixes:
 ==========
 
+* bug 4833 fixed - msprintf() interpreted "\n" as a carriage return even if "\n"
+                   is supplied by the 2nd input argument.
+
 * bug 8608 - dec2hex, hex2dec, dec2oct and oct2dec code have been simplified
              and optimized.
 
index 8ee771f..ace173a 100644 (file)
@@ -72,7 +72,7 @@
     <para>The <literal>msprintf</literal> writes formatted operands in its
     returned value (a Scilab string). The argument operands are formatted
     under control of the format operand.</para>
-    <para>Note that, in this case, the escape sequences (<literal>"\n"</literal>) 
+    <para>Note that, in this case, the escape sequences (<literal>"\n"</literal>) (in format)
     split string to a matrix of string (see example)</para>
   </refsection>
 
index 52d87a9..41fa40c 100644 (file)
@@ -1,7 +1,7 @@
 /*
 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 * Copyright (C) INRIA
-* Copyright (C) DIGITEO - 2010 - Allan CORNET
+* Copyright (C) DIGITEO - 2010-2011 - 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
@@ -11,6 +11,7 @@
 *
 */
 #include "gw_output_stream.h"
+#include "api_scilab.h"
 #include "Scierror.h"
 #include "MALLOC.h"
 #include "stack-c.h"
 #include "freeArrayOfString.h"
 #include "strsubst.h"
 /*--------------------------------------------------------------------------*/
-int sci_msprintf(char *fname,unsigned long fname_len)
+#define TAB_CHAR_SEARCHED "\\t"
+#define TAB_CHAR_REPLACED "\t"
+#define PERCENT_CHAR '%'
+#define SPLIT_ON_CR_IN_FORMAT "<CR_IN_FORMAT>"
+#define CR_IN_FORMAT "\\n"
+#define EMPTY_CHAR '\0'
+/*--------------------------------------------------------------------------*/
+int sci_msprintf(char *fname, unsigned long fname_len)
 {
-    char **lstr = NULL;
-    static int l1 = 0, m1 = 0, n1 = 0, n2 = 0, lcount = 0, rval = 0, blk = 200;
-    static int k = 0;
-    char ** strs = NULL;
-    char *str = NULL, *str1 = NULL;
-    int n = 0, nmax = 0, cat_to_last = 0, ll = 0;
-
-    char *ptrFormat   = NULL;
-    int i             = 0;
+    SciErr sciErr;
+    int iType = 0;
+    int *piAddressVarOne = NULL;
+    char *ptrFormat = NULL;
+    int K = 0;
+    int i = 0;
+    int lenghtFormat = 0;
     int NumberPercent = 0;
-    int NumberCols    = 0;
+    int NumberCols = 0;
+    int nmax = 0;
+    int cat_to_last = 0;
+    int ll = 0;
+    char **pStrs = NULL;
+    char **pOutputStrings = NULL;
+    char *pStrTmp = NULL;
+    char *pStrTmp1 = NULL;
+    int lcount = 0;
+    int rval = 0;
+    int blk = 200;
+
+    int k = 0;
+    int mOut = 0;
+    int nOut = 0;
+    int lenghtSplitChar = (int)strlen(SPLIT_ON_CR_IN_FORMAT);
 
     Nbvars = 0;
-    CheckRhs(1,1000);
-    CheckLhs(0,1);
+    CheckRhs(1, 1000);
+    CheckLhs(0, 1);
 
-    if ( Rhs < 1 )
+    for (K = 2; K <= Rhs; K++)
     {
-        Scierror(999,_("%s: Wrong number of input arguments: at least %d expected.\n"),fname,1);
+        int iTypeK = 0;
+        int *piAddressVarK = NULL;
+
+        sciErr = getVarAddressFromPosition(pvApiCtx, K, &piAddressVarK);
+        if(sciErr.iErr)
+        {
+            printError(&sciErr, 0);
+            return 0;
+        }
+
+        sciErr = getVarType(pvApiCtx, piAddressVarK, &iTypeK);
+        if(sciErr.iErr)
+        {
+            printError(&sciErr, 0);
+            return 0;
+        }
+
+        if ( (iTypeK != sci_matrix) && (iTypeK != sci_strings) )
+        {
+            OverLoad(K);
+            return 0;
+        }
+    }
+
+    sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddressVarOne);
+    if(sciErr.iErr)
+    {
+        printError(&sciErr, 0);
+        return 0;
+    }
+
+    sciErr = getVarType(pvApiCtx, piAddressVarOne, &iType);
+    if(sciErr.iErr)
+    {
+        printError(&sciErr, 0);
         return 0;
     }
 
-    for (k=2;k<=Rhs;k++)
+    if (checkVarDimension(pvApiCtx, piAddressVarOne, 1, 1) != 1)
+    {
+        Scierror(999,_("%s: Wrong size for input argument #%d: A string expected.\n"), fname, 1);
+        return 0;
+    }
+
+    if (getAllocatedSingleString(pvApiCtx, piAddressVarOne, &ptrFormat))
+    {
+        Scierror(999,_("%s: Memory allocation error.\n"), fname);
+        return 0;
+    }
+
+    if (ptrFormat == NULL)
+    {
+        Scierror(999,_("%s: Memory allocation error.\n"), fname);
+        return 0;
+    }
+    else
     {
-        if ( (VarType(k) != sci_matrix) && (VarType(k) != sci_strings) )
+        char *pFormatTmp = strsub(ptrFormat, TAB_CHAR_SEARCHED, TAB_CHAR_REPLACED);
+        if (pFormatTmp)
+        {
+            freeAllocatedSingleString(ptrFormat);
+            ptrFormat = strsub(pFormatTmp, CR_IN_FORMAT, SPLIT_ON_CR_IN_FORMAT);
+            FREE(pFormatTmp);
+            if (ptrFormat == NULL)
+            {
+                Scierror(999,_("%s: Memory allocation error.\n"), fname);
+                return 0;
+            }
+        }
+        else
         {
-            OverLoad(k);
+            Scierror(999,_("%s: Memory allocation error.\n"), fname);
             return 0;
         }
     }
 
-    GetRhsVar(1,STRING_DATATYPE,&m1,&n1,&l1);
-
-    ptrFormat = strsub(cstk(l1), "\\t", "\t");
-
-    for( i=0; i<(int)strlen(ptrFormat); i++)
+    lenghtFormat = (int)strlen(ptrFormat);
+    for(i = 0; i < lenghtFormat; i++)
     {
-        if (ptrFormat[i]=='%')
+        if (ptrFormat[i] == PERCENT_CHAR)
         {
             NumberPercent++;
-            if (ptrFormat[i+1]=='%')
+            if ( (i+1 < lenghtFormat) && (ptrFormat[i+1] == PERCENT_CHAR))
             {
-                NumberPercent--;i++;
+                NumberPercent--;
+                i++;
             }
         }
     }
@@ -75,7 +157,8 @@ int sci_msprintf(char *fname,unsigned long fname_len)
             FREE(ptrFormat);
             ptrFormat = NULL;
         }
-        Scierror(999,_("%s: Wrong number of input arguments: at most %d expected.\n"),fname,NumberPercent);
+
+        Scierror(999,_("%s: Wrong number of input arguments: at most %d expected.\n"), fname, NumberPercent);
         return 0;
     }
 
@@ -83,10 +166,24 @@ int sci_msprintf(char *fname,unsigned long fname_len)
     {
         for( i = 2 ; i <= Rhs ; i++ )
         {
-            int mk = 0;
-            int nk = 0;
-            GetMatrixdims(i,&mk,&nk);
-            NumberCols += nk;
+            int iRows = 0;
+            int iCols = 0;
+            int *piAddressVarI = NULL;
+
+            sciErr = getVarAddressFromPosition(pvApiCtx, i, &piAddressVarI);
+            if(sciErr.iErr)
+            {
+                printError(&sciErr, 0);
+                return 0;
+            }
+
+            sciErr = getVarDimension(pvApiCtx, piAddressVarI, &iRows, &iCols);
+            if(sciErr.iErr)
+            {
+                printError(&sciErr, 0);
+                return 0;
+            }
+            NumberCols += iCols;
         }
     }
 
@@ -97,54 +194,59 @@ int sci_msprintf(char *fname,unsigned long fname_len)
             FREE(ptrFormat);
             ptrFormat = NULL;
         }
-        Scierror(999,_("%s: Wrong number of input arguments: data doesn't fit with format.\n"),fname);
+        Scierror(999,_("%s: Wrong number of input arguments: data doesn't fit with format.\n"), fname);
         return 0;
     }
 
-    n           = 0; /* output line counter */
-    nmax        = 0;
-    strs        = NULL;
-    lcount      = 1;
+    mOut = 0; /* output line counter */
+    nmax = 0;
+    pOutputStrings = NULL;
+    lcount = 1;
     cat_to_last = 0;
 
     while (1)
     {
-        if ((rval = do_xxprintf("msprintf",(FILE *) 0, ptrFormat, Rhs, 1, lcount,(char **) &lstr)) < 0) break;
+        if ((rval = do_xxprintf("msprintf",(FILE *) 0, ptrFormat, Rhs, 1, lcount, (char **) &pStrs)) < 0) 
+        {
+            break;
+        }
 
         lcount++;
-        str =(char *) lstr;
-        if ( str == NULL )
+        pStrTmp = (char *)pStrs;
+        if (pStrTmp == NULL)
         {
             if (ptrFormat)
             {
                 FREE(ptrFormat);
                 ptrFormat = NULL;
             }
+
             Scierror(999,_("%s: Wrong value of input argument %d: data doesn't fit with format.\n"),fname,1);
             return 0;
         }
-        str1 = str;
-        while (*str != '\0')  
+
+        pStrTmp1 = pStrTmp;
+        while (*pStrTmp != '\0')  
         {
-            if (strncmp(str,"\\n",2) ==0) 
+            if (strncmp(pStrTmp, SPLIT_ON_CR_IN_FORMAT, lenghtSplitChar) ==0) 
             {
-                k = (int)(str - str1);
-                if (! cat_to_last) 
+                k = (int)(pStrTmp - pStrTmp1);
+                if (!cat_to_last) 
                 { 
                     /*add a new line */
-                    if (n==nmax) 
+                    if (mOut == nmax) 
                     {
-                        nmax+=blk;
-                        if (strs) 
+                        nmax += blk;
+                        if (pOutputStrings) 
                         {
-                            strs = (char **) REALLOC(strs,nmax*sizeof(char **));
+                            pOutputStrings = (char **) REALLOC(pOutputStrings, nmax * sizeof(char **));
                         } 
                         else 
                         {
-                            strs = (char **) MALLOC(nmax*sizeof(char **));
+                            pOutputStrings = (char **) MALLOC(nmax * sizeof(char **));
                         }
 
-                        if ( strs == NULL) 
+                        if (pOutputStrings == NULL) 
                         {
                             if (ptrFormat)
                             {
@@ -156,7 +258,9 @@ int sci_msprintf(char *fname,unsigned long fname_len)
                             return 0;
                         }
                     }
-                    if ((strs[n]=MALLOC((k+1))) == NULL) 
+
+                    pOutputStrings[mOut] = (char*)MALLOC((k+1) * sizeof(char));
+                    if (pOutputStrings[mOut] == NULL) 
                     {
                         if (ptrFormat)
                         {
@@ -167,14 +271,16 @@ int sci_msprintf(char *fname,unsigned long fname_len)
                         Scierror(999,_("%s: No more memory.\n"),fname);
                         return 0;
                     }
-                    strncpy(strs[n],str1, k);
-                    strs[n][k]='\0';
-                    n++;
+                    strncpy(pOutputStrings[mOut], pStrTmp1, k);
+                    pOutputStrings[mOut][k] = EMPTY_CHAR;
+                    mOut++;
                 }
                 else 
-                { /* cat to previous line */
-                    ll=(int)strlen(strs[n-1]);
-                    if ((strs[n-1]=REALLOC(strs[n-1],(k+1+ll))) == NULL) 
+                {
+                    /* cat to previous line */
+                    ll = (int)strlen(pOutputStrings[mOut - 1]);
+                    pOutputStrings[mOut - 1] = (char*)REALLOC(pOutputStrings[mOut - 1], (k + 1 + ll)*sizeof(char));
+                    if (pOutputStrings[mOut - 1] == NULL) 
                     {
                         if (ptrFormat)
                         {
@@ -185,28 +291,32 @@ int sci_msprintf(char *fname,unsigned long fname_len)
                         Scierror(999,_("%s: No more memory.\n"),fname);
                         return 0;
                     }
-                    strncpy(&(strs[n-1][ll]),str1, k);
-                    strs[n-1][k+ll]='\0';
+                    strncpy(&(pOutputStrings[mOut - 1][ll]), pStrTmp1, k);
+                    pOutputStrings[mOut - 1][k + ll] = EMPTY_CHAR;
                 }
-                k=0;
-                str+=2;
-                str1=str;
-                cat_to_last=0;
+                k = 0;
+                pStrTmp += lenghtSplitChar;
+                pStrTmp1 = pStrTmp;
+                cat_to_last = 0;
             }
             else
             {
-                str++;
+                pStrTmp++;
             }
         }
-        k=(int)(str-str1); /* @TODO add comment */
-        if (k>0) {
-            if ((! cat_to_last) || (n == 0)) { /*add a new line */
-                if (n==nmax) 
+        k = (int)(pStrTmp - pStrTmp1);
+        if (k > 0) 
+        {
+            if ((!cat_to_last) || (mOut == 0)) 
+            { 
+                /*add a new line */
+                if (mOut == nmax) 
                 {
-                    nmax+=blk;
-                    if (strs)
+                    nmax += blk;
+                    if (pOutputStrings)
                     {
-                        if ((strs = (char **) REALLOC(strs,nmax*sizeof(char **))) == NULL) 
+                        pOutputStrings = (char **) REALLOC(pOutputStrings, nmax*sizeof(char **));
+                        if (pOutputStrings == NULL) 
                         {
                             if (ptrFormat)
                             {
@@ -220,7 +330,8 @@ int sci_msprintf(char *fname,unsigned long fname_len)
                     }
                     else
                     {
-                        if ( (strs = (char **) MALLOC(nmax*sizeof(char **))) == NULL) 
+                        pOutputStrings = (char **) MALLOC(nmax * sizeof(char **));
+                        if (pOutputStrings == NULL) 
                         {
                             if (ptrFormat)
                             {
@@ -232,10 +343,10 @@ int sci_msprintf(char *fname,unsigned long fname_len)
                             return 0;
                         }
                     }
-
                 }
 
-                if ((strs[n]=MALLOC((k+1))) == NULL) 
+                pOutputStrings[mOut] = (char*) MALLOC((k + 1) * sizeof(char));
+                if (pOutputStrings[mOut] == NULL) 
                 {
                     if (ptrFormat)
                     {
@@ -243,17 +354,19 @@ int sci_msprintf(char *fname,unsigned long fname_len)
                         ptrFormat = NULL;
                     }
 
-                    Scierror(999,_("%s: No more memory.\n"),fname);
+                    Scierror(999,_("%s: No more memory.\n"), fname);
                     return 0;
                 }
-                strncpy(strs[n],str1, k);
-                strs[n][k]='\0';
-                n++;
-
+                strncpy(pOutputStrings[mOut], pStrTmp1, k);
+                pOutputStrings[mOut][k] = EMPTY_CHAR;
+                mOut++;
             }
-            else { /* cat to previous line */
-                ll=(int)strlen(strs[n-1]);
-                if ((strs[n-1]=REALLOC(strs[n-1],(k+1+ll))) == NULL) 
+            else 
+            { 
+                /* cat to previous line */
+                ll = (int)strlen(pOutputStrings[mOut - 1]);
+                pOutputStrings[mOut - 1] = (char*)REALLOC(pOutputStrings[mOut - 1], (k + 1 + ll) * sizeof(char));
+                if (pOutputStrings[mOut - 1] == NULL) 
                 {
                     if (ptrFormat)
                     {
@@ -264,11 +377,15 @@ int sci_msprintf(char *fname,unsigned long fname_len)
                     Scierror(999,_("%s: No more memory.\n"),fname);
                     return 0;
                 }
-                strncpy(&(strs[n-1][ll]),str1, k);
-                strs[n-1][k+ll]='\0';
+                strncpy(&(pOutputStrings[mOut - 1][ll]), pStrTmp1, k);
+                pOutputStrings[mOut - 1][k + ll] = EMPTY_CHAR;
             }
         }
-        if (strncmp(str-2,"\\n",2) !=0) cat_to_last=1;
+
+        if (strncmp(pStrTmp - lenghtSplitChar, SPLIT_ON_CR_IN_FORMAT, lenghtSplitChar) != 0) 
+        {
+            cat_to_last = 1;
+        }
         if (Rhs == 1) break;
 
     }
@@ -280,14 +397,22 @@ int sci_msprintf(char *fname,unsigned long fname_len)
     }
 
     if (rval == RET_BUG) return 0;
-    /** Create a Scilab String : lstr must not be freed **/
-    n2=1;
-    CreateVarFromPtr(Rhs+1,MATRIX_OF_STRING_DATATYPE, &n, &n2, strs);
 
-    freeArrayOfString(strs, n);
+    /* Create a Scilab String */
+    nOut = 1;
+    sciErr = createMatrixOfString(pvApiCtx, Rhs + 1 , mOut, nOut, pOutputStrings);
 
-    LhsVar(1)=Rhs+1;
-    PutLhsVar();
+    /* lstr must not be freed */
+    freeArrayOfString(pOutputStrings, mOut * nOut);
+    if(sciErr.iErr)
+    {
+        printError(&sciErr, 0);
+    }
+    else
+    {
+        LhsVar(1) = Rhs + 1;
+        PutLhsVar();
+    }
     return 0;
 }
 /*--------------------------------------------------------------------------*/ 
index e27f1ca..679edbe 100644 (file)
@@ -12,3 +12,7 @@ getVarDimension
 getMatrixOfDouble
 getMatrixOfWideString
 createMatrixOfBoolean
+checkVarDimension
+getAllocatedSingleString
+createMatrixOfString
+freeAllocatedSingleString
\ No newline at end of file
diff --git a/scilab/modules/output_stream/tests/nonreg_tests/bug_4833.dia.ref b/scilab/modules/output_stream/tests/nonreg_tests/bug_4833.dia.ref
new file mode 100644 (file)
index 0000000..49a9d57
--- /dev/null
@@ -0,0 +1,31 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2011 - DIGITEO - Allan CORNET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- JVM NOT MANDATORY -->
+//
+// <-- Non-regression test for bug 4833 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=4833
+//
+// <-- Short Description -->
+//  msprintf() interpreted "\n" as a carriage return even if "\n"
+//  is supplied by the 2nd input argument.
+//
+if msprintf("string : --%s--","\n") <> "string : --\n--" then bugmes();quit;end
+R = msprintf("%s\n%s", "titi", "toto");
+REF = ["titi";"toto"];
+if or(R <> REF) then bugmes();quit;end
+R = msprintf("%s %s", "titi\n", "toto");
+REF = "titi\n toto";
+if R <> REF then bugmes();quit;end
+R = msprintf("%s %s", "titi\n", "toto\n");
+REF = "titi\n toto\n";
+if R <> REF then bugmes();quit;end
+R = msprintf("%s\n%s", "titi\n", "toto\n");
+REF = ["titi\n";"toto\n"];
+if or(R <> REF) then bugmes();quit;end
diff --git a/scilab/modules/output_stream/tests/nonreg_tests/bug_4833.tst b/scilab/modules/output_stream/tests/nonreg_tests/bug_4833.tst
new file mode 100644 (file)
index 0000000..5df429e
--- /dev/null
@@ -0,0 +1,36 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2011 - DIGITEO - Allan CORNET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- JVM NOT MANDATORY -->
+//
+// <-- Non-regression test for bug 4833 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=4833
+//
+// <-- Short Description -->
+//  msprintf() interpreted "\n" as a carriage return even if "\n"
+//  is supplied by the 2nd input argument.
+//
+
+if msprintf("string : --%s--","\n") <> "string : --\n--" then pause, end
+
+R = msprintf("%s\n%s", "titi", "toto");
+REF = ["titi";"toto"];
+if or(R <> REF) then pause, end
+
+R = msprintf("%s %s", "titi\n", "toto");
+REF = "titi\n toto";
+if R <> REF then pause, end
+
+R = msprintf("%s %s", "titi\n", "toto\n");
+REF = "titi\n toto\n";
+if R <> REF then pause, end
+
+R = msprintf("%s\n%s", "titi\n", "toto\n");
+REF = ["titi\n";"toto\n"];
+if or(R <> REF) then pause, end