# HG changeset patch # User Rik # Date 1401038945 25200 # Node ID 888f8ce79bbee984265d9503d68132038953c932 # Parent 70ea5a2856fe0ca6780f4b70f976790cf6a719ff# Parent bd1fd4ed3d67fb3bfd60184071a96ac5eb5f848d maint: Periodic merge gui-release -> default. diff --git a/CITATION b/CITATION --- 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}, } diff --git a/etc/CHECKLIST b/etc/CHECKLIST --- 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-.html, index.in, news.in, and download.in diff --git a/libgui/src/m-editor/file-editor-tab.cc b/libgui/src/m-editor/file-editor-tab.cc --- 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 diff --git a/libgui/src/m-editor/file-editor-tab.h b/libgui/src/m-editor/file-editor-tab.h --- 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; diff --git a/libgui/src/m-editor/file-editor.cc b/libgui/src/m-editor/file-editor.cc --- 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 ())); diff --git a/libgui/src/m-editor/file-editor.h b/libgui/src/m-editor/file-editor.h --- 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); diff --git a/libgui/src/m-editor/octave-qscintilla.cc b/libgui/src/m-editor/octave-qscintilla.cc --- 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 diff --git a/libgui/src/main-window.cc b/libgui/src/main-window.cc --- 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); diff --git a/libinterp/corefcn/data.cc b/libinterp/corefcn/data.cc --- 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); } } diff --git a/libinterp/corefcn/find.cc b/libinterp/corefcn/find.cc --- 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::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::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) diff --git a/libinterp/corefcn/graphics.cc b/libinterp/corefcn/graphics.cc --- 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; } diff --git a/libinterp/parse-tree/lex.ll b/libinterp/parse-tree/lex.ll --- a/libinterp/parse-tree/lex.ll +++ b/libinterp/parse-tree/lex.ll @@ -341,6 +341,18 @@ return curr_lexer->show_token (INPUT_FILE); } +<> { + curr_lexer->lexer_debug ("<>"); + + // 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. %} diff --git a/scripts/plot/draw/hist.m b/scripts/plot/draw/hist.m --- 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) diff --git a/scripts/plot/draw/private/__bar__.m b/scripts/plot/draw/private/__bar__.m --- 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