* Bug #14742 fixed: `mprintf`, `msprintf` a non finite number displayed nothing. 78/21278/7
Clement David [Tue, 4 Feb 2020 09:44:56 +0000 (10:44 +0100)]
Change-Id: Ice80a758b1e2eb7e5a76cf7708e39ca379cbbaae

scilab/CHANGES.md
scilab/modules/output_stream/src/cpp/scilab_sprintf.cpp
scilab/modules/output_stream/tests/nonreg_tests/bug_14742.tst [new file with mode: 0644]

index f9f1bf8..69782eb 100644 (file)
@@ -257,6 +257,7 @@ Bug Fixes
 * [#14642](http://bugzilla.scilab.org/show_bug.cgi?id=14642): No more "\r" carriage return with printf.
 * [#14735](http://bugzilla.scilab.org/show_bug.cgi?id=14735): The `genetic_algorithms` module was out of the `optimization` one.
 * [#14741](http://bugzilla.scilab.org/show_bug.cgi?id=14741): The syntax `[m,e]=log2(x)` was not documented. As public function `frexp` was in duplicate with `[m,e]=log2(x)`.
+* [#14742](http://bugzilla.scilab.org/show_bug.cgi?id=14742): `mprintf`, `msprintf` a non finite number displayed nothing. 
 * [#14746](http://bugzilla.scilab.org/show_bug.cgi?id=14746): Tiny numbers were sometimes displayed as 0.
 * [#14791](http://bugzilla.scilab.org/show_bug.cgi?id=14791): `sleep 1` crashed Scilab.
 * [#14812](http://bugzilla.scilab.org/show_bug.cgi?id=14812): Minor typos in messages.
index 66d12e5..85a4c57 100644 (file)
@@ -39,6 +39,7 @@ static wchar_t* replace_with_ls(TokenDef* token);
 static void updatel(TokenDef* token);
 static void replace_lu_llu(TokenDef* token);
 static void replace_ld_lld(TokenDef* token);
+static void print_nan_or_inf(wchar_t* pwstTemp, double dblVal, const wchar_t* token, int pos, int width);
 
 #define NanString L"Nan"
 #define InfString L"Inf"
@@ -47,7 +48,7 @@ static void replace_ld_lld(TokenDef* token);
 wchar_t** scilab_sprintf(const std::string& funcname, const wchar_t* _pwstInput, types::typed_list &in, int* _piOutputRows, int* _piNewLine)
 {
     wchar_t** pwstOutput = nullptr;
-    int rhs = in.size();
+    int rhs = static_cast<int>(in.size());
     wchar_t* pwstFirstOutput = nullptr;
     *_piNewLine = 0;
     int col = 0;
@@ -133,6 +134,7 @@ wchar_t** scilab_sprintf(const std::string& funcname, const wchar_t* _pwstInput,
         wchar_t* pwstPercent = wcsstr(tok->pwstToken, L"%");
         if (pwstPercent != nullptr && percentpercent == false)
         {
+            int offset = 1;
             //looking for flags
             if (*(pwstPercent + 1) == L'-' ||
                     *(pwstPercent + 1) == L'+' ||
@@ -140,11 +142,11 @@ wchar_t** scilab_sprintf(const std::string& funcname, const wchar_t* _pwstInput,
                     *(pwstPercent + 1) == L'#' ||
                     *(pwstPercent + 1) == L'0')
             {
-                pwstPercent++;
+                offset = 2;
             }
 
             //looking for width
-            if (*(pwstPercent + 1) == L'*')
+            if (*(pwstPercent + offset) == L'*')
             {
                 if (itPos == inPos.end())
                 {
@@ -172,16 +174,18 @@ wchar_t** scilab_sprintf(const std::string& funcname, const wchar_t* _pwstInput,
             else
             {
                 //number
-                if (iswdigit(*(pwstPercent + 1)))
+                if (iswdigit(*(pwstPercent + offset)))
                 {
                     tok->width = os_wtoi(pwstPercent + 1);
-                    while (iswdigit(*(pwstPercent + 1)))
+                    while (iswdigit(*(pwstPercent + offset)))
                     {
                         pwstPercent++;
                     }
                 }
             }
 
+            pwstPercent += (offset - 1);
+
             //looking for precision
             if (*(pwstPercent + 1) == L'.')
             {
@@ -231,7 +235,7 @@ wchar_t** scilab_sprintf(const std::string& funcname, const wchar_t* _pwstInput,
             }
 
             wchar_t wcType = *(pwstPercent + 1);
-            tok->typePos = (pwstPercent + 1) - tok->pwstToken;
+            tok->typePos = static_cast<int>((pwstPercent + 1) - tok->pwstToken);
 
             switch (wcType)
             {
@@ -439,22 +443,7 @@ wchar_t** scilab_sprintf(const std::string& funcname, const wchar_t* _pwstInput,
                     }
                     else
                     {
-                        wchar_t* newToken = replace_with_ls(tok);
-
-                        if (std::isnan(dblVal))
-                        {
-                            os_swprintf(pwstTemp, bsiz, newToken, NanString);
-                        }
-                        else if (std::signbit(dblVal))
-                        {
-                            os_swprintf(pwstTemp, bsiz, newToken, NegInfString);
-                        }
-                        else
-                        {
-                            os_swprintf(pwstTemp, bsiz, newToken, InfString);
-                        }
-
-                        delete[] newToken;
+                        print_nan_or_inf(pwstTemp, dblVal, token, tok->typePos, tok->width);
                     }
 
                     oFirstOutput << pwstTemp;
@@ -494,25 +483,7 @@ wchar_t** scilab_sprintf(const std::string& funcname, const wchar_t* _pwstInput,
                     }
                     else
                     {
-                        wchar_t* newToken = replace_with_ls(tok);
-
-                        if (std::isnan(dblVal))
-                        {
-                            os_swprintf(pwstTemp, bsiz, newToken, NanString);
-                        }
-                        else
-                        {
-                            if (std::signbit(dblVal))
-                            {
-                                os_swprintf(pwstTemp, bsiz, newToken, NegInfString);
-                            }
-                            else
-                            {
-                                os_swprintf(pwstTemp, bsiz, newToken, InfString);
-                            }
-                        }
-
-                        delete[] newToken;
+                        print_nan_or_inf(pwstTemp, dblVal, token, tok->typePos, tok->width);
                     }
 
                     oFirstOutput << pwstTemp;
@@ -552,25 +523,7 @@ wchar_t** scilab_sprintf(const std::string& funcname, const wchar_t* _pwstInput,
                     }
                     else
                     {
-                        wchar_t* newToken = replace_with_ls(tok);
-
-                        if (std::isnan(dblVal))
-                        {
-                            os_swprintf(pwstTemp, bsiz, newToken, NanString);
-                        }
-                        else
-                        {
-                            if (std::signbit(dblVal))
-                            {
-                                os_swprintf(pwstTemp, bsiz, newToken, NegInfString);
-                            }
-                            else
-                            {
-                                os_swprintf(pwstTemp, bsiz, newToken, InfString);
-                            }
-                        }
-
-                        delete[] newToken;
+                        print_nan_or_inf(pwstTemp, dblVal, token, tok->typePos, tok->width);
                     }
 
                     oFirstOutput << pwstTemp;
@@ -682,7 +635,7 @@ wchar_t** scilab_sprintf(const std::string& funcname, const wchar_t* _pwstInput,
                 // skip LF
                 tmpToken = ++lf;
                 // if not at the end of token, continue with same token
-                if(lf - tok->pwstToken < wcslen(tok->pwstToken))
+                if(static_cast<size_t>(lf - tok->pwstToken) < wcslen(tok->pwstToken))
                 {
                     continue;
                 }
@@ -851,3 +804,34 @@ static void replace_ld_lld(TokenDef* token)
     }
 #endif
 }
+/*--------------------------------------------------------------------------*/
+static void print_nan_or_inf(wchar_t* pwstTemp, double dblVal, const wchar_t* token, int pos, int width)
+{
+    int sizeTotal = (int)wcslen(token);
+    wchar_t* pwstToken = new wchar_t[sizeTotal + 2]{ 0 };
+
+    if (width)
+    {
+        os_swprintf(pwstToken, sizeTotal + 2, L"%%%dls%ls", width, token + pos + 1);
+    }
+    else
+    {
+        os_swprintf(pwstToken, sizeTotal + 2, L"%%ls%ls", token + pos + 1);
+    }
+
+    if (std::isnan(dblVal))
+    {
+        os_swprintf(pwstTemp, bsiz, pwstToken, NanString);
+    }
+    else if (std::signbit(dblVal))
+    {
+        os_swprintf(pwstTemp, bsiz, pwstToken, NegInfString);
+    }
+    else
+    {
+        os_swprintf(pwstTemp, bsiz, pwstToken, InfString);
+    }
+
+    delete[] pwstToken;
+
+}
diff --git a/scilab/modules/output_stream/tests/nonreg_tests/bug_14742.tst b/scilab/modules/output_stream/tests/nonreg_tests/bug_14742.tst
new file mode 100644 (file)
index 0000000..4577fe3
--- /dev/null
@@ -0,0 +1,62 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2020 - ESI Group - Clement DAVID
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+
+// <-- Non-regression test for bug 14742 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=14742
+//
+// <-- ENGLISH IMPOSED -->
+
+// <-- Short Description -->
+// Wrong display of Inf or Nan
+//
+
+assert_checkequal(" Nan", msprintf('%4.1f',%nan));
+assert_checkequal(" Inf", msprintf('%4.1f',%inf));
+assert_checkequal("-Inf", msprintf('%4.1f',-%inf));
+
+assert_checkequal("Nan ", msprintf('%-4.1f',%nan));
+assert_checkequal("Inf ", msprintf('%-4.1f',%inf));
+assert_checkequal("-Inf", msprintf('%-4.1f',-%inf));
+
+assert_checkequal("Nan", msprintf('%1.1f',%nan));
+assert_checkequal("Inf", msprintf('%1.1f',%inf));
+assert_checkequal("-Inf", msprintf('%1.1f',-%inf));
+
+assert_checkequal("Nan", msprintf('%-1.1f',%nan));
+assert_checkequal("Inf", msprintf('%-1.1f',%inf));
+assert_checkequal("-Inf", msprintf('%-1.1f',-%inf));
+
+F="%10.3f";
+assert_checkequal("     3.000       Nan     5.000", msprintf(F+F+F, [3,%nan,5]));
+assert_checkequal("     3.000       Inf     5.000", msprintf(F+F+F, [3,%inf,5]));
+assert_checkequal("     3.000      -Inf     5.000", msprintf(F+F+F, [3,-%inf,5]));
+
+F="%-10.3f";
+assert_checkequal("3.000     Nan       5.000     ", msprintf(F+F+F, [3,%nan,5]));
+assert_checkequal("3.000     Inf       5.000     ", msprintf(F+F+F, [3,%inf,5]));
+assert_checkequal("3.000     -Inf      5.000     ", msprintf(F+F+F, [3,-%inf,5]));
+
+
+assert_checkequal(["a = Inf";"b = Inf"], msprintf("a = %f\nb = %f", %inf, %inf));
+assert_checkequal(["a = Nan";"b = Nan"], msprintf("a = %f\nb = %f", %nan, %nan));
+
+assert_checkequal(["a = Inf";"b = Inf"], msprintf("a = %f\nb = %f\n", %inf, %inf));
+assert_checkequal(["a = Nan";"b = Nan"], msprintf("a = %f\nb = %f\n", %nan, %nan));
+
+assert_checkequal("Inffoo", msprintf("%ffoo\n", %inf));
+assert_checkequal("Nanfoo", msprintf("%ffoo\n", %nan));
+
+assert_checkequal("fooInf", msprintf("foo%f\n", %inf));
+assert_checkequal("fooNan", msprintf("foo%f\n", %nan));
+
+assert_checkequal("fooInfbar", msprintf("foo%fbar\n", %inf));
+assert_checkequal("fooNanbar", msprintf("foo%fbar\n", %nan));
+