changeset 18970:888f8ce79bbe

maint: Periodic merge gui-release -> default.
author Rik <rik@octave.org>
date Sun, 25 May 2014 10:29:05 -0700
parents 70ea5a2856fe (current diff) bd1fd4ed3d67 (diff)
children 5556ddfb841b
files libgui/src/m-editor/octave-qscintilla.cc libgui/src/main-window.cc libinterp/corefcn/data.cc libinterp/corefcn/find.cc libinterp/corefcn/graphics.cc libinterp/parse-tree/lex.ll
diffstat 14 files changed, 113 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/CITATION
+++ b/CITATION
@@ -1,17 +1,18 @@
 To cite GNU Octave in publications use:
 
-  John W. Eaton, David Bateman, and Søren Hauberg (2009).  GNU Octave version
-  3.0.1 manual: a high-level interactive language for numerical computations.
+  John W. Eaton, David Bateman, Søren Hauberg, Rik Wehbring (2014).
+  GNU Octave version 3.8.1 manual: a high-level interactive language for
+  numerical computations.
   CreateSpace Independent Publishing Platform.  ISBN 1441413006,
   URL http://www.gnu.org/software/octave/doc/interpreter/
 
 A BibTeX entry for LaTeX users is:
 
   @book{,
-    author    = {John W. Eaton and David Bateman and S\oren Hauberg},
-    title     = {{GNU Octave} version 3.0.1 manual: a high-level interactive language for numerical computations},
+    author    = {John W. Eaton, David Bateman, S\oren Hauberg, and Rik Wehbring},
+    title     = {{GNU Octave} version 3.8.1 manual: a high-level interactive language for numerical computations},
     publisher = {CreateSpace Independent Publishing Platform},
-    year      = {2009},
+    year      = {2014},
     note      = {{ISBN} 1441413006},
     url       = {http://www.gnu.org/software/octave/doc/interpreter},
   }
--- a/etc/CHECKLIST
+++ b/etc/CHECKLIST
@@ -2,6 +2,8 @@
 
   * Update the version number and release date in configure.ac.
 
+  * Update version number and release year in CITATION.
+
   * Update the NEWS file.
 
   * Update the NEWS-<VERSION>.html, index.in, news.in, and download.in
--- a/libgui/src/m-editor/file-editor-tab.cc
+++ b/libgui/src/m-editor/file-editor-tab.cc
@@ -66,6 +66,7 @@
   QString directory = directory_arg;
   _lexer_apis = 0;
   _app_closing = false;
+  _is_octave_file = true;
 
   // Make sure there is a slash at the end of the directory name
   // for identification when saved later.
@@ -84,7 +85,7 @@
            this,
            SLOT (execute_command_in_terminal (const QString&)));
 
-  connect (_edit_area, 
+  connect (_edit_area,
            SIGNAL (cursorPositionChanged (int, int)),
            this,
            SLOT (handle_cursor_moved (int,int)));
@@ -215,9 +216,9 @@
   update_lexer ();
 
   // update the file editor with current editing directory
-  emit editor_state_changed (_copy_available, _file_name);
+  emit editor_state_changed (_copy_available, _file_name, _is_octave_file);
+
   // add the new file to the mru list
-
   emit mru_add_file (_file_name);
 }
 
@@ -270,6 +271,8 @@
   delete lexer;
   lexer = 0;
 
+  _is_octave_file = false;
+
   if (_file_name.endsWith (".m")
       || _file_name.endsWith ("octaverc"))
     {
@@ -278,6 +281,7 @@
 #elif defined (HAVE_LEXER_MATLAB)
       lexer = new QsciLexerMatlab ();
 #endif
+      _is_octave_file = true;
     }
 
   if (! lexer)
@@ -311,8 +315,10 @@
           // new, no yet named file: let us assume it is octave
 #if defined (HAVE_LEXER_OCTAVE)
           lexer = new QsciLexerOctave ();
+          _is_octave_file = true;
 #elif defined (HAVE_LEXER_MATLAB)
           lexer = new QsciLexerMatlab ();
+          _is_octave_file = true;
 #else
           lexer = new QsciLexerBash ();
 #endif
@@ -975,7 +981,8 @@
 file_editor_tab::handle_copy_available (bool enableCopy)
 {
   _copy_available = enableCopy;
-  emit editor_state_changed (_copy_available, QDir::cleanPath (_file_name));
+  emit editor_state_changed (_copy_available, QDir::cleanPath (_file_name),
+                             _is_octave_file);
 }
 
 // show_dialog: shows a modal or non modal dialog depeding on the closing
