1% STK_ERROR throws an STK error with a good-looking error identifier.
2
3% Copyright Notice
4%
5%    Copyright (C) 2017 CentraleSupelec
6%    Copyright (C) 2012 SUPELEC
7%
8%    Authors:   Julien Bect        <julien.bect@centralesupelec.fr>
9%               Emmanuel Vazquez   <emmanuel.vazquez@centralesupelec.fr>
10
11% Copying Permission Statement
12%
13%    This file is part of
14%
15%            STK: a Small (Matlab/Octave) Toolbox for Kriging
16%               (http://sourceforge.net/projects/kriging)
17%
18%    STK is free software: you can redistribute it and/or modify it under
19%    the terms of the GNU General Public License as published by the Free
20%    Software Foundation,  either version 3  of the License, or  (at your
21%    option) any later version.
22%
23%    STK is distributed  in the hope that it will  be useful, but WITHOUT
24%    ANY WARRANTY;  without even the implied  warranty of MERCHANTABILITY
25%    or FITNESS  FOR A  PARTICULAR PURPOSE.  See  the GNU  General Public
26%    License for more details.
27%
28%    You should  have received a copy  of the GNU  General Public License
29%    along with STK.  If not, see <http://www.gnu.org/licenses/>.
30
31function stk_error (errmsg, mnemonic, stack)
32
33% Second component of error identifier = name of calling function
34% (unless stk_error has been called directly from the base workspace)
35if nargin < 3,
36
37    try
38        stack = dbstack ('-completenames');
39        % In Octave, -completenames is at best ignored (in recent versions)
40        % or generates an error (in, e.g., Octave 3.6.2).
41    catch
42        stack = dbstack ();
43    end
44
45    if length (stack) == 1,
46        caller = 'BaseWorkspace';
47    else
48        % pretend that the error has been thrown by the caller
49        stack = stack(2:end);
50        % and get caller name to form the error identifier
51        caller = stack(1).name;
52    end
53else
54    % If a "stack" has been provided by the user, we use it without asking
55    % questions (if it's a struct)
56    if ~ isstruct (stack) || ~ isfield (stack, 'name'),
57        % We will throw an error, but not the one we were requested to!
58        errmsg = 'Argument "stack" should be a valid stack structure.';
59        mnemonic = 'InvalidArgument';
60        stack = dbstack ();
61    end
62    caller = stack(1).name;
63end
64
65% Keep only subfunction name (Octave)
66gt_pos = strfind (caller, '>');
67if ~ isempty (gt_pos),
68    caller = caller((gt_pos + 1):end);
69end
70
71% Construct the error structure
72errstruct = struct (...
73    'message', errmsg, ...
74    'identifier', sprintf ('STK:%s:%s', caller, mnemonic), ...
75    'stack', stack);
76
77% Note: the 'stack' argument is ignore in Octave 4.0.0 and earlier
78%       releases (see https://savannah.gnu.org/bugs/?47107)
79
80error (errstruct);
81
82end % function
83
84
85%!shared errmsg, mnemonic, badstack
86%!  errmsg = 'Go ahead, make my day.';
87%!  mnemonic = 'ClintEastwood';
88%!  badstack = 0; % not a valid stack structure
89
90% Valid use of stk_error
91%!error <make my day> stk_error(errmsg, mnemonic);
92
93% Use of an incorrect stack structure
94%!error <stack structure> stk_error (errmsg, mnemonic, badstack);
95%!error id=STK:stk_error:InvalidArgument stk_error (errmsg, mnemonic, badstack);
96