Hello community,
here is the log from the commit of package octave-forge-doctest for
openSUSE:Factory checked in at 2018-07-28 12:40:23
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/octave-forge-doctest (Old)
and /work/SRC/openSUSE:Factory/.octave-forge-doctest.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "octave-forge-doctest"
Sat Jul 28 12:40:23 2018 rev:4 rq:624038 version:0.6.1
Changes:
--------
---
/work/SRC/openSUSE:Factory/octave-forge-doctest/octave-forge-doctest.changes
2017-02-03 17:51:42.897841757 +0100
+++
/work/SRC/openSUSE:Factory/.octave-forge-doctest.new/octave-forge-doctest.changes
2018-07-28 12:40:26.240429796 +0200
@@ -1,0 +2,18 @@
+Wed Jul 18 07:33:28 UTC 2018 - [email protected]
+
+- Update to version 0.6.1:
+ * Workaround regex bug on ARM (again!).
+- Changes from version 0.6.0:
+ * Tests can now call "clear" and "clear all".
+ * Fixes for running on Octave development versions (upcoming
+ 4.4.0).
+ * Minimum supported Octave version is now 4.2.0. The package no
+ longer has any compiled code and does not include an "evalc"
+ implementation.
+- Update Requires: octave-cli > 4.2.0 is now required.
+- Update file list: pkg no longer installs to libdir.
+- BuildArch: noarch because pkg no longer installs arch dependent
+ binaries.
+- Untar tarball in build dir before running checks.
+
+-------------------------------------------------------------------
Old:
----
doctest-0.5.0.tar.gz
New:
----
doctest-0.6.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ octave-forge-doctest.spec ++++++
--- /var/tmp/diff_new_pack.HAoxH5/_old 2018-07-28 12:40:26.728430734 +0200
+++ /var/tmp/diff_new_pack.HAoxH5/_new 2018-07-28 12:40:26.728430734 +0200
@@ -1,7 +1,7 @@
#
# spec file for package octave-forge-doctest
#
-# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,16 +18,17 @@
%define octpkg doctest
Name: octave-forge-%{octpkg}
-Version: 0.5.0
+Version: 0.6.1
Release: 0
Summary: Octave-Forge documentation tests
-License: GPL-3.0+ and BSD-3-Clause
+License: GPL-3.0-or-later AND BSD-3-Clause
Group: Productivity/Scientific/Math
Url: http://octave.sourceforge.net
Source0:
http://downloads.sourceforge.net/octave/%{octpkg}-%{version}.tar.gz
BuildRequires: gcc-c++
BuildRequires: octave-devel
-Requires: octave-cli >= 4.0.0
+Requires: octave-cli >= 4.2.0
+BuildArch: noarch
%description
The Octave-Forge Doctest package finds specially-formatted blocks of example
@@ -47,6 +48,7 @@
%octave_pkg_install
%check
+tar -zxvf %{octpkg}-%{version}.tar.gz
%octave_pkg_test
%post
@@ -58,6 +60,5 @@
%files
%defattr(-,root,root)
%{octpackages_dir}/%{octpkg}-%{version}
-%{octlib_dir}/%{octpkg}-%{version}
%changelog
++++++ doctest-0.5.0.tar.gz -> doctest-0.6.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/DESCRIPTION
new/doctest-0.6.1/DESCRIPTION
--- old/doctest-0.5.0/DESCRIPTION 2016-11-14 07:08:14.000000000 +0100
+++ new/doctest-0.6.1/DESCRIPTION 2018-01-04 20:48:27.000000000 +0100
@@ -1,6 +1,6 @@
Name: doctest
-Version: 0.5.0
-Date: 2016-11-13
+Version: 0.6.1
+Date: 2018-01-04
Author: various authors
Maintainer: Colin B. Macdonald <[email protected]>, Michael Walter
<[email protected]>
Title: Documentation tests
@@ -9,6 +9,6 @@
the code and confirms the output is correct. This can be useful as part of
a testing framework or simply to ensure that documentation stays up-to-date
during software development.
-Depends: octave (>= 4.0.0)
+Depends: octave (>= 4.2.0)
Url: https://github.com/catch22/octave-doctest
License: BSD-3-Clause
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/NEWS new/doctest-0.6.1/NEWS
--- old/doctest-0.5.0/NEWS 2016-11-14 07:08:14.000000000 +0100
+++ new/doctest-0.6.1/NEWS 2018-01-04 20:48:27.000000000 +0100
@@ -1,3 +1,22 @@
+doctest 0.6.1 (2018-01-04)
+==========================
+
+ * Workaround regex bug on ARM (again!).
+
+
+
+doctest 0.6.0 (2017-12-25)
+==========================
+
+ * Tests can now call "clear" and "clear all".
+
+ * Fixes for running on Octave development versions (upcoming 4.4.0).
+
+ * Minimum supported Octave version is now 4.2.0. The package no longer
+ has any compiled code and does not include an "evalc" implementation.
+
+
+
doctest 0.5.0 (2016-11-13)
==========================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/inst/doctest.m
new/doctest-0.6.1/inst/doctest.m
--- old/doctest-0.5.0/inst/doctest.m 2016-11-14 07:08:14.000000000 +0100
+++ new/doctest-0.6.1/inst/doctest.m 2018-01-04 20:48:27.000000000 +0100
@@ -1,6 +1,6 @@
%% Copyright (c) 2010 Thomas Grenfell Smith
%% Copyright (c) 2011, 2013-2016 Michael Walter
-%% Copyright (c) 2015-2016 Colin B. Macdonald
+%% Copyright (c) 2015-2017 Colin B. Macdonald
%%
%% Redistribution and use in source and binary forms, with or without
%% modification, are permitted provided that the following conditions are met:
@@ -273,7 +273,7 @@
[color_ok, color_err, color_warn, reset] = doctest_colors(fid);
% print banner
-fprintf(fid, 'Doctest v0.5.0: this is Free Software without warranty, see
source.\n\n');
+fprintf(fid, 'Doctest v0.6.1: this is Free Software without warranty, see
source.\n\n');
summary = struct();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/inst/private/doctest_collect.m
new/doctest-0.6.1/inst/private/doctest_collect.m
--- old/doctest-0.5.0/inst/private/doctest_collect.m 2016-11-14
07:08:14.000000000 +0100
+++ new/doctest-0.6.1/inst/private/doctest_collect.m 2018-01-04
20:48:27.000000000 +0100
@@ -1,13 +1,19 @@
function summary = doctest_collect(what, directives, summary, recursive,
depth, fid)
-% Find and run doctests.
+%DOCTEST_COLLECT Find and run doctests.
%
-% The parameter WHAT is the name of a class, directory, function or filename:
+% The parameter WHAT is the name of a class, directory, function or filename:
% * For a directory, calls itself on the contents, recursively if
% RECURSIVE is true;
% * For a class, all methods are tested;
% * When running Octave, it can also be the filename of a Texinfo file.
-%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%
+% Copyright (c) 2010 Thomas Grenfell Smith
+% Copyright (c) 2015 Michael Walter
+% Copyright (c) 2015-2017 Colin B. Macdonald
+% Copyright (c) 2015 Oliver Heimlich
+% This is Free Software, BSD-3-Clause, see doctest.m for details.
+
% TODO: methods('logical') octave/matlab differ: which behaviour do we want?
% TODO: what about builtin "test" versus dir "test/"? Do we prefer dir?
@@ -170,7 +176,7 @@
end
% run doctest
- results = doctest_run(target.docstring, directives);
+ results = doctest_run_docstring(target.docstring, directives);
% determine number of tests passed
num_tests = numel(results);
@@ -233,6 +239,19 @@
% Octave methods('@foo') gives java error, Matlab just says "No methods"
what = what(2:end);
end
+
+ % TODO: workaround github.com/catch22/octave-doctest/issues/135 by
+ % accessing all non-constructor method help text *before* "help obj"
+ if (is_octave ())
+ meths = methods (what);
+ for i=1:numel (meths)
+ if (~ strcmp (meths{i}, what)) % skip @obj/obj
+ name = sprintf ('@%s%s%s', what, filesep (), meths{i});
+ [docstring, format] = get_help_text (name);
+ end
+ end
+ end % end workaround
+
% First, "help class". For classdef, this differs from "help class.class"
% (general class help vs constructor help). For old-style classes we will
% probably end up testing the constructor twice but... meh.
@@ -319,17 +338,40 @@
% Mark the occurrence of “@example” and “@end example” to be able to find
% example blocks after conversion from texi to plain text. Also consider
% indentation, so we can later correctly unindent the example's content.
- % Note: uses “@example” instead of “$2” to avoid ARM-specific bug #130.
- str = regexprep (str, ...
- '^([ \t]*)(\@example)(.*)$', ...
- [ '$1\@example$3\n', ... % retain original line
- '$1###### EXAMPLE START ######'], ...
- 'lineanchors', 'dotexceptnewline', 'emptymatch');
- str = regexprep (str, ...
- '^([ \t]*)(\@end example)(.*)$', ...
- [ '$1###### EXAMPLE STOP ######\n', ...
- '$1\@end example$3'], ... % retain original line
- 'lineanchors', 'dotexceptnewline', 'emptymatch');
+
+ % These should work, but I keep hitting ARM-specific when $1 is empty:
+ % https://savannah.gnu.org/bugs/index.php?52810
+ %str = regexprep (str, ...
+ % '^([ \t]*)(\@example)(.*)$', ...
+ % [ '$1$2$3\n', ... % retain original line
+ % '$1###### EXAMPLE START ######'], ...
+ % 'lineanchors', 'dotexceptnewline', 'emptymatch');
+ %str = regexprep (str, ...
+ % '^([ \t]*)(\@end example)(.*)$', ...
+ % [ '$1###### EXAMPLE STOP ######\n', ...
+ % '$1$2$3'], ... % retain original line
+ % 'lineanchors', 'dotexceptnewline', 'emptymatch');
+
+ % Instead we do it manually
+ [S, E, TE, M, T, NM, SP] = regexp (str, '^([ \t]*)(\@example)(.*)$', ...
+ 'lineanchors', 'dotexceptnewline', 'emptymatch');
+ str = SP{1};
+ for i=1:length (T)
+ str = [str ...
+ T{i}{:} sprintf('\n') ... % retain original line
+ T{i}{1} '###### EXAMPLE START ######' ...
+ SP{i+1}];
+ end
+
+ [S, E, TE, M, T, NM, SP] = regexp (str, '^([ \t]*)(\@end example)(.*)$', ...
+ 'lineanchors', 'dotexceptnewline', 'emptymatch');
+ str = SP{1};
+ for i=1:length (T)
+ str = [str ...
+ T{i}{1} '###### EXAMPLE STOP ######' sprintf('\n') ...
+ T{i}{:} ... % retain original line
+ SP{i+1}];
+ end
% special comments "@c doctest: cmd" are translated
% FIXME the expression would also match @@c doctest: ...
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/inst/private/doctest_colors.m
new/doctest-0.6.1/inst/private/doctest_colors.m
--- old/doctest-0.5.0/inst/private/doctest_colors.m 2016-11-14
07:08:14.000000000 +0100
+++ new/doctest-0.6.1/inst/private/doctest_colors.m 2018-01-04
20:48:27.000000000 +0100
@@ -1,8 +1,13 @@
function [color_ok, color_err, color_warn, reset] = doctest_colors(fid)
-% Return terminal color codes to use for current invocation of doctest.
+%DOCTEST_COLORS Return terminal color codes.
%
-% FIXME: Shouldn't use colors if stdout is not a TTY.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% FIXME: Shouldn't use colors if stdout is not a TTY.
+
+%%
+% Copyright (c) 2015 Michael Walter
+% Copyright (c) 2015, 2017 Colin B. Macdonald
+% This is Free Software, BSD-3-Clause, see doctest.m for details.
+
% by default, no colors
color_ok = '';
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/inst/private/doctest_compare.m
new/doctest-0.6.1/inst/private/doctest_compare.m
--- old/doctest-0.5.0/inst/private/doctest_compare.m 2016-11-14
07:08:14.000000000 +0100
+++ new/doctest-0.6.1/inst/private/doctest_compare.m 2018-01-04
20:48:27.000000000 +0100
@@ -1,5 +1,5 @@
function match = doctest_compare(want, got, normalize_whitespace, ellipsis)
-%DOCTEST_COMPARE check if two strings match
+%DOCTEST_COMPARE Check if two strings match.
%
% Returns true if string GOT matches the template string WANT. Basically
% WANT and GOT should be identical, except:
@@ -9,7 +9,13 @@
% * WANT can have "..."; matches anything in GOT (if ELLIPSIS is true);
% * WANT can omit "ans = ";
% * various other nonsense of unknown current relevance.
-%
+
+%%
+% Copyright (c) 2010 Thomas Grenfell Smith
+% Copyright (c) 2015 Michael Walter
+% Copyright (c) 2015-2016 Colin B. Macdonald
+% This is Free Software, BSD-3-Clause, see doctest.m for details.
+
% This looks bad, like hardcoding for lower-case "a href"
% and a double quote... but that's what MATLAB looks for too.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/inst/private/doctest_datastore.m
new/doctest-0.6.1/inst/private/doctest_datastore.m
--- old/doctest-0.5.0/inst/private/doctest_datastore.m 1970-01-01
01:00:00.000000000 +0100
+++ new/doctest-0.6.1/inst/private/doctest_datastore.m 2018-01-04
20:48:27.000000000 +0100
@@ -0,0 +1,44 @@
+function out = doctest_datastore(action, arg)
+%DOCTEST_DATASTORE Used internally by doctest.
+%
+% Usage:
+% doctest_datastore(action, arg)
+% Store variables in a way that survives "clear" and "clear all".
+%
+% See https://gcurrentub.com/catch22/octave-doctest/issues/149 for discussion.
+
+%%
+% Copyright (c) 2017 Colin B. Macdonald
+% Copyright (c) 2017 Michael Walter
+% This is Free Software, BSD-3-Clause, see doctest.m for details.
+
+
+mlock();
+persistent i tests;
+
+switch lower(action)
+ case 'clear_and_munlock'
+ % don't leave persistent data lying around
+ tests = [];
+ i = [];
+
+ % unlock so that changes to .m file are picked up again
+ munlock();
+
+ case 'set_tests'
+ tests = num2cell(arg); % cell array so it can be heterogeneous
+ case 'get_tests'
+ out = tests;
+
+ case 'set_current_index'
+ i = arg;
+ case 'set_current_test'
+ tests{i} = arg;
+ case 'get_current_test'
+ out = tests{i};
+
+ otherwise
+ error('unexpected action "%s"', action);
+end
+
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/doctest-0.5.0/inst/private/doctest_default_directives.m
new/doctest-0.6.1/inst/private/doctest_default_directives.m
--- old/doctest-0.5.0/inst/private/doctest_default_directives.m 2016-11-14
07:08:14.000000000 +0100
+++ new/doctest-0.6.1/inst/private/doctest_default_directives.m 2018-01-04
20:48:27.000000000 +0100
@@ -1,11 +1,16 @@
function d = doctest_default_directives(varargin)
-%DOCTEST_DEFAULT_DIRECTIVES Return/set defaults directives
+%DOCTEST_DEFAULT_DIRECTIVES Return/set defaults directives.
% Possible calling forms:
% dirs = doctest_default_directives()
% dirs = doctest_default_directives('ellipsis', true)
% dirs = doctest_default_directives(dirs, 'ellipsis', true)
% See source/documentation for valid directives.
+%%
+% Copyright (c) 2015 Colin B. Macdonald
+% This is Free Software, BSD-3-Clause, see doctest.m for details.
+
+
defaults.normalize_whitespace = true;
defaults.ellipsis = true;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/doctest-0.5.0/inst/private/doctest_format_exception.m
new/doctest-0.6.1/inst/private/doctest_format_exception.m
--- old/doctest-0.5.0/inst/private/doctest_format_exception.m 1970-01-01
01:00:00.000000000 +0100
+++ new/doctest-0.6.1/inst/private/doctest_format_exception.m 2018-01-04
20:48:27.000000000 +0100
@@ -0,0 +1,31 @@
+function formatted = doctest_format_exception(ex)
+%DOCTEST_FORMAT_EXCEPTION Used internally by doctest.
+%
+% Usage:
+% doctest_format_exception(ex)
+% Given an exception, return error message to be reported.
+
+%%
+% Copyright (c) 2010 Thomas Grenfell Smith
+% Copyright (c) 2015 Colin B. Macdonald
+% Copyright (c) 2015, 2017 Michael Walter
+% This is Free Software, BSD-3-Clause, see doctest.m for details.
+
+
+% octave?
+if is_octave()
+ formatted = ['??? ' ex.message];
+ return
+end
+
+% matlab!
+if strcmp(ex.stack(1).name, 'doctest_run_tests')
+ % we don't want the report, we just want the message
+ % otherwise it'll talk about evalc, which is not what the user got on
+ % the command line.
+ formatted = ['??? ' ex.message];
+else
+ formatted = ['??? ' ex.getReport('basic')];
+end
+
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/inst/private/doctest_join_conditions.m
new/doctest-0.6.1/inst/private/doctest_join_conditions.m
--- old/doctest-0.5.0/inst/private/doctest_join_conditions.m 1970-01-01
01:00:00.000000000 +0100
+++ new/doctest-0.6.1/inst/private/doctest_join_conditions.m 2018-01-04
20:48:27.000000000 +0100
@@ -0,0 +1,20 @@
+function result = doctest_join_conditions(conditions)
+%DOCTEST_JOIN_CONDITIONS Used internally by doctest.
+%
+% Usage:
+% doctest_join_conditions(conditions)
+% Given a cell array of conditions (represented as strings to be
eval'ed),
+% return the string that corresponds to their logical "or".
+
+%%
+% Copyright (c) 2015, 2017 Michael Walter
+% This is Free Software, BSD-3-Clause, see doctest.m for details.
+
+
+if isempty(conditions)
+ result = 'false';
+else
+ result = strcat('(', strjoin(conditions, ') || ('), ')');
+end
+
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/inst/private/doctest_run.m
new/doctest-0.6.1/inst/private/doctest_run.m
--- old/doctest-0.5.0/inst/private/doctest_run.m 2016-11-14
07:08:14.000000000 +0100
+++ new/doctest-0.6.1/inst/private/doctest_run.m 1970-01-01
01:00:00.000000000 +0100
@@ -1,179 +0,0 @@
-function results = doctest_run(docstring, defaults)
-%DOCTEST_RUN - used internally by doctest
-%
-% Usage:
-% doctest_run(docstring)
-% Runs all the examples in the given docstring and returns a
-% structure with the results from running.
-%
-% The return value is a structure with the following fields:
-%
-% results.source: the source code that was run
-% results.want: the desired output
-% results.got: the output that was recieved
-% results.passed: whether .want and .got match each other according to
-% doctest_compare.
-%
-
-% extract tests from docstring
-TEST_RE = [ % loosely based on Python 2.6
doctest.py, line 510
- '(?m)(?-s)' ... % options
- '(?:^ *>> )' ... % ">> "
- '(.*(?:\n *\.\. .*)*)\n' ... % rest of line + ".. " lines
- '((?:(?:^ *$\n)?(?!\s*>>).*\S.*\n)*)']; % the output
-
-tests = [];
-test_matches = regexp(docstring, TEST_RE, 'tokens');
-for i=1:length(test_matches)
- % each block should be split into source and desired output
- source = test_matches{i}{1};
- tests(i).want = test_matches{i}{2};
-
- % replace initial '..' by ' ' in subsequent lines
- lines = strsplit(source, '\n');
- source = lines{1};
- for j = 2:length(lines)
- T = regexp(lines{j}, '^\s*(\.\.)(.*)$', 'tokens');
- assert(length(T) == 1);
- T = T{1};
- assert(length(T) == 2);
- source = sprintf('%s\n %s', source, T{2});
- end
- tests(i).source = source;
-
- % set default options
- tests(i).normalize_whitespace = defaults.normalize_whitespace;
- tests(i).ellipsis = defaults.ellipsis;
- tests(i).skip = {};
- tests(i).xfail = {};
-
- % find and process directives
- re = [ ...
- '[#%]\s*doctest:\s+' ... % e.g., "# doctest: "
- '([\+\-]\w+)' ... % token for cmd, e.g., "+XSKIP_IF"
- '(\s*\(' ... % token for code, starting with "("
- '[^#%\n]+' ... % no newlines, no comments in code
- '\))?']; % ")" of code, at most one code arg
- directive_matches = regexp(tests(i).source, re, 'tokens');
- for j = 1:length(directive_matches)
- directive = directive_matches{j}{1};
- if (strcmp('+SKIP_IF', directive) || strcmp('+SKIP_UNLESS', directive) ||
strcmp('+XFAIL_IF', directive) || strcmp('+XFAIL_UNLESS', directive))
- if length(directive_matches{j}) == 2
- condition = directive_matches{j}{2};
- else
- error('doctest: syntax error, expected %s(varname)', directive);
- end
- end
-
- if strcmp('NORMALIZE_WHITESPACE', directive(2:end))
- tests(i).normalize_whitespace = strcmp(directive(1), '+');
- elseif strcmp('ELLIPSIS', directive(2:end))
- tests(i).ellipsis = strcmp(directive(1), '+');
- elseif strcmp('+SKIP', directive)
- tests(i).skip{end + 1} = 'true';
- elseif strcmp('+SKIP_IF', directive)
- tests(i).skip{end + 1} = condition;
- elseif strcmp('+SKIP_UNLESS', directive)
- tests(i).skip{end + 1} = sprintf('~(%s)', condition);
- elseif strcmp('+XFAIL', directive)
- tests(i).xfail{end + 1} = 'true';
- elseif strcmp('+XFAIL_IF', directive)
- tests(i).xfail{end + 1} = condition;
- elseif strcmp('+XFAIL_UNLESS', directive)
- tests(i).xfail{end + 1} = sprintf('~(%s)', condition);
- else
- warning('Doctest:unexpected-directive', 'doctest: ignoring unexpected
directive %s', directive);
- end
- end
-end
-
-% run tests in a local namespace
-results = DOCTEST__run_impl(tests);
-
-end
-
-
-% given a cell array of conditions (represented as strings to be eval'ed),
-% return the string that corresponds to their logical "or".
-function result = DOCTEST__join_conditions(conditions)
- if isempty(conditions)
- result = 'false';
- else
- result = strcat('(', strjoin(conditions, ') || ('), ')');
- end
-end
-
-% the following function is used to evaluate all lines of code in same
-% namespace (the one of this invocation of DOCTEST__run_impl)
-function DOCTEST__results = DOCTEST__run_impl(DOCTEST__tests)
-
-% do not split long rows (TODO: how to do this on MATLAB?)
-if is_octave()
- split_long_rows(0, 'local')
-end
-
-% define test-global constants
-DOCTEST_OCTAVE = is_octave();
-DOCTEST_MATLAB = ~DOCTEST_OCTAVE;
-
-% Octave has [no evalc command](https://savannah.gnu.org/patch/?8033)
-DOCTEST__has_builtin_evalc = exist('evalc', 'builtin');
-
-DOCTEST__results = [];
-for DOCTEST__i = 1:numel(DOCTEST__tests)
- DOCTEST__result = DOCTEST__tests(DOCTEST__i);
-
- % determine whether test should be skipped
- % (careful about Octave bug #46397 to not change the current value of “ans”)
- eval (strcat ('DOCTEST__result.skip = ', ...
- DOCTEST__join_conditions (DOCTEST__result.skip), ...
- ';'));
- if (DOCTEST__result.skip)
- continue
- end
-
- % determine whether test is expected to fail
- % (careful about Octave bug #46397 to not change the current value of “ans”)
- eval (strcat ('DOCTEST__result.xfail = ', ...
- DOCTEST__join_conditions (DOCTEST__result.xfail), ...
- ';'));
-
- % evaluate input (structure adapted from a StackOverflow answer by user
Amro, see http://stackoverflow.com/questions/3283586 and
http://stackoverflow.com/users/97160/amro)
- try
- if (DOCTEST__has_builtin_evalc)
- DOCTEST__result.got = evalc(DOCTEST__result.source);
- else
- DOCTEST__result.got = doctest_evalc(DOCTEST__result.source);
- end
- catch DOCTEST__exception
- DOCTEST__result.got = DOCTEST__format_exception(DOCTEST__exception);
- end
-
- % determine if test has passed
- DOCTEST__result.passed = doctest_compare(DOCTEST__result.want,
DOCTEST__result.got, DOCTEST__result.normalize_whitespace,
DOCTEST__result.ellipsis);
- if DOCTEST__result.xfail
- DOCTEST__result.passed = ~DOCTEST__result.passed;
- end
-
- DOCTEST__results = [DOCTEST__results; DOCTEST__result];
-end
-
-end
-
-
-function formatted = DOCTEST__format_exception(ex)
-
- if is_octave()
- formatted = ['??? ' ex.message];
- return
- end
-
- if strcmp(ex.stack(1).name, 'DOCTEST__run_impl')
- % we don't want the report, we just want the message
- % otherwise it'll talk about evalc, which is not what the user got on
- % the command line.
- formatted = ['??? ' ex.message];
- else
- formatted = ['??? ' ex.getReport('basic')];
- end
-end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/inst/private/doctest_run_docstring.m
new/doctest-0.6.1/inst/private/doctest_run_docstring.m
--- old/doctest-0.5.0/inst/private/doctest_run_docstring.m 1970-01-01
01:00:00.000000000 +0100
+++ new/doctest-0.6.1/inst/private/doctest_run_docstring.m 2018-01-04
20:48:27.000000000 +0100
@@ -0,0 +1,98 @@
+function results = doctest_run_docstring(docstring, defaults)
+%DOCTEST_RUN_DOCSTRING Used internally by doctest.
+%
+% Usage: doctest_run_docstring(docstring, defaults)
+% Extract all the examples in the input docstring into a
+% structure. Process various flags and directives that
+% about each test. Run the tests in a common namespace.
+%
+% The return value is a structure with the following fields:
+%
+% results.source: the source code that was run
+% results.want: the desired output
+% results.got: the output that was recieved
+% results.passed: whether .want and .got match each other according to
+% doctest_compare.
+
+%%
+% Copyright (c) 2010 Thomas Grenfell Smith
+% Copyright (c) 2011, 2015 Michael Walter
+% Copyright (c) 2015-2017 Colin B. Macdonald
+% License: BSD-3-Clause, see doctest.m for details
+
+
+% extract tests from docstring
+TEST_RE = [ % loosely based on Python 2.6
doctest.py, line 510
+ '(?m)(?-s)' ... % options
+ '(?:^ *>> )' ... % ">> "
+ '(.*(?:\n *\.\. .*)*)\n' ... % rest of line + ".. " lines
+ '((?:(?:^ *$\n)?(?!\s*>>).*\S.*\n)*)']; % the output
+
+tests = [];
+test_matches = regexp(docstring, TEST_RE, 'tokens');
+for i=1:length(test_matches)
+ % each block should be split into source and desired output
+ source = test_matches{i}{1};
+ tests(i).want = test_matches{i}{2};
+
+ % replace initial '..' by ' ' in subsequent lines
+ lines = strsplit(source, '\n');
+ source = lines{1};
+ for j = 2:length(lines)
+ T = regexp(lines{j}, '^\s*(\.\.)(.*)$', 'tokens');
+ assert(length(T) == 1);
+ T = T{1};
+ assert(length(T) == 2);
+ source = sprintf('%s\n %s', source, T{2});
+ end
+ tests(i).source = source;
+
+ % set default options
+ tests(i).normalize_whitespace = defaults.normalize_whitespace;
+ tests(i).ellipsis = defaults.ellipsis;
+ tests(i).skip = {};
+ tests(i).xfail = {};
+
+ % find and process directives
+ re = [ ...
+ '[#%]\s*doctest:\s+' ... % e.g., "# doctest: "
+ '([\+\-]\w+)' ... % token for cmd, e.g., "+XSKIP_IF"
+ '(\s*\(' ... % token for code, starting with "("
+ '[^#%\n]+' ... % no newlines, no comments in code
+ '\))?']; % ")" of code, at most one code arg
+ directive_matches = regexp(tests(i).source, re, 'tokens');
+ for j = 1:length(directive_matches)
+ directive = directive_matches{j}{1};
+ if (strcmp('+SKIP_IF', directive) || strcmp('+SKIP_UNLESS', directive) ||
strcmp('+XFAIL_IF', directive) || strcmp('+XFAIL_UNLESS', directive))
+ if length(directive_matches{j}) == 2
+ condition = directive_matches{j}{2};
+ else
+ error('doctest: syntax error, expected %s(varname)', directive);
+ end
+ end
+
+ if strcmp('NORMALIZE_WHITESPACE', directive(2:end))
+ tests(i).normalize_whitespace = strcmp(directive(1), '+');
+ elseif strcmp('ELLIPSIS', directive(2:end))
+ tests(i).ellipsis = strcmp(directive(1), '+');
+ elseif strcmp('+SKIP', directive)
+ tests(i).skip{end + 1} = 'true';
+ elseif strcmp('+SKIP_IF', directive)
+ tests(i).skip{end + 1} = condition;
+ elseif strcmp('+SKIP_UNLESS', directive)
+ tests(i).skip{end + 1} = sprintf('~(%s)', condition);
+ elseif strcmp('+XFAIL', directive)
+ tests(i).xfail{end + 1} = 'true';
+ elseif strcmp('+XFAIL_IF', directive)
+ tests(i).xfail{end + 1} = condition;
+ elseif strcmp('+XFAIL_UNLESS', directive)
+ tests(i).xfail{end + 1} = sprintf('~(%s)', condition);
+ else
+ warning('Doctest:unexpected-directive', 'doctest: ignoring unexpected
directive %s', directive);
+ end
+ end
+end
+
+results = doctest_run_tests(tests);
+
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/inst/private/doctest_run_tests.m
new/doctest-0.6.1/inst/private/doctest_run_tests.m
--- old/doctest-0.5.0/inst/private/doctest_run_tests.m 1970-01-01
01:00:00.000000000 +0100
+++ new/doctest-0.6.1/inst/private/doctest_run_tests.m 2018-01-04
20:48:27.000000000 +0100
@@ -0,0 +1,98 @@
+function DOCTEST__results = doctest_run_tests(DOCTEST__tests)
+%DOCTEST_RUN_TESTS Used internally by doctest.
+%
+% Usage:
+% doctest_run_tests(tests)
+% Carefully evaluate each test in the "tests" structure in
+% a common newly-created clean namespace (specifically, this
+% functions workspace).
+%
+% The input is a structure with various fields including "tests.source",
+% the code to be run and "tests.want" the expected output. Various
+% other flags such as "tests.xfail" and "tests.ellipsis" effect how
+% the test is run and how the test output is compared.
+%
+% The return value is documented in "doctest_run_docstring".
+
+%%
+% Copyright (c) 2010 Thomas Grenfell Smith
+% Copyright (c) 2011, 2015 Michael Walter
+% Copyright (c) 2015-2017 Colin B. Macdonald
+% License: BSD-3-Clause, see doctest.m for details
+
+
+% Implementation note: all internal variables should start with
+% "DOCTEST__" as (1) these will necessarily be exposed to the tests
+% and (2) should not overwrite variables used by ongoing tests.
+
+% do not split long rows (TODO: how to do this on MATLAB?)
+if is_octave()
+ split_long_rows(0, 'local');
+end
+
+% initialize data store (used to preserve state across iterations
+% in the presence of "clear" and "clear all"s in tests)
+doctest_datastore('set_tests', DOCTEST__tests);
+
+for DOCTEST__i = 1:numel(DOCTEST__tests)
+ % from the second iteration on, the only local variable that we can
+ % rely on being present is DOCTEST__i
+ doctest_datastore('set_current_index', DOCTEST__i);
+ DOCTEST__current_test = doctest_datastore('get_current_test');
+
+ % define test-global constants (these are accessible by the tests)
+ DOCTEST_OCTAVE = is_octave();
+ DOCTEST_MATLAB = ~DOCTEST_OCTAVE;
+
+ % determine whether test should be skipped
+ % (careful about Octave bug #46397 to not change the current value of “ans”)
+ eval (strcat ('DOCTEST__current_test.skip = ', ...
+ doctest_join_conditions(DOCTEST__current_test.skip), ...
+ ';'));
+ if (DOCTEST__current_test.skip)
+ doctest_datastore('set_current_test', DOCTEST__current_test);
+ continue
+ end
+
+ % determine whether test is expected to fail
+ % (careful about Octave bug #46397 to not change the current value of “ans”)
+ eval (strcat ('DOCTEST__current_test.xfail = ', ...
+ doctest_join_conditions(DOCTEST__current_test.xfail), ...
+ ';'));
+ doctest_datastore('set_current_test', DOCTEST__current_test);
+
+ % run the test code
+ try
+ DOCTEST__got = evalc(DOCTEST__current_test.source);
+ catch DOCTEST__exception
+ DOCTEST__got = doctest_format_exception(DOCTEST__exception);
+ end
+
+ % at this point, we can only rely on the DOCTEST__got variable
+ % being available
+ DOCTEST__current_test = doctest_datastore('get_current_test');
+ DOCTEST__current_test.got = DOCTEST__got;
+
+ % determine if test has passed
+ DOCTEST__current_test.passed = doctest_compare(DOCTEST__current_test.want,
DOCTEST__current_test.got, DOCTEST__current_test.normalize_whitespace,
DOCTEST__current_test.ellipsis);
+ if DOCTEST__current_test.xfail
+ DOCTEST__current_test.passed = ~DOCTEST__current_test.passed;
+ end
+
+ doctest_datastore('set_current_test', DOCTEST__current_test);
+end
+
+% retrieve all tests from data store
+tests = doctest_datastore('get_tests');
+doctest_datastore('clear_and_munlock');
+
+% unwrap from cell-array, discarding skips
+%DOCTEST__results = cell2mat(tests); % fails b/c they have different fields
+DOCTEST__results = [];
+for j=1:numel(tests)
+ if ~any(tests{j}.skip)
+ DOCTEST__results = [DOCTEST__results tests{j}];
+ end
+end
+
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/inst/private/is_octave.m
new/doctest-0.6.1/inst/private/is_octave.m
--- old/doctest-0.5.0/inst/private/is_octave.m 2016-11-14 07:08:14.000000000
+0100
+++ new/doctest-0.6.1/inst/private/is_octave.m 2018-01-04 20:48:27.000000000
+0100
@@ -1,5 +1,10 @@
function r = is_octave()
-%IS_OCTAVE Return true if we are running Octave, false for Matlab.
+%IS_OCTAVE True if we are running Octave, false for Matlab.
+
+%%
+% Copyright (c) 2015 Colin B. Macdonald
+% This is Free Software, BSD-3-Clause, see doctest.m for details.
+
% Timings for different implementations, 10000 calls
%
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/src/Makefile
new/doctest-0.6.1/src/Makefile
--- old/doctest-0.5.0/src/Makefile 2016-11-14 07:08:14.000000000 +0100
+++ new/doctest-0.6.1/src/Makefile 1970-01-01 01:00:00.000000000 +0100
@@ -1,5 +0,0 @@
-all: doctest_evalc.oct
-
-%.oct: %.cc
- $(MKOCTFILE) $<
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/src/doctest_evalc.cc
new/doctest-0.6.1/src/doctest_evalc.cc
--- old/doctest-0.5.0/src/doctest_evalc.cc 2016-11-14 07:08:14.000000000
+0100
+++ new/doctest-0.6.1/src/doctest_evalc.cc 1970-01-01 01:00:00.000000000
+0100
@@ -1,87 +0,0 @@
-/*
- Copyright 2015 Oliver Heimlich
-
- This program 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.
-
- This program 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 this program; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <octave/oct.h>
-#include <octave/parse.h>
-
-DEFUN_DLD (doctest_evalc, args, nargout,
- "-*- texinfo -*-\n"
- "@documentencoding UTF-8\n"
- "@deftypefn {Loadable Function} {@var{S} =} doctest_evalc (@var{TRY})\n"
- "@deftypefnx {Loadable Function} {@var{S} =} doctest_evalc (@var{TRY},
@var{CATCH})\n"
- "\n"
- "Parse the string @var{TRY} and evaluate it as if it were an Octave "
- "program. If that fails, evaluate the optional string @var{CATCH}. The "
- "string @var{TRY} is evaluated in the current context, so any results "
- "remain available after @command{doctest_evalc} returns."
- "\n\n"
- "This function is like @command{eval}, except any output that would "
- "normally be written in the console is captured and returned as string "
- "@var{S}."
- "\n\n"
- "@example\n"
- "@group\n"
- "s = doctest_evalc (\"t = 42\"), t\n"
- " @result{}\n"
- " s = t = 42\n\n"
- " t = 42\n"
- "@end group\n"
- "@end example\n"
- "@seealso{eval, evalin}\n"
- "@end deftypefn"
- )
-{
- octave_value_list retval;
-
- int nargin = args.length ();
-
- if (nargin > 0)
- {
- // Redirect stdout to capturing buffer
- std::ostream & out_stream = octave_stdout;
- std::ostream & err_stream = std::cerr;
- out_stream.flush ();
- err_stream.flush ();
- std::ostringstream buffer;
- std::streambuf* old_out_buf = out_stream.rdbuf (buffer.rdbuf ());
- std::streambuf* old_err_buf = err_stream.rdbuf (buffer.rdbuf ());
-
- int parse_status = 0;
-
- octave_value_list tmp = eval_string (args(0).string_value (), false,
- parse_status, 0);
-
- if (nargin > 1 && (parse_status != 0 || error_state))
- {
- error_state = 0;
-
- tmp = eval_string (args(1).string_value (), false,
- parse_status, 0);
- }
-
- // Stop capturing buffer and restore stdout
- out_stream.flush ();
- err_stream.flush ();
- retval (0) = buffer.str ();
- out_stream.rdbuf (old_out_buf);
- err_stream.rdbuf (old_err_buf);
- }
- else
- print_usage ();
-
- return retval;
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/test/test_clear.m
new/doctest-0.6.1/test/test_clear.m
--- old/doctest-0.5.0/test/test_clear.m 1970-01-01 01:00:00.000000000 +0100
+++ new/doctest-0.6.1/test/test_clear.m 2018-01-04 20:48:27.000000000 +0100
@@ -0,0 +1,29 @@
+function test_clear()
+% Easy things first, clearing one variable
+% >> a = 6;
+% >> b = 7;
+% >> clear a
+% >> b
+% b = 7
+% >> a
+% ??? ...ndefined ...
+%
+%
+% Harder:
+% >> clear
+% >> a
+% ??? ...ndefined ...
+%
+%
+% >> a = 4
+% a = 4
+%
+%
+% "clear all" clears stuff inside persistent vars
+% >> clear all
+% >> a
+% ??? ...ndefined ...
+%
+%
+% >> a = 5
+% a = 5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/test/test_clear_all_first.m
new/doctest-0.6.1/test/test_clear_all_first.m
--- old/doctest-0.5.0/test/test_clear_all_first.m 1970-01-01
01:00:00.000000000 +0100
+++ new/doctest-0.6.1/test/test_clear_all_first.m 2018-01-04
20:48:27.000000000 +0100
@@ -0,0 +1,10 @@
+function test_clear_all_first()
+% If we "clear all" very early, our implementation may break if
+% subfunctions haven't yet been called. At least on Octave 4.2.1.
+% >> clear all
+% >> a
+% ??? ...ndefined ...
+%
+%
+% >> a = 6
+% a = 6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/test/test_clear_isoctave.m
new/doctest-0.6.1/test/test_clear_isoctave.m
--- old/doctest-0.5.0/test/test_clear_isoctave.m 1970-01-01
01:00:00.000000000 +0100
+++ new/doctest-0.6.1/test/test_clear_isoctave.m 2018-01-04
20:48:27.000000000 +0100
@@ -0,0 +1,19 @@
+function test_clear_isoctave()
+% Easy things first, clearing one variable
+% >> a = 6
+% a = 6
+%
+%
+% >> clear
+% >> a
+% ??? ...ndefined ...
+%
+%
+% >> clear all
+% >> a
+% ??? ...ndefined ...
+%
+%
+% Make sure these macros are still available after a clear
+% >> a = 42 % doctest: +XFAIL_IF(DOCTEST_OCTAVE | DOCTEST_MATLAB)
+% a = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/test/test_multi_return.texinfo
new/doctest-0.6.1/test/test_multi_return.texinfo
--- old/doctest-0.5.0/test/test_multi_return.texinfo 2016-11-14
07:08:14.000000000 +0100
+++ new/doctest-0.6.1/test/test_multi_return.texinfo 2018-01-04
20:48:27.000000000 +0100
@@ -23,9 +23,11 @@
Here the warning is not part of the result:
@example
-inv (0)
+inv ([1 2; 2 4])
@print{} warning: ...matrix singular to machine precision...
-@result{} ans = Inf
+@result{} ans =
+ Inf Inf
+ Inf Inf
@end example
Here we have two results:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/doctest-0.5.0/util/convert_comments.m
new/doctest-0.6.1/util/convert_comments.m
--- old/doctest-0.5.0/util/convert_comments.m 2016-11-14 07:08:14.000000000
+0100
+++ new/doctest-0.6.1/util/convert_comments.m 1970-01-01 01:00:00.000000000
+0100
@@ -1,314 +0,0 @@
-%% Copyright (c) 2015 Colin B. Macdonald
-%%
-%% Redistribution and use in source and binary forms, with or without
-%% modification, are permitted provided that the following conditions are met:
-%%
-%% 1. Redistributions of source code must retain the above copyright notice,
-%% this list of conditions and the following disclaimer.
-%%
-%% 2. Redistributions in binary form must reproduce the above copyright notice,
-%% this list of conditions and the following disclaimer in the documentation
-%% and/or other materials provided with the distribution.
-%%
-%% 3. Neither the name of the copyright holder nor the names of its
-%% contributors may be used to endorse or promote products derived from this
-%% software without specific prior written permission.
-%%
-%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-%% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-%% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-%% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-%% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-%% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-%% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-%% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-%% POSSIBILITY OF SUCH DAMAGE.
-
-function convert_comments (basedir, subdir, dirout)
-% this slightly strange way of doing things (basedir, subdir) is
-% b/c I must "chdir" into base, but get_first_help_sentence() must
-% not be in the class dir...
-
- %basedir, subdir, dirout
- files = dir([basedir subdir]);
- chdir(basedir)
-
- for i=1:length(files)
- if (~files(i).isdir)
- [dir, name, ext] = fileparts(files(i).name);
- if (strcmp(ext, '.m'))
- if isempty(subdir)
- octname = [name ext];
- else
- octname = [subdir '/' name ext];
- end
- fprintf('Converting texinfo to Matlab-style documentation: %s\n',
octname)
- r = convert_oct_2_ml (octname, [dirout octname]);
- if ~r
- [status, msg, msgid] = copyfile (octname, [dirout octname], 'f');
- if (status ~= 1)
- error(msg)
- end
- fprintf('**** COPYING %s UNMODIFIED ****\n', octname)
- end
- end
- end
- end
-end
-
-
-
-
-function success = convert_oct_2_ml (fname, foutname)
-
- [dir, fcn, ext] = fileparts(fname);
-
- newl = sprintf('\n');
-
- [fi,msg] = fopen(fname, 'r');
- if (fi < 0)
- error(msg)
- end
-
- ins = {}; i = 0;
- while (1)
- temp = fgets(fi);
- if ~ischar(temp) && temp == -1
- break
- end
- i = i + 1;
- ins{i} = temp;
- % todo, possible strip newl
- end
-
- fclose(fi);
-
- % trim newlines
- ins = deblank(ins);
-
-
- %% find the actual function [] = ... line
- Nfcn = [];
- for i = 1:length(ins)
- I = strfind (ins{i}, 'function');
- if ~isempty(I) && I(1) == 1
- %disp ('found function header')
- Nfcn = i;
- break
- end
- end
- if isempty(Nfcn)
- disp('AFAICT, this is a script, not a function')
- success = false;
- return
- end
-
-
- %% copyright block
- [cr,N] = findblock(ins, 1);
- if (Nfcn < N)
- warning('function header in first block (where copyright block should be),
not converting')
- success = false;
- return
- end
- cr = ltrim(cr, 3);
-
- % cut 2nd line if empty
- if isempty(cr{2})
- cr2 = cell(1,length(cr)-1);
- cr2(1) = cr(1);
- cr2(2:end) = cr(3:end);
- cr = cr2;
- end
-
- cr = prepend_each_line(cr, '%', ' ');
- cr{1} = ['%' cr{1}];
- copyright_summary = 'This is free software, see .m file for license.';
-
-
- %% use block
- % we don't parse this, just call get_help_text
- temp = ins{N};
- if ~strcmp(temp, '%% -*- texinfo -*-')
- error('can''t find the texinfo line, aborting')
- %success = false;
- %return
- end
-
- %% the "lookfor" line
- lookforstr = get_first_help_sentence (fname);
- if (~isempty(strfind(lookforstr, newl)))
- lookforstr
- error('lookfor string contains newline: missing period? too long? some
other issue?')
- %success = false;
- %return
- end
- if (length(lookforstr) > 76)
- error(sprintf('lookfor string of length %d deemed too long',
length(lookforstr)))
- end
-
-
- %% get the texinfo source, and format it
- [text, form] = get_help_text(fname);
- if ~strcmp(form, 'texinfo')
- text
- form
- error('formatted incorrectly, help text not texinfo')
- end
-
- % Doctest diary-mode compatibility: force two blank lines after example.
- % Final "\n\n" is incase text immediately follows "@end example".
- text = regexprep(text, '(^\s*)(@end example\n)', '$1$2 @*\n\n',
- 'lineanchors');
-
- usestr = __makeinfo__(text, 'plain text');
-
-
- %% remove the lookforstr from the text
- I = strfind(usestr, lookforstr);
- if length(I) ~= 1
- I
- lookforstr
- usestr
- error('too many lookfor lines?')
- end
- len = length(lookforstr);
- J = I + len;
-
- % if usestr has only a lookfor line then no need to see what's next
- if (J < length(usestr))
- % find next non-empty char
- %while isspace(usestr(J))
- % J = J + 1;
- %end
-
- % let's be more conservative trim newline in usual case:
- if ~isspace(usestr(J))
- error('no space or newline after lookfor line?');
- end
- J = J + 1;
- end
-
- usestr = usestr([1:(I-1) J:end]);
-
- use = strsplit(usestr, newl, 'CollapseDelimiters', false);
-
- %% remove this string
- % and make sure these lines have the correct function name
- remstr = '-- Function File: ';
- for i=1:length(use)
- if strfind(use{i}, remstr);
- if isempty(strfind(use{i}, [' ' fcn]))
- error('function @deftypefn line doesn''t include function name')
- end
- end
- use{i} = strrep(use{i}, remstr, ' ');
- end
- %usestr = strrep(usestr, lookforstr, '');
-
- use = ltrim(use, 2);
- while isempty(use{end})
- use = use(1:end-1);
- end
-
-
- %% the rest
- N = Nfcn;
- fcn_line = ins{N};
-
- % sanity checks
- I = strfind(ins{N+1}, '%');
- if ~isempty(I) && I(1) == 1
- ins{N}
- ins{N+1}
- error('possible duplicate comment header following function')
- end
-
- therest = ins(N+1:end);
-
-
-
- %% Output
- f = fopen(foutname, 'w');
-
- fdisp(f, fcn_line)
-
- fprintf(f, '%%%s %s\n', upper(fcn), lookforstr)
-
- for i=1:length(use)
- fprintf(f, '%%%s\n', use{i});
- end
-
- fdisp(f, '%');
- fprintf(f, '%% %s\n', copyright_summary);
-
- %fdisp(f, '%');
- %fdisp(f, '% [Genereated from a GNU Octave .m file, edit that instead.]');
-
- %fprintf(f,(s)
-
- fdisp(f, '');
- fdisp(f, '%% Note for developers');
- fdisp(f, '% This file is autogenerated from a GNU Octave .m file.');
- fdisp(f, '% If you want to edit, please make changes to the original
instead');
-
- fdisp(f, '');
- for i=1:length(cr)
- fprintf(f, '%s\n', cr{i});
- end
-
- fdisp(f, '');
-
- for i=1:length(therest)
- fprintf(f, '%s\n', therest{i});
- end
-
- fclose(f);
-
- success = true;
-
-end
-
-
-function [block,endl] = findblock(f, j)
- block = {}; c = 0;
- %newl = sprintf('\n');
- for i = j:length(f)
- temp = f{i};
- %if (strcmp(temp, newl))
- if (isempty(temp))
- endl = i + 1;
- break
- end
- c = c + 1;
- block{c} = temp;
- end
-end
-
-
-function g = ltrim(f, n)
- g = {};
- for i = 1:length(f)
- temp = f{i};
- if length(temp) < n
- g{i} = '';
- else
- g{i} = substr(temp, n+1);
- end
- end
-end
-
-
-function g = prepend_each_line(f, pre, pad)
- g = {};
- for i = 1:length(f)
- temp = f{i};
- if isempty(temp)
- g{i} = pre;
- else
- g{i} = [pre pad temp];
- end
- end
-end