@@ -1510,7 +1517,8 @@
       _find_dialog->show ();
     }
 
-  emit editor_state_changed (_copy_available, QDir::cleanPath (_file_name));
+  emit editor_state_changed (_copy_available, QDir::cleanPath (_file_name),
+                             _is_octave_file);
 }
 
 void
--- a/libgui/src/m-editor/file-editor-tab.h
+++ b/libgui/src/m-editor/file-editor-tab.h
@@ -123,7 +123,8 @@
 signals:
 
   void file_name_changed (const QString& fileName, const QString& toolTip);
-  void editor_state_changed (bool copy_available, const QString& fileName);
+  void editor_state_changed (bool copy_available, const QString& fileName,
+                             bool is_octave_file);
   void tab_remove_request ();
   void add_filename_to_list (const QString&, QWidget *);
   void mru_add_file (const QString& file_name);
@@ -217,6 +218,7 @@
   bool _long_title;
   bool _copy_available;
   bool _app_closing;
+  bool _is_octave_file;
 
   QFileSystemWatcher _file_system_watcher;
 
--- a/libgui/src/m-editor/file-editor.cc
+++ b/libgui/src/m-editor/file-editor.cc
@@ -965,6 +965,8 @@
   menu->addAction (_paste_action);
   menu->addSeparator ();
   menu->addAction (_selectall_action);
+  menu->addSeparator ();
+  menu->addAction (_run_selection_action);
 }
 
 void
@@ -994,7 +996,8 @@
 
 void
 file_editor::handle_editor_state_changed (bool copy_available,
-                                          const QString& file_name)
+                                          const QString& file_name,
+                                          bool is_octave_file)
 {
   // In case there is some scenario where traffic could be coming from
   // all the file editor tabs, just process info from the current active tab.
@@ -1002,7 +1005,8 @@
     {
       _copy_action->setEnabled (copy_available);
       _cut_action->setEnabled (copy_available);
-      _run_selection_action->setEnabled (copy_available);
+      _run_selection_action->setEnabled (copy_available && is_octave_file);
+      _run_action->setEnabled (is_octave_file);
 
       if (!file_name.isEmpty ())
         {
@@ -1410,8 +1414,8 @@
            this, SLOT (handle_file_name_changed (const QString&,
                                                  const QString&)));
 
-  connect (f, SIGNAL (editor_state_changed (bool, const QString&)),
-           this, SLOT (handle_editor_state_changed (bool, const QString&)));
+  connect (f, SIGNAL (editor_state_changed (bool, const QString&, bool)),
+           this, SLOT (handle_editor_state_changed (bool, const QString&, bool)));
 
   connect (f, SIGNAL (tab_remove_request ()),
            this, SLOT (handle_tab_remove_request ()));
--- a/libgui/src/m-editor/file-editor.h
+++ b/libgui/src/m-editor/file-editor.h
@@ -178,7 +178,8 @@
   void handle_tab_remove_request (void);
   void handle_add_filename_to_list (const QString& fileName, QWidget *ID);
   void active_tab_changed (int index);
-  void handle_editor_state_changed (bool enableCopy, const QString& fileName);
+  void handle_editor_state_changed (bool enableCopy, const QString& fileName,
+                                    bool is_octave_file);
   void handle_mru_add_file (const QString& file_name);
   void check_conflict_save (const QString& fileName, bool remove_on_success);
 
--- a/libgui/src/m-editor/octave-qscintilla.cc
+++ b/libgui/src/m-editor/octave-qscintilla.cc
@@ -200,10 +200,6 @@
           context_menu->addAction (tr ("Edit") + " " + _word_at_cursor,
                                    this, SLOT (contextmenu_edit (bool)));
         }
-      context_menu->addSeparator ();   // separator before custom entries
-      if (hasSelectedText ())
-        context_menu->addAction (tr ("&Run Selection"),
-                                 this, SLOT (contextmenu_run (bool)));
     }
 
   // finaly show the menu
