0031092: Foundation Classes - incorrect last output value for Infinite progress indicator
authorabv <abv@opencascade.com>
Fri, 25 Oct 2019 14:11:33 +0000 (17:11 +0300)
committerapn <apn@opencascade.com>
Wed, 30 Oct 2019 20:23:55 +0000 (23:23 +0300)
DRAW implementation of progress indicator is corrected to print "finished" instead of 1e100 for the end of infinite range.
Added test bugs fclasses bug31092

src/Draw/Draw_ProgressIndicator.cxx
src/QABugs/QABugs_11.cxx
tests/bugs/fclasses/bug31092 [new file with mode: 0644]

index 35c1b6f..8c68e7e 100644 (file)
@@ -18,7 +18,7 @@
 #include <Message.hxx>
 #include <Message_Messenger.hxx>
 #include <Message_ProgressScale.hxx>
-#include <Standard_Type.hxx>
+#include <Precision.hxx>
 
 #include <stdio.h>
 #include <time.h>
@@ -92,21 +92,34 @@ Standard_Boolean Draw_ProgressIndicator::Show(const Standard_Boolean force)
   myLastPosition = aPosition;
   
   // Prepare textual progress info
-  char text[2048];
-  Standard_Integer n = 0;
-  n += Sprintf ( &text[n], "Progress: %.0f%%", 100. * GetPosition() );
+  std::stringstream aText;
+  aText.setf (std::ios::fixed, std:: ios::floatfield);
+  aText.precision(0);
+  aText << "Progress: " << 100. * GetPosition() << "%";
   for ( Standard_Integer i=GetNbScopes(); i >=1; i-- ) {
     const Message_ProgressScale &scale = GetScope ( i );
     if ( scale.GetName().IsNull() ) continue; // skip unnamed scopes
+    aText << " " << scale.GetName()->ToCString() << ": ";
+
     // if scope has subscopes, print end of subscope as its current position
     Standard_Real locPos = ( i >1 ? GetScope ( i-1 ).GetLast() : GetPosition() );
     // print progress info differently for finite and infinite scopes
     if ( scale.GetInfinite() )
-      n += Sprintf ( &text[n], " %s: %.0f", scale.GetName()->ToCString(), 
-                     scale.BaseToLocal ( locPos ) );
-    else 
-      n += Sprintf ( &text[n], " %s: %.0f / %.0f", scale.GetName()->ToCString(), 
-                     scale.BaseToLocal ( locPos ), scale.GetMax() );
+    {
+      Standard_Real aVal = scale.BaseToLocal(locPos);
+      if (Precision::IsInfinite(aVal))
+      {
+        aText << "finished";
+      }
+      else
+      {
+        aText << aVal;
+      }
+    }
+    else
+    {
+      aText << scale.BaseToLocal ( locPos ) << " / " << scale.GetMax();
+    }
   }
 
   // Show graphic progress bar
@@ -117,8 +130,8 @@ Standard_Boolean Draw_ProgressIndicator::Show(const Standard_Boolean force)
       time_t aTimeT;
       time ( &aTimeT );
       Standard_Size aTime = (Standard_Size)aTimeT;
-      n += Sprintf ( &text[n], "\nElapsed/estimated time: %ld/%.0f sec", 
-                     (long)(aTime - myStartTime), ( aTime - myStartTime ) / GetPosition() );
+      aText << "\nElapsed/estimated time: " << (long)(aTime - myStartTime) <<
+               "/" << ( aTime - myStartTime ) / GetPosition() << " sec";
     }
   
     if ( ! myShown ) {
@@ -135,20 +148,19 @@ Standard_Boolean Draw_ProgressIndicator::Show(const Standard_Boolean force)
       ((Draw_Interpretor*)myDraw)->Eval ( command );
       myShown = Standard_True;
     }
-    char command[1024];
-    Standard_Integer num = 0;
-    num += Sprintf ( &command[num], ".xprogress.bar coords progress 2 2 %.0f 21;", 
-                  1+400*GetPosition() );
-    num += Sprintf ( &command[num], ".xprogress.bar coords progress_next 2 2 %.0f 21;", 
-                  1+400*GetScope(1).GetLast() );
-    num += Sprintf ( &command[num], ".xprogress.text configure -text \"%s\";", text );
-    num += Sprintf ( &command[num], "update" );
-    ((Draw_Interpretor*)myDraw)->Eval ( command );
+    std::stringstream aCommand;
+    aCommand.setf(std::ios::fixed, std::ios::floatfield);
+    aCommand.precision(0);
+    aCommand << ".xprogress.bar coords progress 2 2 " << (1 + 400 * GetPosition()) << " 21;";
+    aCommand << ".xprogress.bar coords progress_next 2 2 " << (1 + 400 * GetScope(1).GetLast()) << " 21;";
+    aCommand << ".xprogress.text configure -text \"" << aText.str() << "\";";
+    aCommand << "update";
+    ((Draw_Interpretor*)myDraw)->Eval (aCommand.str().c_str());
   }
 
   // Print textual progress info
   if ( myTextMode )
