changeset 25204:6afed459d063

maint: Merge stable to default.
author John W. Eaton <jwe@octave.org>
date Tue, 10 Apr 2018 23:33:53 -0400
parents 5251de3c34d7 (current diff) c80323fe4938 (diff)
children 22522ea137b4
files test/module.mk
diffstat 9 files changed, 108 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/variable-editor.cc	Tue Apr 10 15:46:07 2018 -0700
+++ b/libgui/src/variable-editor.cc	Tue Apr 10 23:33:53 2018 -0400
@@ -1029,12 +1029,21 @@
     m_main->setCentralWidget (central_mdiarea);
 
     setWidget (m_main);
-    setFocusProxy (m_main);
 
     connect (this, SIGNAL (command_signal (const QString&)),
              p, SLOT (execute_command_in_terminal (const QString&)));
   }
 
+  void variable_editor::focusInEvent (QFocusEvent *ev)
+  {
+    octave_dock_widget::focusInEvent (ev);
+
+    // set focus to the current variable
+    QWidget *fw = m_main->focusWidget ();
+    if (fw != nullptr)
+      fw->setFocus ();
+  }
+
   // Add an action to a menu or the widget itself.
 
   QAction*
--- a/libgui/src/variable-editor.h	Tue Apr 10 15:46:07 2018 -0700
+++ b/libgui/src/variable-editor.h	Tue Apr 10 23:33:53 2018 -0400
@@ -334,6 +334,10 @@
 
     void selected_command_signal (const QString& cmd);
 
+  protected:
+
+    void focusInEvent (QFocusEvent *ev);
+
   private:
 
     QAction * add_action (QMenu *menu, const QIcon& icon, const QString& text,
--- a/libinterp/corefcn/load-save.cc	Tue Apr 10 15:46:07 2018 -0700
+++ b/libinterp/corefcn/load-save.cc	Tue Apr 10 23:33:53 2018 -0400
@@ -153,12 +153,18 @@
 
   if (global)
     {
-      scope.clear_variable (name);
-      scope.mark_global (name);
-      symtab.assign (name, val);
+      octave::symbol_record sym = scope.find_symbol (name);
+
+      if (! sym.is_global ())
+        {
+          octave::symbol_scope global_scope = symtab.global_scope ();
+          octave::symbol_record global_sym = global_scope.find_symbol (name);
+
+          sym.bind_fwd_rep (global_scope.get_rep (), global_sym);
+        }
     }
-  else
-    scope.assign (name, val);
+
+  scope.assign (name, val);
 }
 
 // Return TRUE if NAME matches one of the given globbing PATTERNS.
--- a/libinterp/corefcn/symrec.h	Tue Apr 10 15:46:07 2018 -0700
+++ b/libinterp/corefcn/symrec.h	Tue Apr 10 23:33:53 2018 -0400
@@ -203,7 +203,7 @@
         // clear the local value.
 
         if (is_global ())
-          unbind_fwd_rep ();
+          unbind_global_rep ();
 
         if (! (is_hidden () || is_inherited ()))
           {
@@ -280,7 +280,7 @@
         if (auto t_fwd_rep = m_fwd_rep.lock ())
           return t_fwd_rep->is_global ();
 
-        return m_storage_class & global;
+        return is_marked_global ();
       }
 
       bool is_persistent (void) const
@@ -363,6 +363,11 @@
         m_storage_class |= global;
       }
 
+      bool is_marked_global (void) const
+      {
+        return m_storage_class & global;
+      }
+
       void mark_persistent (void)
       {
         if (auto t_fwd_rep = m_fwd_rep.lock ())
@@ -482,51 +487,51 @@
 
         if (auto t_fwd_rep = m_fwd_rep.lock ())
           {
+            // If this is the symbol in the global scope, then don't
+            // forward again!
+
+            if (t_fwd_rep->is_marked_global ())
+              return;
+
             t_fwd_rep->bind_fwd_rep (fwd_scope, fwd_rep);
-            return;
           }
 
         m_fwd_scope = fwd_scope;
         m_fwd_rep = fwd_rep;
       }
 