--- a/libgui/src/main-window.cc
+++ b/libgui/src/main-window.cc
@@ -740,6 +740,7 @@
 {
   QString dir
     = QFileDialog::getExistingDirectory (this, tr ("Browse directories"), 0,
+                                         QFileDialog::ShowDirsOnly |
                                          QFileDialog::DontUseNativeDialog);
 
   set_current_working_directory (dir);
--- a/libinterp/corefcn/data.cc
+++ b/libinterp/corefcn/data.cc
@@ -3291,17 +3291,16 @@
                     result = Complex (0, 1) * SparseComplexMatrix (im_val);
                   else
                     {
-                      result = SparseComplexMatrix (im_val.dims (), re_val (0));
                       octave_idx_type nr = im_val.rows ();
                       octave_idx_type nc = im_val.cols ();
+                      result = SparseComplexMatrix (nr, nc, re_val(0));
 
                       for (octave_idx_type j = 0; j < nc; j++)
                         {
                           octave_idx_type off = j * nr;
                           for (octave_idx_type i = im_val.cidx (j);
                                i < im_val.cidx (j + 1); i++)
-                            result.data (im_val.ridx (i) + off) =
-                              result.data (im_val.ridx (i) + off) +
+                            result.data (im_val.ridx (i) + off) +=
                               Complex (0, im_val.data (i));
                         }
                     }
@@ -3314,19 +3313,17 @@
                     result = SparseComplexMatrix (re_val);
                   else
                     {
-                      result = SparseComplexMatrix (re_val.rows (),
-                                                    re_val.cols (),
-                                                    Complex (0, im_val (0)));
                       octave_idx_type nr = re_val.rows ();
                       octave_idx_type nc = re_val.cols ();
+                      result = SparseComplexMatrix (nr, nc,
+                                                    Complex (0, im_val(0)));
 
                       for (octave_idx_type j = 0; j < nc; j++)
                         {
                           octave_idx_type off = j * nr;
                           for (octave_idx_type i = re_val.cidx (j);
                                i < re_val.cidx (j + 1); i++)
-                            result.data (re_val.ridx (i) + off) =
-                              result.data (re_val.ridx (i) + off) +
+                            result.data (re_val.ridx (i) + off) +=
                               re_val.data (i);
                         }
                     }
--- a/libinterp/corefcn/find.cc
+++ b/libinterp/corefcn/find.cc
@@ -89,9 +89,8 @@
 {
   octave_value_list retval ((nargout == 0 ? 1 : nargout), Matrix ());
 
-
+  octave_idx_type nr = v.rows ();
   octave_idx_type nc = v.cols ();
-  octave_idx_type nr = v.rows ();
   octave_idx_type nz = v.nnz ();
 
   // Search in the default range.
@@ -139,21 +138,20 @@
   count = (n_to_find > v.cidx (end_nc) - v.cidx (start_nc) ?
            v.cidx (end_nc) - v.cidx (start_nc) : n_to_find);
 
-  // If the original argument was a row vector, force a row vector of
-  // the overall indices to be returned.  But see below for scalar
-  // case...
+  octave_idx_type result_nr;
+  octave_idx_type result_nc;
 
-  octave_idx_type result_nr = count;
-  octave_idx_type result_nc = 1;
-
-  bool scalar_arg = false;
-
-  if (v.rows () == 1)
+  // Default case is to return a column vector, however, if the original
+  // argument was a row vector, then force return of a row vector.
+  if (nr == 1)
     {
       result_nr = 1;
       result_nc = count;
-
-      scalar_arg = (v.columns () == 1);
+    }
+  else
+    {
+      result_nr = count;
+      result_nc = 1;
     }
 
   Matrix idx (result_nr, result_nc);
@@ -165,9 +163,8 @@
 
   if (count > 0)
     {
-      // Search for elements to return.  Only search the region where
-      // there are elements to be found using the count that we want
-      // to find.
+      // Search for elements to return.  Only search the region where there
+      // are elements to be found using the count that we want to find.
       for (octave_idx_type j = start_nc, cx = 0; j < end_nc; j++)
         for (octave_idx_type i = v.cidx (j); i < v.cidx (j+1); i++)
           {
@@ -183,14 +180,19 @@
               break;
           }
     }
-  else if (scalar_arg)
+  else
     {
-      idx.resize (0, 0);
+      // No items found.  Fixup return dimensions for Matlab compatibility.
+      // The behavior to match is documented in Array.cc (Array<T>::find).
+      if ((nr == 0 && nc == 0) || nr == 1 & nc == 1)
+        {
+          idx.resize (0, 0);
 
-      i_idx.resize (0, 0);
-      j_idx.resize (0, 0);
+          i_idx.resize (0, 0);
+          j_idx.resize (0, 0);
 
-      val.resize (dim_vector (0, 0));
+          val.resize (dim_vector (0, 0));
+        }
     }
 
   switch (nargout)
@@ -232,6 +234,7 @@
   // There are far fewer special cases to handle for a PermMatrix.
   octave_value_list retval ((nargout == 0 ? 1 : nargout), Matrix ());
 
+  octave_idx_type nr = v.rows ();
   octave_idx_type nc = v.cols ();
   octave_idx_type start_nc, count;
 
@@ -252,8 +255,6 @@
       count = n_to_find;
     }
 
-  bool scalar_arg = (v.rows () == 1 && v.cols () == 1);
-
   Matrix idx (count, 1);
   Matrix i_idx (count, 1);
   Matrix j_idx (count, 1);
@@ -291,13 +292,22 @@
             }
         }
     }
