changeset 33557:bfa4ab12b323 bytecode-interpreter

maint: Merge default to bytecode-interpreter
author Arun Giridhar <arungiridhar@gmail.com>
date Thu, 09 May 2024 18:18:53 -0400
parents 129d335e4b78 (current diff) 4b0987b80bb7 (diff)
children 67d22dc78b80
files
diffstat 8 files changed, 154 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/command-widget.cc	Wed May 08 15:17:17 2024 -0400
+++ b/libgui/src/command-widget.cc	Thu May 09 18:18:53 2024 -0400
@@ -54,22 +54,37 @@
 command_widget::command_widget (QWidget *p)
   : QWidget (p), m_incomplete_parse (false),
     m_prompt (QString ()),
-    m_console (new console (this))
+    m_console (new console (this)),
+    m_find_widget (new find_widget (false, this))
+
 {
+  gui_settings settings;
+
   QPushButton *pause_button = new QPushButton (tr("Pause"), this);
   QPushButton *stop_button = new QPushButton (tr("Stop"), this);
   QPushButton *resume_button = new QPushButton (tr("Continue"), this);
 
-  QGroupBox *input_group_box = new QGroupBox ();
+  connect (m_find_widget, &find_widget::find_signal,
+           m_console, &console::find);
+  connect (m_find_widget, &find_widget::find_incremental_signal,
+           m_console, &console::find_incremental);
+
+  QWidget *input_widget = new QWidget;
   QHBoxLayout *input_layout = new QHBoxLayout;
   input_layout->addWidget (pause_button);
   input_layout->addWidget (stop_button);
   input_layout->addWidget (resume_button);
-  input_group_box->setLayout (input_layout);
+  input_layout->addStretch ();
+  input_layout->addWidget (m_find_widget);
+  input_layout->setContentsMargins (0, 0, 0, 0);
+  input_widget->setLayout (input_layout);
+  input_widget->setContentsMargins (0, 0, 0, 0);
 
   QVBoxLayout *main_layout = new QVBoxLayout ();
   main_layout->addWidget (m_console);
-  main_layout->addWidget (input_group_box);
+  main_layout->addWidget (input_widget);
+  main_layout->setSpacing (0);
+  main_layout->setContentsMargins (2, 2, 2, 0);
 
   setLayout (main_layout);
 
@@ -97,7 +112,6 @@
            this, qOverload<const meth_callback&> (&command_widget::interpreter_event));
 
   insert_interpreter_output ("\n\n    Welcome to Octave\n\n");
-
 }
 
 void
@@ -208,6 +222,8 @@
 
   m_console->setStyleSheet (QString ("color: %1; background-color:%2;")
                             .arg (fgc.name ()).arg (bgc.name ()));
+
+  m_find_widget->notice_settings ();
 }
 
 // The console itself using QScintilla.
@@ -221,7 +237,10 @@
     m_cursor_position (0),
     m_text_changed (false),
     m_command_widget (p),
-    m_last_key_string (QString ())
+    m_last_key_string (QString ()),
+    m_find_result_available (false),
+    m_find_direction (false),
+    m_last_find_inc_result (QString ())
 {
   setMargins (0);
   setWrapMode (QsciScintilla::WrapWord);
@@ -337,6 +356,72 @@
   m_text_changed = true;
 }
 