-      void unbind_fwd_rep (bool recurse = true)
+      void unbind_fwd_rep (void)
       {
-        // When unbinding variables in a script scope, recurse will be
-        // false and we will only break the immediate link.  By doing
-        // that, we ensure that any variables that are made global in
-        // a script remain linked as globals in the enclosing scope.
-
-        // When unbinding variables in a (possibly nested) function
-        // scope, recurse will be true and we will break the link to
-        // the global scope, not just the immediate link to the parent
-        // scope of the nested function.
-
-        if (recurse)
-          {
-            if (auto t_fwd_rep = m_fwd_rep.lock ())
-              {
-                // Currently, it is only possible to have at most two
-                // levels of indirection here, either
-                //
-                //   nested function -> parent function -> global scope
-                //
-                // or
-                //
-                //   script -> top level scope -> global scope
-                //
-                // so we can break the recursion here by setting the
-                // argument to unbind_fwd_rep to false.
-
-                t_fwd_rep->unbind_fwd_rep (false);
-                return;
-              }
-          }
+        // When unbinding variables in a script scope, we only break
+        // the immediate link.  By doing that, we ensure that any
+        // variables that are made global in a script remain linked as
+        // globals in the enclosing scope.
 
         m_fwd_scope = std::weak_ptr<symbol_scope_rep> ();
         m_fwd_rep.reset ();
       }
 
+      void unbind_global_rep (void)
+      {
+        // Break the link to the global symbol_record_rep.  These must
+        // forwarded, so we don't do anything unless the forward rep
+        // points to something.
+
+        if (auto t_fwd_rep = m_fwd_rep.lock ())
+          {
+            if (t_fwd_rep->is_marked_global ())
+              {
+                // The rep this object points to is in the global
+                // scope, so delete the link to it.
+
+                m_fwd_scope = std::weak_ptr<symbol_scope_rep> ();
+                m_fwd_rep.reset ();
+              }
+            else
+              t_fwd_rep->unbind_fwd_rep ();
+          }
+      }
+
       std::shared_ptr<symbol_record_rep>
       dup (const std::shared_ptr<symbol_scope_rep>& new_scope) const;
 
@@ -657,7 +662,6 @@
     void mark_formal (void) { m_rep->mark_formal (); }
     void mark_hidden (void) { m_rep->mark_hidden (); }
     void mark_inherited (void) { m_rep->mark_inherited (); }
-    void mark_global (void) { m_rep->mark_global (); }
     void mark_persistent (void) { m_rep->mark_persistent (); }
     void mark_added_static (void) { m_rep->mark_added_static (); }
 
@@ -669,6 +673,9 @@
     void unmark_persistent (void) { m_rep->unmark_persistent (); }
     void unmark_added_static (void) { m_rep->unmark_added_static (); }
 
+    bool is_marked_global (void) const { return m_rep->is_marked_global (); }
+    void mark_global (void) { m_rep->mark_global (); }
+
     void init_persistent (void) { m_rep->init_persistent (); }
 
     unsigned int storage_class (void) const { return m_rep->storage_class (); }
@@ -679,7 +686,7 @@
       m_rep->bind_fwd_rep (fwd_scope, sr.m_rep);
     }
 
-    void unbind_fwd_rep (bool recurse = true) { m_rep->unbind_fwd_rep (recurse); }
+    void unbind_fwd_rep (void) { m_rep->unbind_fwd_rep (); }
 
     octave_value dump (context_id context) const
     {
--- a/libinterp/corefcn/symscope.cc	Tue Apr 10 15:46:07 2018 -0700
+++ b/libinterp/corefcn/symscope.cc	Tue Apr 10 23:33:53 2018 -0400
@@ -237,6 +237,6 @@
   symbol_scope_rep::unbind_script_symbols (void)
   {
     for (auto& nm_sr : m_symbols)
-      nm_sr.second.unbind_fwd_rep (false);
+      nm_sr.second.unbind_fwd_rep ();
   }
 }
