Skip to content

Commit

Permalink
fix #352 number of input arguments checked in macro
Browse files Browse the repository at this point in the history
  • Loading branch information
Nelson-numerical-software committed Mar 25, 2021
1 parent 50926a3 commit 9502cd1
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 14 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
@@ -1,3 +1,9 @@
# 0.5.4 (UNRELEASED)

## Features:

- [#352](http://github.com/Nelson-numerical-software/nelson/issues/352): number of input arguments checked in macro.

# 0.5.3 (2021-03-24)

## Features:
Expand All @@ -18,7 +24,7 @@

- for loop faster > x2.

- assignment does not copy matrix.
- assignment does not copy matrix.

- reworks ArrayOfVector (internal).

Expand Down
2 changes: 1 addition & 1 deletion modules/elementary_functions/functions/magic.nlf
Expand Up @@ -24,7 +24,7 @@
// LICENCE_BLOCK_END
//=============================================================================
function M = magic(N)
if (nargin ~= 1)
if (nargin < 1)
error(_('Wrong number of input arguments.'));
end
if (nargout > 1)
Expand Down
34 changes: 22 additions & 12 deletions modules/interpreter/src/cpp/MacroFunctionDef.cpp
Expand Up @@ -170,22 +170,29 @@ MacroFunctionDef::evaluateFunction(Evaluator* eval, const ArrayOfVector& inputs,
// argument function, then use the following logic:
minCount = 0;
if (inputArgCount() != -1) {
if (inputs.size() > arguments.size()) {
context->popScope();
eval->callstack.popDebug();
Error(ERROR_WRONG_NUMBERS_INPUT_ARGS);
}
minCount = (inputs.size() < arguments.size()) ? inputs.size() : arguments.size();
for (size_t i = 0; i < minCount; i++) {
std::string arg(arguments[i]);
if (arg[0] == '&') {
arg.erase(0, 1);
}
context->insertVariableLocally(arg, inputs[i]);
}
// context->insertVariableLocally("nargin",
// ArrayOf::doubleConstructor((double)minCount));
context->getCurrentScope()->setNargIn(static_cast<int>(minCount));
} else {
// Count the number of supplied arguments
size_t inputCount = inputs.size();
// context->insertVariableLocally("nargin",
// ArrayOf::doubleConstructor((double)inputCount));
size_t nbArgumentsWithoutVarArgIn = arguments.size();
if (arguments[arguments.size() - 1] == "varargin") {
nbArgumentsWithoutVarArgIn = nbArgumentsWithoutVarArgIn - 1;
}
if (inputCount < nbArgumentsWithoutVarArgIn) {
context->popScope();
eval->callstack.popDebug();
Error(ERROR_WRONG_NUMBERS_INPUT_ARGS);
}
context->getCurrentScope()->setNargIn(static_cast<int>(inputCount));
// Get the number of explicit arguments
int explicitCount = static_cast<int>(arguments.size()) - 1;
Expand All @@ -197,9 +204,6 @@ MacroFunctionDef::evaluateFunction(Evaluator* eval, const ArrayOfVector& inputs,
size_t i;
for (i = 0; i < minCount; i++) {
std::string arg(arguments[i]);
if (arg[0] == '&') {
arg.erase(0, 1);
}
context->insertVariableLocally(arg, inputs[i]);
}
inputCount -= minCount;
Expand All @@ -212,8 +216,6 @@ MacroFunctionDef::evaluateFunction(Evaluator* eval, const ArrayOfVector& inputs,
}
context->insertVariableLocally("varargin", varg);
}
// context->insertVariableLocally("nargout",
// ArrayOf::doubleConstructor(nargout));
context->getCurrentScope()->setNargOut(nargout);
uint64 tic = 0;
try {
Expand Down Expand Up @@ -251,6 +253,8 @@ MacroFunctionDef::evaluateFunction(Evaluator* eval, const ArrayOfVector& inputs,
bool haveVarargout = context->lookupVariableLocally("varargout", varargout);
if (haveVarargout) {
if (varargout.getDataClass() != NLS_CELL_ARRAY) {
context->popScope();
eval->callstack.popDebug();
Error(_W("The special variable 'varargout' was not defined as a "
"cell-array."));
}
Expand All @@ -259,6 +263,8 @@ MacroFunctionDef::evaluateFunction(Evaluator* eval, const ArrayOfVector& inputs,
int explicitCount = static_cast<int>(returnVals.size()) - 1;
bool noArgs = (explicitCount == 0 && varlen == 0);
if (!noArgs && !haveVarargout) {
context->popScope();
eval->callstack.popDebug();
Error(_W("The special variable 'varargout' was not defined as expected."));
}
if (explicitCount == 0 && varlen > 0 && nargout < 2) {
Expand All @@ -268,6 +274,8 @@ MacroFunctionDef::evaluateFunction(Evaluator* eval, const ArrayOfVector& inputs,
// Get the length
if (static_cast<indexType>(toFill)
> static_cast<indexType>(varargout.getElementCount())) {
context->popScope();
eval->callstack.popDebug();
Error(_W("Not enough outputs in varargout to satisfy call."));
}
outputs[0] = dp[0];
Expand All @@ -292,6 +300,8 @@ MacroFunctionDef::evaluateFunction(Evaluator* eval, const ArrayOfVector& inputs,
// Get the length
int toFill = nargout - explicitCount;
if (static_cast<double>(toFill) > static_cast<double>(varlen)) {
context->popScope();
eval->callstack.popDebug();
Error(_W("Not enough outputs in varargout to satisfy call."));
}
for (int i = 0; i < toFill; i++) {
Expand Down
32 changes: 32 additions & 0 deletions modules/interpreter/tests/bug_github_issue_#352.nls
@@ -0,0 +1,32 @@
//=============================================================================
// Copyright (c) 2017 Allan CORNET (Nelson)
//=============================================================================
// This file is part of the Nelson.
//=============================================================================
// LICENCE_BLOCK_BEGIN
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// Alternatively, 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 2 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program. If not, see <http://www.gnu.org/licenses/>.
// LICENCE_BLOCK_END
//=============================================================================
// <-- Issue URL -->
// https://github.com/Nelson-numerical-software/nelson/issues/352
// <-- Short Description -->
// add nb input check on macros
//=============================================================================
assert_checkerror('magic(1, 1)', _('Wrong number of input arguments.'));
//=============================================================================

0 comments on commit 9502cd1

Please sign in to comment.