+// find incremental
+void
+console::find_incremental (const QString& text)
+{
+  int line = -1, col = -1;
+
+  // Go the start of last incremental find result avoiding that the next
+  // match is found instead of the current one
+  if (! m_last_find_inc_result.isEmpty ())
+    {
+      getCursorPosition (&line, &col);
+      int currpos = positionFromLineIndex (line, col);
+      currpos = currpos - (m_last_find_inc_result.length ());
+      lineIndexFromPosition (currpos, &line, &col);
+    }
+
+
+  if (findFirst (text, false, false, false, true, true, line, col))
+    m_last_find_inc_result = text;
+  else
+    m_last_find_inc_result.clear ();
+}
+
+// find
+void
+console::find (const QString& text, bool backward)
+{
+  bool direction_changed = m_find_direction != backward;
+
+  int line = -1, col = -1;
+
+  if (direction_changed)
+    {
+      // Direction changed
+      m_find_direction = backward;
+      if (m_find_result_available)
+        {
+          // Something was found but direction changed, go to start/end of selection
+          if (m_find_result_available)
+            {
+              getCursorPosition (&line, &col);
+              int currpos = positionFromLineIndex (line, col);
+              if (backward)
+                currpos = currpos - (text.length ());
+              else
+                currpos = currpos + (text.length ());
+              if (currpos < 0)
+                currpos = 0;
+              lineIndexFromPosition (currpos, &line, &col);
+            }
+        }
+    }
+  else
+    {
+      // Direction not changed
+      if (m_find_result_available)
+        {
+          m_find_result_available = findNext ();
+          return;
+        }
+    }
+
+  m_find_result_available =
+      findFirst (text, false, false, false, true, ! backward, line, col);
+}
+
 // Re-implement key event
 void
 console::keyPressEvent (QKeyEvent *e)
--- a/libgui/src/command-widget.h	Wed May 08 15:17:17 2024 -0400
+++ b/libgui/src/command-widget.h	Thu May 09 18:18:53 2024 -0400
@@ -30,6 +30,8 @@
 
 #include <Qsci/qsciscintilla.h>
 
+#include "find-widget.h"
+
 // FIXME: We need the following header for the fcn_callback and
 // meth_callback typedefs.  Maybe it would be better to declare those in
 // a separate file because inclding "event-manager.h" pulls in a lot of
@@ -67,6 +69,10 @@
 
   void execute_command (const QString& command);
 
+  void find_incremental (const QString&);
+
+  void find (const QString&, bool);
+
 protected:
 
   void keyPressEvent (QKeyEvent *e);
@@ -82,6 +88,9 @@
   bool m_text_changed;
   command_widget *m_command_widget;
   QString m_last_key_string;
+  bool m_find_result_available;
+  bool m_find_direction;
+  QString m_last_find_inc_result;
 
 };
 
@@ -128,6 +137,8 @@
   bool m_incomplete_parse;
   QString m_prompt;
   console *m_console;
+  find_widget *m_find_widget;
+
 };
 
 OCTAVE_END_NAMESPACE(octave)
--- a/libgui/src/documentation.cc	Wed May 08 15:17:17 2024 -0400
+++ b/libgui/src/documentation.cc	Thu May 09 18:18:53 2024 -0400
@@ -174,11 +174,8 @@
   connect (m_doc_browser, &documentation_browser::cursorPositionChanged,
            this, &documentation::handle_cursor_position_change);
 
-  // Tool bar
-  construct_tool_bar ();
-
   // Find bar
-  m_find_widget = new find_widget (this);
+  m_find_widget = new find_widget (true, this);
   connect (m_find_widget, &find_widget::find_signal,
            this, &documentation::find);
   connect (m_find_widget, &find_widget::find_incremental_signal,
@@ -190,11 +187,14 @@
   v_box_browser_find->addWidget (m_find_widget);
   browser_find->setLayout (v_box_browser_find);
 
-  notice_settings ();
-
   m_find_widget->hide ();
   m_search_anchor_position = 0;
 
+  // Tool bar
+  construct_tool_bar ();
+
+  notice_settings ();
+
   if (m_help_engine)
     {
 #if defined (HAVE_NEW_QHELPINDEXWIDGET_API)
@@ -419,7 +419,7 @@
   m_tool_bar->addSeparator ();
   m_action_find
     = add_action (settings.icon ("edit-find"), tr ("Find"),
-                  SLOT (activate_find ()), this, m_tool_bar);
+                  SLOT (activate_find ()), m_find_widget, m_tool_bar);
 
   // Zoom
   m_tool_bar->addSeparator ();
@@ -757,12 +757,6 @@
 }
 
 void
