# HG changeset patch # User Markus Mützel # Date 1711133102 -3600 # Node ID 5565b3e6eb60efaefdb4e93b74d4401934f2b59b # Parent 3305b504bc2b303ecbfa7042cafe3af1095f9448# Parent c0ee9e8e311716d6f7132d2010aab8aefbe12c9f maint: Merge default to bytecode-interpreter. diff -r 3305b504bc2b -r 5565b3e6eb60 .github/workflows/make.yaml --- a/.github/workflows/make.yaml Wed Mar 20 08:13:12 2024 +0100 +++ b/.github/workflows/make.yaml Fri Mar 22 19:45:02 2024 +0100 @@ -480,11 +480,9 @@ - compiler: clang cc: "clang" cxx: "clang++" - # Qt6 doesn't install pkg-config files on macOS. See: https://bugreports.qt.io/browse/QTBUG-86080 - # So, we need to provide the necessary flags manually. - qt-cppflags: "-I${HOMEBREW_PREFIX}/opt/qt@6/include/QtCore -I${HOMEBREW_PREFIX}/opt/qt@6/include/QtGui -I${HOMEBREW_PREFIX}/opt/qt@6/include/QtHelp -I${HOMEBREW_PREFIX}/opt/qt@6/include/QtNetwork -I${HOMEBREW_PREFIX}/opt/qt@6/include/QtOpenGL -I${HOMEBREW_PREFIX}/opt/qt@6/include/QtOpenGLWidgets -I${HOMEBREW_PREFIX}/opt/qt@6/include/QtPrintSupport -I${HOMEBREW_PREFIX}/opt/qt@6/include/QtSql -I${HOMEBREW_PREFIX}/opt/qt@6/include/QtWidgets -I${HOMEBREW_PREFIX}/opt/qt@6/include/QtXml -I${HOMEBREW_PREFIX}/opt/qt@6/include/QtCore5Compat" - qt-ldflags: "-F${HOMEBREW_PREFIX}/opt/qt@6/Frameworks" - qt-libs: "-framework QtCore -framework QtGui -framework QtHelp -framework QtNetwork -framework QtOpenGL -framework QtOpenGLWidgets -framework QtPrintSupport -framework QtSql -framework QtWidgets -framework QtXml -framework QtCore5Compat" + # Qt6 doesn't install pkg-config files on macOS by default. See: https://bugreports.qt.io/browse/QTBUG-86080 + # Homebrew installs "unofficial" .pc files for it in a non-default location. + qt-pkg-config-path: opt/qt@6/libexec/lib/pkgconfig env: CC: ${{ matrix.cc }} @@ -595,12 +593,9 @@ CPPFLAGS="-I${HOMEBREW_PREFIX}/opt/gettext/include -I${HOMEBREW_PREFIX}/opt/icu4c/include -I${HOMEBREW_PREFIX}/opt/qt@${{ matrix.qt }}/include -I${HOMEBREW_PREFIX}/opt/readline/include -I${HOMEBREW_PREFIX}/opt/sqlite/include $MY_CPPFLAGS -I${HOMEBREW_PREFIX}/include" \ CXXFLAGS="-O2 -g" \ LDFLAGS="-L${HOMEBREW_PREFIX}/opt/bison/lib -L${HOMEBREW_PREFIX}/opt/gettext/lib -L${HOMEBREW_PREFIX}/opt/icu4c/lib -L${HOMEBREW_PREFIX}/opt/readline/lib -L${HOMEBREW_PREFIX}/opt/sqlite/lib $MY_LDFLAGS -L${HOMEBREW_PREFIX}/lib" \ - PKG_CONFIG_PATH="${HOMEBREW_PREFIX}/opt/openblas/lib/pkgconfig:${HOMEBREW_PREFIX}/opt/icu4c/lib/pkgconfig:${HOMEBREW_PREFIX}/opt/qt@${{ matrix.qt }}/lib/pkgconfig" \ + PKG_CONFIG_PATH="${HOMEBREW_PREFIX}/opt/openblas/lib/pkgconfig:${HOMEBREW_PREFIX}/opt/icu4c/lib/pkgconfig:${HOMEBREW_PREFIX}/${{ matrix.qt-pkg-config-path }}" \ --with-qt=${{ matrix.qt }} \ QCOLLECTIONGENERATOR="qhelpgenerator" \ - QT_CPPFLAGS="${{ matrix.qt-cppflags }}" \ - QT_LDFLAGS="${{ matrix.qt-ldflags }}" \ - QT_LIBS="${{ matrix.qt-libs }}" \ --with-x=no \ --with-blas="-L${HOMEBREW_PREFIX}/opt/openblas/lib -lopenblas" \ --with-java-homedir="${HOMEBREW_PREFIX}/opt/openjdk" \ diff -r 3305b504bc2b -r 5565b3e6eb60 libinterp/corefcn/help.cc --- a/libinterp/corefcn/help.cc Wed Mar 20 08:13:12 2024 +0100 +++ b/libinterp/corefcn/help.cc Fri Mar 22 19:45:02 2024 +0100 @@ -675,6 +675,20 @@ help = fcn->doc_string (fcn_nm); what = fcn->fcn_file_name (); + if (help.empty () && ov_fcn.is_user_function ()) + { + octave_user_function *ufcn = ov_fcn.user_function_value (); + + if (ufcn->is_classdef_constructor ()) + help = "undocumented constructor: "; + else if (ufcn->is_classdef_method ()) + help = "undocumented method: "; + else + help = "undocumented function: "; + + help += ufcn->signature (); + } + if (what.empty ()) what = fcn->is_user_function () ? "command-line function" : "built-in function"; @@ -719,10 +733,23 @@ } } - // We found a class, but no docstring for it or its constructor. - // Create a generic doc string. - help = name + " is an undocumented class"; - what = "class"; + // No dot in name and class is undocumented. Look for documented + // constructor. + + octave_value ov_meth = cls.get_method (name); + + if (get_help_from_fcn (name, ov_meth, help, what, symbol_found)) + { + what = "constructor"; + symbol_found = true; + return true; + } + + // We found a class, but no docstring for it and there is no + // constructor explicitly defined. + + help = "default constructor: obj = " + name + " ()"; + what = "constructor"; symbol_found = true; return true; } @@ -813,7 +840,21 @@ octave_value ov_meth = cls.get_method (nm); if (get_help_from_fcn (nm, ov_meth, help, what, symbol_found)) - return true; + { + what = "class method"; + return true; + } + + // Found class but no method. If the NM is the same as the name + // of the class, then we have a default constructor. + + if (cls.get_name () == nm) + { + help = "default constructor: obj = " + nm + " ()"; + what = "constructor"; + symbol_found = true; + return true; + } // FIXME: Should we only find public properties here? diff -r 3305b504bc2b -r 5565b3e6eb60 libinterp/corefcn/syscalls.cc --- a/libinterp/corefcn/syscalls.cc Wed Mar 20 08:13:12 2024 +0100 +++ b/libinterp/corefcn/syscalls.cc Fri Mar 22 19:45:02 2024 +0100 @@ -124,25 +124,34 @@ if (args.length () != 2) print_usage (); - stream_list& streams = interp.get_stream_list (); - - stream old_stream = streams.lookup (args(0), "dup2"); + int i_old, i_new; + try + { + // Look up FID in Octave's list of open streams. + stream_list& streams = interp.get_stream_list (); - stream new_stream = streams.lookup (args(1), "dup2"); - - int i_old = old_stream.file_number (); - int i_new = new_stream.file_number (); + stream old_stream = streams.lookup (args(0), "dup2"); + stream new_stream = streams.lookup (args(1), "dup2"); - if (i_old >= 0 && i_new >= 0) + i_old = old_stream.file_number (); + i_new = new_stream.file_number (); + } + catch (execution_exception& ee) { - std::string msg; + // If the FIDs are not known to Octave, try the provided FIDs directly. + i_old = args(0).int_value (true); + i_new = args(1).int_value (true); + } - int status = sys::dup2 (i_old, i_new, msg); + if (i_old < 0 || i_new < 0) + // Bad FIDs, return error immediately + return ovl (-1, ""); - return ovl (status, msg); - } - else - return ovl (-1, ""); + std::string msg; + + int status = sys::dup2 (i_old, i_new, msg); + + return ovl (status, msg); } DEFMETHODX ("exec", Fexec, interp, args, , @@ -439,21 +448,28 @@ if (args.length () != 3) print_usage (); - stream_list& streams = interp.get_stream_list (); + int fid; + try + { + // Look up FID in Octave's list of open streams. + stream_list& streams = interp.get_stream_list (); + stream strm = streams.lookup (args(0), "fcntl"); + fid = strm.file_number (); + } + catch (execution_exception& ee) + { + // If the file is not known to Octave, try the provided file ID directly. + fid = args(0).int_value (true); + } - stream strm = streams.lookup (args(0), "fcntl"); - - int fid = strm.file_number (); + if (fid < 0) + error ("fcntl: invalid file id FID"); // FIXME: Do we want to use xint_value and throw a warning message // if input validation fails? int req = args(1).int_value (true); int arg = args(2).int_value (true); - // FIXME: Need better checking here? - if (fid < 0) - error ("fcntl: invalid file id"); - octave_value_list retval; std::string msg; @@ -908,9 +924,21 @@ if (args(0).is_scalar_type ()) { - stream_list& streams = interp.get_stream_list (); + int fid; + try + { + // Look up FID in Octave's list of open streams. + stream_list& streams = interp.get_stream_list (); + fid = streams.get_file_number (args(0)); + } + catch (execution_exception& ee) + { + // If the file is not known to Octave, try provided file ID directly. + fid = args(0).int_value (true); + } - int fid = streams.get_file_number (args(0)); + if (fid < 0) + error ("stat: invalid file id FID"); sys::file_fstat fs (fid); diff -r 3305b504bc2b -r 5565b3e6eb60 libinterp/octave-value/ov-usr-fcn.cc --- a/libinterp/octave-value/ov-usr-fcn.cc Wed Mar 20 08:13:12 2024 +0100 +++ b/libinterp/octave-value/ov-usr-fcn.cc Fri Mar 22 19:45:02 2024 +0100 @@ -283,6 +283,29 @@ delete m_trail_comm; } +std::string +octave_user_function::signature () const +{ + std::ostringstream buf; + + octave::tree_print_code tpc (buf); + + if (m_ret_list) + { + m_ret_list->accept (tpc); + buf << " = "; + } + + buf << m_name << " "; + + if (m_param_list) + m_param_list->accept (tpc); + else + buf << " ()"; + + return buf.str (); +} + octave_user_function * octave_user_function::define_ret_list (octave::tree_parameter_list *t) { diff -r 3305b504bc2b -r 5565b3e6eb60 libinterp/octave-value/ov-usr-fcn.h --- a/libinterp/octave-value/ov-usr-fcn.h Wed Mar 20 08:13:12 2024 +0100 +++ b/libinterp/octave-value/ov-usr-fcn.h Fri Mar 22 19:45:02 2024 +0100 @@ -235,6 +235,9 @@ ~octave_user_function (); + // Declared calling form, generated from the parse tree. + std::string signature () const; + octave_function * function_value (bool = false) { return this; } octave_user_function * user_function_value (bool = false) { return this; } diff -r 3305b504bc2b -r 5565b3e6eb60 test/Makefile.am --- a/test/Makefile.am Wed Mar 20 08:13:12 2024 +0100 +++ b/test/Makefile.am Fri Mar 22 19:45:02 2024 +0100 @@ -114,7 +114,6 @@ include bug-61191/module.mk include bug-63841/module.mk include bug-65037/module.mk -include bug-65220/module.mk include class-concat/module.mk include classdef/module.mk include classdef-debug/module.mk @@ -126,6 +125,7 @@ include ctor-vs-method/module.mk include fcn-handle/module.mk include file-encoding/module.mk +include help/module.mk include json/module.mk include jupyter-notebook/module.mk include load-path/module.mk diff -r 3305b504bc2b -r 5565b3e6eb60 test/bug-65220/bug-65220.tst --- a/test/bug-65220/bug-65220.tst Wed Mar 20 08:13:12 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -######################################################################## -## -## Copyright (C) 2024 The Octave Project Developers -## -## See the file COPYRIGHT.md in the top-level directory of this -## distribution or . -## -## This file is part of Octave. -## -## Octave is free software: you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## . -## -######################################################################## - -%!test <*65220> -%! unwind_protect -%! addpath ('cdefdir'); -%! -%! ## Check methods first (bug was disguised if class checked first) -%! s = help ('cdef_help1.meth1'); -%! assert (regexp (s, 'meth1: method help text ABOVE function')); -%! -%! s = help ('cdef_help1.meth2'); -%! assert (regexp (s, 'meth2: method help text BELOW function')); -%! -%! s = help ('cdef_help1.meth3'); -%! assert (regexp (s, 'meth3: method help text BELOW function')); -%! -%! s = ''; -%! try -%! s = help ('cdef_help1.meth4'); -%! catch -%! assert (regexp (lasterr (), "'cdef_help1.meth4' is not documented")); -%! end_try_catch -%! if (! isempty (s)) -%! error ("Impossible state: Help text found for 'cdef_help1.meth4'"); -%! endif -%! -%! ## Check documentation for entire class -%! s = help ('cdef_help1'); -%! assert (regexp (s, 'class cdef_help1 : class help text ABOVE classdef')); -%! -%! ## Check documentation for constructor -%! s = help ('cdef_help1.cdef_help1'); -%! assert (regexp (s, 'cdef_help1: constructor help text BELOW function')); -%! -%! ## Check documentation for properties -%! s = help ('cdef_help1.prop1'); -%! assert (regexp (s, 'prop1: property help text ABOVE property')); -%! -%! s = help ('cdef_help1.prop2'); -%! assert (regexp (s, 'prop2: property help text in EOL-comment')); -%! -%! unwind_protect_cleanup -%! rmpath ('cdefdir'); -%! end_unwind_protect - -%!test <*65220> -%! unwind_protect -%! addpath ('cdefdir'); -%! -%! ## Check methods first (bug was disguised if class checked first) -%! s = help ('cdef_help2.meth1'); -%! assert (regexp (s, 'meth1: method help text ABOVE function')); -%! -%! s = help ('cdef_help2.meth2'); -%! assert (regexp (s, 'meth2: method help text BELOW function')); -%! -%! s = help ('cdef_help2.meth3'); -%! assert (regexp (s, 'meth3: method help text ABOVE function')); -%! -%! s = ''; -%! try -%! s = help ('cdef_help2.meth4'); -%! catch -%! assert (regexp (lasterr (), "'cdef_help2.meth4' is not documented")); -%! end_try_catch -%! if (! isempty (s)) -%! error ("Impossible state: Help text found for 'cdef_help2.meth4'"); -%! endif -%! -%! ## Check documentation for entire class -%! s = help ('cdef_help2'); -%! assert (regexp (s, 'class cdef_help2 : class help text BELOW classdef')); -%! -%! ## Check documentation for constructor -%! s = help ('cdef_help2.cdef_help2'); -%! assert (regexp (s, 'cdef_help2: constructor help text ABOVE function')); -%! -%! ## Check documentation for properties -%! s = help ('cdef_help2.prop1'); -%! assert (regexp (s, 'prop1: property help text ABOVE property')); -%! -%! s = help ('cdef_help2.prop2'); -%! assert (regexp (s, 'prop2: property help text in EOL-comment')); -%! -%! unwind_protect_cleanup -%! rmpath ('cdefdir'); -%! end_unwind_protect diff -r 3305b504bc2b -r 5565b3e6eb60 test/bug-65220/cdefdir/cdef_help1.m --- a/test/bug-65220/cdefdir/cdef_help1.m Wed Mar 20 08:13:12 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% -%% Copyright (C) 2024 The Octave Project Developers -%% -%% See the file COPYRIGHT.md in the top-level directory of this -%% distribution or . -%% -%% This file is part of Octave. -%% -%% Octave is free software: you can redistribute it and/or modify it -%% under the terms of the GNU General Public License as published by -%% the Free Software Foundation, either version 3 of the License, or -%% (at your option) any later version. -%% -%% Octave is distributed in the hope that it will be useful, but -%% WITHOUT ANY WARRANTY; without even the implied warranty of -%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -%% GNU General Public License for more details. -%% -%% You should have received a copy of the GNU General Public License -%% along with Octave; see the file COPYING. If not, see -%% . -%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -% class cdef_help1 : class help text ABOVE classdef keyword. -% -% Type 'help cdef_help1' - -classdef cdef_help1 - % -*- texinfo -*- - % class cdef_help1 : class help text BELOW classdef keyword. - % - % Type 'help cdef_help1' - - properties - % prop1: property help text ABOVE property name. - % Type "help cdef_help1.prop1" - prop1 % prop1: EOL-comment text. Should not be displayed - prop2 % prop2: property help text in EOL-comment for property PROP2. Type "help cdef_help1.prop2" - end - - methods - - % cdef_help1: constructor help text ABOVE function keyword - % Type 'help cdef_help1.cdef_help1'. - function obj = cdef_help1 (p1, p2) - % cdef_help1: constructor help text BELOW function keyword - % Type 'help cdef_help1.cdef_help1'. - if (nargin ~= 2) - obj.prop1 = 'default'; - obj.prop2 = 42; - else - obj.prop1 = p1; - obj.prop2 = p2; - end - end - - % meth1: method help text ABOVE function - % - % Type 'help cdef_help1.meth1'. - function obj2 = meth1 (obj, n) - obj2 = n + obj; - end - - function obj2 = meth2 (obj, n) - - % meth2: method help text BELOW function - % The blank line between function and comment is intentional. - % Type 'help cdef_help1.meth2'. - obj2 = n - obj; - end - - % meth3: method help text ABOVE function - % Type 'help cdef_help1.meth3'. - % This should not be shown. - function obj3 = meth3 (obj, n) - % meth3: method help text BELOW function - % Type 'help cdef_help1.meth3'. - % This should be displayed. - obj3 = obj + n; - end - - function obj4 = meth4 (obj, n) - - obj4 = n - obj; - if (n) - % meth4: pure comment text. This should *never* be displayed. - % Type 'help cdef_help1.meth4'. - end - end - - end - -end diff -r 3305b504bc2b -r 5565b3e6eb60 test/bug-65220/cdefdir/cdef_help2.m --- a/test/bug-65220/cdefdir/cdef_help2.m Wed Mar 20 08:13:12 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -######################################################################## -## -## Copyright (C) 2024 The Octave Project Developers -## -## See the file COPYRIGHT.md in the top-level directory of this -## distribution or . -## -## This file is part of Octave. -## -## Octave is free software: you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## . -## -######################################################################## - -classdef cdef_help2 - # -*- texinfo -*- - # class cdef_help2 : class help text BELOW classdef keyword. - # - # Type 'help cdef_help2' - - properties - # prop1: property help text ABOVE property name. - # Type "help cdef_help2.prop1" - prop1 # prop1: EOL-comment text. Should not be displayed - prop2 # prop2: property help text in EOL-comment for property PROP2. Type "help cdef_help2.prop2" - end - - methods - - # cdef_help2: constructor help text ABOVE function keyword - # Type 'help cdef_help2.cdef_help2'. - # This should be shown because Octave comment character '#' is used. - function obj = cdef_help2 (p1, p2) - # cdef_help2: constructor help text BELOW function keyword - # Type 'help cdef_help2.cdef_help2'. - if (nargin ~= 2) - obj.prop1 = 'default'; - obj.prop2 = 42; - else - obj.prop1 = p1; - obj.prop2 = p2; - end - end - - # meth1: method help text ABOVE function - # - # Type 'help cdef_help2.meth1'. - function obj2 = meth1 (obj, n) - obj2 = n + obj; - end - - function obj2 = meth2 (obj, n) - - # meth2: method help text BELOW function - # The blank line between function and comment is intentional. - # Type 'help cdef_help2.meth2'. - obj2 = n - obj; - end - - # meth3: method help text ABOVE function - # Type 'help cdef_help2.meth3'. - # This should be shown because Octave comment character '#' is used. - function obj3 = meth3 (obj, n) - # meth3: method help text BELOW function - # Type 'help cdef_help2.meth3'. - # This should NOT be displayed. - obj3 = obj + n; - end - - function obj4 = meth4 (obj, n) - - obj4 = n - obj; - if (n) - # meth4: pure comment text. This should *never* be displayed. - # Type 'help cdef_help2.meth4'. - end - end - - end - -end diff -r 3305b504bc2b -r 5565b3e6eb60 test/bug-65220/module.mk --- a/test/bug-65220/module.mk Wed Mar 20 08:13:12 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -bug_65220_TEST_FILES = \ - %reldir%/bug-65220.tst \ - %reldir%/cdefdir/cdef_help1.m \ - %reldir%/cdefdir/cdef_help2.m - -TEST_FILES += $(bug_65220_TEST_FILES) diff -r 3305b504bc2b -r 5565b3e6eb60 test/help/cdefdir/cdef_help1.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/help/cdefdir/cdef_help1.m Fri Mar 22 19:45:02 2024 +0100 @@ -0,0 +1,95 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Copyright (C) 2024 The Octave Project Developers +%% +%% See the file COPYRIGHT.md in the top-level directory of this +%% distribution or . +%% +%% This file is part of Octave. +%% +%% Octave is free software: you can redistribute it and/or modify it +%% under the terms of the GNU General Public License as published by +%% the Free Software Foundation, either version 3 of the License, or +%% (at your option) any later version. +%% +%% Octave is distributed in the hope that it will be useful, but +%% WITHOUT ANY WARRANTY; without even the implied warranty of +%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%% GNU General Public License for more details. +%% +%% You should have received a copy of the GNU General Public License +%% along with Octave; see the file COPYING. If not, see +%% . +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% class cdef_help1 : class help text ABOVE classdef keyword. +% +% Type 'help cdef_help1' + +classdef cdef_help1 + % -*- texinfo -*- + % class cdef_help1 : class help text BELOW classdef keyword. + % + % Type 'help cdef_help1' + + properties + % prop1: property help text ABOVE property name. + % Type "help cdef_help1.prop1" + prop1 % prop1: EOL-comment text. Should not be displayed + prop2 % prop2: property help text in EOL-comment for property PROP2. Type "help cdef_help1.prop2" + end + + methods + + % cdef_help1: constructor help text ABOVE function keyword + % Type 'help cdef_help1.cdef_help1'. + function obj = cdef_help1 (p1, p2) + % cdef_help1: constructor help text BELOW function keyword + % Type 'help cdef_help1.cdef_help1'. + if (nargin ~= 2) + obj.prop1 = 'default'; + obj.prop2 = 42; + else + obj.prop1 = p1; + obj.prop2 = p2; + end + end + + % meth1: method help text ABOVE function + % + % Type 'help cdef_help1.meth1'. + function obj2 = meth1 (obj, n) + obj2 = n + obj; + end + + function obj2 = meth2 (obj, n) + + % meth2: method help text BELOW function + % The blank line between function and comment is intentional. + % Type 'help cdef_help1.meth2'. + obj2 = n - obj; + end + + % meth3: method help text ABOVE function + % Type 'help cdef_help1.meth3'. + % This should not be shown. + function obj3 = meth3 (obj, n) + % meth3: method help text BELOW function + % Type 'help cdef_help1.meth3'. + % This should be displayed. + obj3 = obj + n; + end + + function obj4 = meth4 (obj, n) + + obj4 = n - obj; + if (n) + % meth4: pure comment text. This should *never* be displayed. + % Type 'help cdef_help1.meth4'. + end + end + + end + +end diff -r 3305b504bc2b -r 5565b3e6eb60 test/help/cdefdir/cdef_help2.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/help/cdefdir/cdef_help2.m Fri Mar 22 19:45:02 2024 +0100 @@ -0,0 +1,92 @@ +######################################################################## +## +## Copyright (C) 2024 The Octave Project Developers +## +## See the file COPYRIGHT.md in the top-level directory of this +## distribution or . +## +## This file is part of Octave. +## +## Octave is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## . +## +######################################################################## + +classdef cdef_help2 + # -*- texinfo -*- + # class cdef_help2 : class help text BELOW classdef keyword. + # + # Type 'help cdef_help2' + + properties + # prop1: property help text ABOVE property name. + # Type "help cdef_help2.prop1" + prop1 # prop1: EOL-comment text. Should not be displayed + prop2 # prop2: property help text in EOL-comment for property PROP2. Type "help cdef_help2.prop2" + end + + methods + + # cdef_help2: constructor help text ABOVE function keyword + # Type 'help cdef_help2.cdef_help2'. + # This should be shown because Octave comment character '#' is used. + function obj = cdef_help2 (p1, p2) + # cdef_help2: constructor help text BELOW function keyword + # Type 'help cdef_help2.cdef_help2'. + if (nargin ~= 2) + obj.prop1 = 'default'; + obj.prop2 = 42; + else + obj.prop1 = p1; + obj.prop2 = p2; + end + end + + # meth1: method help text ABOVE function + # + # Type 'help cdef_help2.meth1'. + function obj2 = meth1 (obj, n) + obj2 = n + obj; + end + + function obj2 = meth2 (obj, n) + + # meth2: method help text BELOW function + # The blank line between function and comment is intentional. + # Type 'help cdef_help2.meth2'. + obj2 = n - obj; + end + + # meth3: method help text ABOVE function + # Type 'help cdef_help2.meth3'. + # This should be shown because Octave comment character '#' is used. + function obj3 = meth3 (obj, n) + # meth3: method help text BELOW function + # Type 'help cdef_help2.meth3'. + # This should NOT be displayed. + obj3 = obj + n; + end + + function obj4 = meth4 (obj, n) + + obj4 = n - obj; + if (n) + # meth4: pure comment text. This should *never* be displayed. + # Type 'help cdef_help2.meth4'. + end + end + + end + +end diff -r 3305b504bc2b -r 5565b3e6eb60 test/help/cdefdir/cdef_help3.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/help/cdefdir/cdef_help3.m Fri Mar 22 19:45:02 2024 +0100 @@ -0,0 +1,38 @@ +######################################################################## +## +## Copyright (C) 2024 The Octave Project Developers +## +## See the file COPYRIGHT.md in the top-level directory of this +## distribution or . +## +## This file is part of Octave. +## +## Octave is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## . +## +######################################################################## + +classdef cdef_help3 + properties + prop1 = 13; + prop2 = 42; + end + + methods + function obj = cdef_help3 (p1, p2) + obj.prop1 = p1; + obj.prop2 = p2; + end + end +end diff -r 3305b504bc2b -r 5565b3e6eb60 test/help/cdefdir/cdef_help4.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/help/cdefdir/cdef_help4.m Fri Mar 22 19:45:02 2024 +0100 @@ -0,0 +1,31 @@ +######################################################################## +## +## Copyright (C) 2024 The Octave Project Developers +## +## See the file COPYRIGHT.md in the top-level directory of this +## distribution or . +## +## This file is part of Octave. +## +## Octave is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## . +## +######################################################################## + +classdef cdef_help4 + properties + prop1 = 13; + prop2 = 42; + end +end diff -r 3305b504bc2b -r 5565b3e6eb60 test/help/help.tst --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/help/help.tst Fri Mar 22 19:45:02 2024 +0100 @@ -0,0 +1,254 @@ +######################################################################## +## +## Copyright (C) 2024 The Octave Project Developers +## +## See the file COPYRIGHT.md in the top-level directory of this +## distribution or . +## +## This file is part of Octave. +## +## Octave is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## . +## +######################################################################## + +%!test <*65220> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! ## Check methods first (bug was disguised if class checked first) +%! s = help ('cdef_help1.meth1'); +%! assert (regexp (s, 'meth1: method help text ABOVE function')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65220> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! s = help ('cdef_help1.meth2'); +%! assert (regexp (s, 'meth2: method help text BELOW function')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65220> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! s = help ('cdef_help1.meth3'); +%! assert (regexp (s, 'meth3: method help text BELOW function')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65258> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! s = help ('cdef_help1.meth4'); +%! assert (regexp (s, 'undocumented method: obj4 = meth4 \(obj, n\)')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65220> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! ## Check documentation for entire class +%! s = help ('cdef_help1'); +%! assert (regexp (s, 'class cdef_help1 : class help text ABOVE classdef')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65220> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! ## Check documentation for constructor +%! s = help ('cdef_help1.cdef_help1'); +%! assert (regexp (s, 'cdef_help1: constructor help text BELOW function')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65220> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! ## Check documentation for properties +%! s = help ('cdef_help1.prop1'); +%! assert (regexp (s, 'prop1: property help text ABOVE property')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65220> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! s = help ('cdef_help1.prop2'); +%! assert (regexp (s, 'prop2: property help text in EOL-comment')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65220> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! ## Check methods first (bug was disguised if class checked first) +%! s = help ('cdef_help2.meth1'); +%! assert (regexp (s, 'meth1: method help text ABOVE function')); +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%! +%!test <*65220> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! s = help ('cdef_help2.meth2'); +%! assert (regexp (s, 'meth2: method help text BELOW function')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65220> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! s = help ('cdef_help2.meth3'); +%! assert (regexp (s, 'meth3: method help text ABOVE function')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65220> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! s = help ('cdef_help2.meth4'); +%! assert (regexp (s, 'undocumented method: obj4 = meth4 \(obj, n\)')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65220> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! ## Check documentation for entire class +%! s = help ('cdef_help2'); +%! assert (regexp (s, 'class cdef_help2 : class help text BELOW classdef')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65220> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! ## Check documentation for constructor +%! s = help ('cdef_help2.cdef_help2'); +%! assert (regexp (s, 'cdef_help2: constructor help text ABOVE function')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65220> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! ## Check documentation for properties +%! s = help ('cdef_help2.prop1'); +%! assert (regexp (s, 'prop1: property help text ABOVE property')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65220> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! s = help ('cdef_help2.prop2'); +%! assert (regexp (s, 'prop2: property help text in EOL-comment')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65258> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! s = help ('cdef_help3'); +%! assert (regexp (s, 'undocumented constructor: obj = cdef_help3 \(p1, p2\)')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65258> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! s = help ('cdef_help3.cdef_help3'); +%! assert (regexp (s, 'undocumented constructor: obj = cdef_help3 \(p1, p2\)')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65258> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! s = help ('cdef_help4'); +%! assert (regexp (s, 'default constructor: obj = cdef_help4 \(\)')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!test <*65258> +%! unwind_protect +%! addpath ('cdefdir'); +%! +%! s = help ('cdef_help4.cdef_help4'); +%! assert (regexp (s, 'default constructor: obj = cdef_help4 \(\)')); +%! +%! unwind_protect_cleanup +%! rmpath ('cdefdir'); +%! end_unwind_protect + +%!assert <*65258> (regexp (help ('undoc_fcn'), 'undocumented function: \[x, y, z\] = undoc_fcn \(a, b, ~, c = 3\)')) diff -r 3305b504bc2b -r 5565b3e6eb60 test/help/module.mk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/help/module.mk Fri Mar 22 19:45:02 2024 +0100 @@ -0,0 +1,9 @@ +help_TEST_FILES = \ + %reldir%/help.tst \ + %reldir%/undoc_fcn.m \ + %reldir%/cdefdir/cdef_help1.m \ + %reldir%/cdefdir/cdef_help2.m \ + %reldir%/cdefdir/cdef_help3.m \ + %reldir%/cdefdir/cdef_help4.m + +TEST_FILES += $(help_TEST_FILES) diff -r 3305b504bc2b -r 5565b3e6eb60 test/help/undoc_fcn.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/help/undoc_fcn.m Fri Mar 22 19:45:02 2024 +0100 @@ -0,0 +1,5 @@ +function [x, y, z] = undoc_fcn (a, b, ~, c = 3) + x = a; + y = b; + z = c; +end