--- a/libinterp/corefcn/symscope.h	Tue Apr 10 15:46:07 2018 -0700
+++ b/libinterp/corefcn/symscope.h	Tue Apr 10 23:33:53 2018 -0400
@@ -792,6 +792,10 @@
         m_rep->mark_hidden (name);
     }
 
+    // This function should only be called for the global
+    // symbol_scope, and that should only happen when it is added to
+    // the global symbol_scope.
+
     void mark_global (const std::string& name)
     {
       if (m_rep)
--- a/scripts/sparse/bicg.m	Tue Apr 10 15:46:07 2018 -0700
+++ b/scripts/sparse/bicg.m	Tue Apr 10 23:33:53 2018 -0400
@@ -106,7 +106,8 @@
 ## difference between the current iteration @var{x} and the previous is less
 ## than @code{eps * norm (@var{x},2)}.
 ##
-## @item 4: The algorithm can't continue due to a division by zero.
+## @item 4: The algorithm could not continue because intermediate values
+## became too small or too large for reliable computation.
 ## @end itemize
 ##
 ## @item
@@ -271,11 +272,12 @@
   while ((flag != 2) && (iter < maxit) && (resvec(iter+1) >= norm_b * tol))
     v = Afun (p, "notransp", varargin{:});
     prod_qv = q' * v;
-    if (prod_qv == 0)
+    alpha = (s0' * prec_r0);
+    if (abs (prod_qv) <= eps * abs (alpha))
       flag = 4;
       break
     endif
-    alpha = (s0' * prec_r0) / prod_qv;
+    alpha ./= prod_qv;
     x += alpha * p;
     prod_rs = (s0' * prec_r0);  # Product between r0 and s0
     r0 -= alpha * v;
@@ -283,6 +285,12 @@
     prec_r0 = M1fun (r0, "notransp", varargin{:});
     prec_s0 = s0;
     prec_r0 = M2fun (prec_r0, "notransp", varargin{:});
+    beta = s0' * prec_r0;
+    if (abs (prod_rs) <= abs (beta))
+      flag = 4;
+      break;
+    endif
+    beta ./= prod_rs;
     prec_s0 = M2fun (prec_s0, "transp", varargin{:});
     prec_s0 = M1fun (prec_s0, "transp", varargin{:});
     iter += 1;
@@ -295,11 +303,6 @@
       flag = 3;
       break;
     endif
-    if (prod_rs == 0)
-      flag = 4;
-      break;
-    endif
-    beta = (s0' * prec_r0) / prod_rs;
     p = prec_r0 + beta*p;
     q = prec_s0 + conj (beta) * q;
   endwhile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/bug-53599.tst	Tue Apr 10 23:33:53 2018 -0400
@@ -0,0 +1,23 @@
+%!function rval = sggval (val)
+%!  global gval
+%!  if (nargin == 1)
+%!    gval = val;
+%!  else
+%!    rval = gval;
+%!  endif
+%!endfunction
+
+%!test
+%! global gval
+%! assert (isempty (gval))
+%! sggval (13);
+%! assert (sggval (), 13);
+%! assert (gval, 13);
+%! clear global gval
+%! assert (sggval (), [])
+%! gval = 42;
+%! assert (sggval (), []);
+%! clear gval
+%! global gval
+%! gval = 42;
+%! assert (sggval (), 42);
--- a/test/module.mk	Tue Apr 10 15:46:07 2018 -0700
+++ b/test/module.mk	Tue Apr 10 23:33:53 2018 -0400
@@ -12,6 +12,7 @@
   %reldir%/bug-38576.tst \
   %reldir%/bug-46330.tst \
   %reldir%/bug-49904.tst \
+  %reldir%/bug-53599.tst \
   %reldir%/colormaps.tst \
   %reldir%/command.tst \
   %reldir%/complex.tst \