-    Message::DefaultMessenger()->Send (text, Message_Info);
+    Message::DefaultMessenger()->Send (aText.str().c_str(), Message_Info);
   
   return Standard_True;
 }
index 2d403e2..56d3b33 100644 (file)
@@ -4748,6 +4748,7 @@ Standard_Integer OCC28478 (Draw_Interpretor& di, Standard_Integer argc, const ch
 {      
   Standard_Integer nbOuter = (argc > 1 ? Draw::Atoi(argv[1]) : 3);
   Standard_Integer nbInner = (argc > 2 ? Draw::Atoi(argv[2]) : 2);
+  Standard_Boolean isInf = (argc > 3 && ! strcmp (argv[3], "-inf"));
 
   // test behavior of progress indicator when using nested scopes with names set by Sentry objects
   Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (di, 1);
@@ -4758,7 +4759,7 @@ Standard_Integer OCC28478 (Draw_Interpretor& di, Standard_Integer argc, const ch
   for (int i = 0; i < nbOuter && anOuter.More(); i++, anOuter.Next())
   {
     // Inner cycle
-    Message_ProgressSentry anInner (aProgress, "Inner", 0, nbInner, 1);
+    Message_ProgressSentry anInner (aProgress, "Inner", 0, nbInner, 1, isInf);
     for (int j = 0; j < nbInner && anInner.More(); j++, anInner.Next())
     {
       // Cycle body
@@ -4870,6 +4871,6 @@ void QABugs::Commands_11(Draw_Interpretor& theCommands) {
   theCommands.Add("OCC22558", "OCC22558 x_vec y_vec z_vec x_dir y_dir z_dit x_pnt y_pnt z_pnt", __FILE__, OCC22558, group);
   theCommands.Add("CR23403", "CR23403 string", __FILE__, CR23403, group);
   theCommands.Add("OCC23429", "OCC23429 res shape tool [appr]", __FILE__, OCC23429, group);
-  theCommands.Add("OCC28478", "OCC28478 [nb_outer=3 [nb_inner=2]: test progress indicator on nested cycles", __FILE__, OCC28478, group);
+  theCommands.Add("OCC28478", "OCC28478 [nb_outer=3 [nb_inner=2] [-inf]: test progress indicator on nested cycles", __FILE__, OCC28478, group);
   return;
 }
diff --git a/tests/bugs/fclasses/bug31092 b/tests/bugs/fclasses/bug31092
new file mode 100644 (file)
index 0000000..989dfb6
--- /dev/null
@@ -0,0 +1,30 @@
+puts "# ============"
+puts "# 0031092: Foundation Classes - incorrect last output value for Infinite progress indicator"
+puts "# ============"
+puts ""
+puts "# Test output of progress indicator in text mode (infinite scale)"
+
+pload QAcommands
+set out [OCC28478 3 2 -inf]
+
+set expected {
+  {Progress: 0% Outer: 1 / 3}
+  {Progress: 11% Outer: 1 / 3 Inner: 1}
+  {Progress: 17% Outer: 1 / 3 Inner: 2}
+  {Progress: 20% Outer: 1 / 3 Inner: 3}
+  {Progress: 33% Outer: 1 / 3 Inner: finished}
+  {Progress: 44% Outer: 2 / 3 Inner: 1}
+  {Progress: 50% Outer: 2 / 3 Inner: 2}
+  {Progress: 53% Outer: 2 / 3 Inner: 3}
+  {Progress: 67% Outer: 2 / 3 Inner: finished}
+  {Progress: 78% Outer: 3 / 3 Inner: 1}
+  {Progress: 83% Outer: 3 / 3 Inner: 2}
+  {Progress: 87% Outer: 3 / 3 Inner: 3}
+  {Progress: 100% Outer: 3 / 3 Inner: finished}
+}
+
+if { [string compare [string trim $out] [join $expected "\n"]] } {
+  puts "Error: output (see above) does not match expected one:"
+  puts "[join $expected "\n"]"
+  puts ""
+}
\ No newline at end of file