-  else if (scalar_arg)
+  else
     {
-      // Same odd compatibility case as the other overrides.
-      idx.resize (0, 0);
-      i_idx.resize (0, 0);
-      j_idx.resize (0, 0);
-      val.resize (dim_vector (0, 0));
+      // FIXME: Is this case even possible?  A scalar permutation matrix seems to devolve
+      //        to a scalar full matrix, at least from the Octave command line.  Perhaps
+      //        this function could be called internally from C++ with such a matrix.
+      // No items found.  Fixup return dimensions for Matlab compatibility.
+      // The behavior to match is documented in Array.cc (Array<T>::find).
+      if ((nr == 0 && nc == 0) || nr == 1 & nc == 1)
+        {
+          idx.resize (0, 0);
+
+          i_idx.resize (0, 0);
+          j_idx.resize (0, 0);
+
+          val.resize (dim_vector (0, 0));
+        }
     }
 
   switch (nargout)
--- a/libinterp/corefcn/graphics.cc
+++ b/libinterp/corefcn/graphics.cc
@@ -9721,16 +9721,17 @@
 
   int nargin = args.length ();
 
-  if (nargin != 1)
+  if (nargin == 1)
+    {
+      double h = args(0).double_value ();
+      if (! error_state)
+        retval = calc_dimensions (gh_manager::get_object (h));
+      else
+        error ("__calc_dimensions__: expecting graphics handle as only argument");
+    }
+  else
     print_usage ();
 
-  double h = args(0).double_value ();
-
-  if (! error_state)
-    retval = calc_dimensions (gh_manager::get_object (h));
-  else
-    error ("__calc_dimensions__: expecting graphics handle as only argument");
-
   return retval;
 }
 
--- a/libinterp/parse-tree/lex.ll
+++ b/libinterp/parse-tree/lex.ll
@@ -341,6 +341,18 @@
     return curr_lexer->show_token (INPUT_FILE);
   }
 
+<INPUT_FILE_START><<EOF>> {
+    curr_lexer->lexer_debug ("<INPUT_FILE_START><<EOF>>");
+
+    // May be reset later if we see "function" or "classdef" appears
+    // as the first token.
+    curr_lexer->reading_script_file = true;
+
+    curr_lexer->pop_start_state ();
+
+    return curr_lexer->show_token (INPUT_FILE);
+  }
+
 %{
 // Help and other command-style functions.
 %}
--- a/scripts/plot/draw/hist.m
+++ b/scripts/plot/draw/hist.m
@@ -157,7 +157,7 @@
   if (nargin > 2 && ! ischar (varargin{iarg}))
     ## Normalize the histogram.
     norm = varargin{iarg++};
-    freq *= norm / sum (! isnan (y));
+    freq = bsxfun (@times, freq, norm ./ sum (! isnan (y)));
   endif
 
   if (nargout > 0)
@@ -209,4 +209,6 @@
 %! endfor
 %!assert (hist (1,1), 1)
 %!assert (size (hist (randn (750,240), 200)), [200,240])
-
+## Test bug #42394
+%!assert (isempty (hist (rand (10,2), 0:5, 1)), false)
+%!assert (isempty (hist (rand (10,2), 0:5, [1 1])), false)
--- a/scripts/plot/draw/private/__bar__.m
+++ b/scripts/plot/draw/private/__bar__.m
@@ -120,13 +120,17 @@
 
   nbars = columns (y);
 
-  ## Column width is 1 for 'hist*' styles.  Otherwise, same as group width.
-  if (nbars == 1)
+  ## Column width is 1 for 'hist*' styles (bars touch).
+  if (islogical (histc))
+    cwidth = 1;
+    if (nbars == 1)
+      gwidth = 1;
+    else
+      gwidth = width^2;
+    endif
+  elseif (nbars == 1)
     cwidth = 1;
     gwidth = width;
-  elseif (islogical (histc))
-    cwidth = 1;
-    gwidth = width^2;
   else
     cwidth = gwidth = width;
   endif