-documentation::activate_find ()
-{
-  m_find_widget->activate_find ();
-}
-
-void
 documentation::filter_update (const QString& expression)
 {
   if (! m_help_engine)
--- a/libgui/src/documentation.h	Wed May 08 15:17:17 2024 -0400
+++ b/libgui/src/documentation.h	Thu May 09 18:18:53 2024 -0400
@@ -134,7 +134,6 @@
 
 private slots:
 
-  void activate_find ();
   void global_search ();
   void global_search_started ();
   void global_search_finished (int hits);
--- a/libgui/src/find-widget.cc	Wed May 08 15:17:17 2024 -0400
+++ b/libgui/src/find-widget.cc	Thu May 09 18:18:53 2024 -0400
@@ -36,8 +36,9 @@
 
 // The documentation splitter, which is the main widget
 // of the doc dock widget
-find_widget::find_widget (QWidget *p)
+find_widget::find_widget (bool x_button, QWidget *p)
   : QWidget (p),
+    m_find_line_edit (new QLineEdit (this)),
     m_findnext_shortcut (new QShortcut (this)),
     m_findprev_shortcut (new QShortcut (this))
 {
@@ -45,7 +46,8 @@
 
   QLabel *find_label = new QLabel (tr ("Find:"), this);
 
-  m_find_line_edit = new QLineEdit (this);
+  m_find_line_edit->setClearButtonEnabled (true);
+
   connect (m_find_line_edit, &QLineEdit::returnPressed,
            this, &find_widget::find);
   connect (m_find_line_edit, &QLineEdit::textEdited,
@@ -65,19 +67,23 @@
   connect (backward_button, &QToolButton::pressed,
            this, &find_widget::find_backward);
 
-  QToolButton *close_button = new QToolButton (this);
-//  close_button->setText (tr ("Close"));
-  close_button->setToolTip (tr ("Close find dialog"));
-  close_button->setIcon (settings.icon ("window-close"));
-  connect (close_button, &QToolButton::pressed,
-           this, [this] () { close (); });
-
   QHBoxLayout *h_box_this = new QHBoxLayout (this);
   h_box_this->addWidget (find_label);
   h_box_this->addWidget (m_find_line_edit);
   h_box_this->addWidget (forward_button);
   h_box_this->addWidget (backward_button);
-  h_box_this->addWidget (close_button);
+
+  if (x_button)
+    {
+      QToolButton *close_button = new QToolButton (this);
+      close_button->setText (tr ("Close"));
+      close_button->setToolTip (tr ("Close find dialog"));
+      close_button->setIcon (settings.icon ("window-close"));
+      connect (close_button, &QToolButton::pressed,
+               this, [this] () { close (); });
+      h_box_this->addWidget (close_button);
+    }
+
   h_box_this->setContentsMargins (2, 2, 2, 2);
   this->setLayout (h_box_this);
 
--- a/libgui/src/find-widget.h	Wed May 08 15:17:17 2024 -0400
+++ b/libgui/src/find-widget.h	Thu May 09 18:18:53 2024 -0400
@@ -38,7 +38,9 @@
 //    3. Provide suitable actions in the slots of the signals above
 //    4. Call the find widget's methods notice_settings when settings
 //       are updated and save_settings when settings are saved
-//    5. Other methods are
+//    5. Other methods or slots are
+//        - file_widget::activate_find (): slot for hiding/showing
+//                                         find widget
 //        - file_widget::text (): get current search text
 //        - file_widget::set_text (const QString& text): set search text
 //
@@ -63,10 +65,10 @@
 
 public:
 
-  find_widget (QWidget *parent = nullptr);
+  // x_button: provide a close button for the widget or not
+  find_widget (bool x_button = true, QWidget *parent = nullptr);
   ~find_widget () = default;
 
-  void activate_find (void);
   QString text (void);
   void set_text (const QString& text);
   void notice_settings (void);
@@ -74,6 +76,8 @@
 
 public slots:
 
+  void activate_find (void);
+
 private slots:
 
   void find (void);
--- a/libinterp/corefcn/data.cc	Wed May 08 15:17:17 2024 -0400
+++ b/libinterp/corefcn/data.cc	Thu May 09 18:18:53 2024 -0400
@@ -7120,15 +7120,13 @@
         }
       else
         {
-          // Forbid vector or array input
-          if (! args(1).is_scalar_type ())
+          // Require dim to be positive real scalar.
+          if (! args(1).is_scalar_type () || args(1).iscomplex ()
+              || args(1).double_value () <= 0)
             error ("sort: DIM must be a positive scalar integer");
 
           // Forbid fractional value input, also nan input.
           dim = args(1).strict_int_value ("sort: DIM must be a positive scalar integer") - 1;
-
-          if (dim < 0)
-            error ("sort: DIM must be a positive scalar integer");
         }
     }
 
@@ -7162,7 +7160,8 @@
       // NOTE: Can not change this to ovl() call because arg.sort changes sidx
       //       and objects are declared const in ovl prototype.
       retval(0) = arg.sort (sidx, dim, smode);
-      retval(1) = idx_vector (sidx, dv(dim));  // No checking, extent is known.
+      // Check for index dimension extent. Set to 1 for dimension >= ndims ()
+      retval(1) = idx_vector (sidx, (dim < arg.ndims ()) ? dv(dim) : 1);
     }
   else
     retval = ovl (arg.sort (dim, smode));
@@ -7394,11 +7393,20 @@
 %! A = [1 2; 3 4];
 %! assert (sort (A, 100), A)
 %! assert (sort (A, inf), A)
+%! [B, idx] = sort (A, 100);
+%! assert (B, A);
+%! assert (idx, ones (2))
+%! [B, idx] = sort (A, inf);
+%! assert (B, A);
+%! assert (idx, ones (2))
 
 %!error <Invalid call> sort ()
 %!error <Invalid call> sort (1, 2, 3, 4)
 %!error <MODE must be either "ascend" or "descend"> sort (1, "foobar")
 %!error <DIM must be a positive scalar integer> sort (1, [1 2 3])
+%!error <DIM must be a positive scalar integer> sort ([1 2; 3 4], -inf)
+%!error <DIM must be a positive scalar integer> sort ([1 2; 3 4], 0)
+%!error <DIM must be a positive scalar integer> sort ([1 2; 3 4], 1+i)
 %!error <DIM must be a positive scalar integer> sort ([1 2; 3 4], 1.234)
 %!error <DIM must be a positive scalar integer> sort ([1 2; 3 4], nan)
 %!error <DIM argument must precede MODE argument> sort (1, "ascend", 1)
--- a/liboctave/array/Array-base.cc	Wed May 08 15:17:17 2024 -0400
+++ b/liboctave/array/Array-base.cc	Thu May 09 18:18:53 2024 -0400
@@ -1922,19 +1922,18 @@
 Array<T, Alloc>::sort (Array<octave_idx_type>& sidx, int dim,
                        sortmode mode) const
 {
-  if (dim < 0 || dim >= ndims ())
+  if (dim < 0)
     (*current_liboctave_error_handler) ("sort: invalid dimension");
 
+  const dim_vector& dv = dims ();
+
+  sidx = Array<octave_idx_type> (dv);
+
+  if (numel () < 1 || dim >= ndims ())
+    return *this;
+
   Array<T, Alloc> m (dims ());
 
-  const dim_vector& dv = m.dims ();
-
-  if (m.numel () < 1)
-    {
-      sidx = Array<octave_idx_type> (dv);
-      return m;
-    }
-
   octave_idx_type ns = dv(dim);
   octave_idx_type iter = dv.numel () / ns;
   octave_idx_type stride = 1;
@@ -1947,7 +1946,6 @@
 
   octave_sort<T> lsort;
 
-  sidx = Array<octave_idx_type> (dv);
   octave_idx_type *vi = sidx.rwdata ();
 
   if (mode != UNSORTED)