diff --git a/CHANGELOG.md b/CHANGELOG.md index 189b0db501..933dd27fe8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ Features: --------- + * [#173](http://github.com/Nelson-numerical-software/nelson/issues/173): convertStringsToChars builtin. + Bug Fixes: diff --git a/modules/string/builtin/c/nlsString_builtin.vcxproj b/modules/string/builtin/c/nlsString_builtin.vcxproj index 94c99dd3bc..77de3f1109 100644 --- a/modules/string/builtin/c/nlsString_builtin.vcxproj +++ b/modules/string/builtin/c/nlsString_builtin.vcxproj @@ -170,6 +170,7 @@ + @@ -224,6 +225,7 @@ + diff --git a/modules/string/builtin/c/nlsString_builtin.vcxproj.filters b/modules/string/builtin/c/nlsString_builtin.vcxproj.filters index 8beb2650c6..d39c972ae5 100644 --- a/modules/string/builtin/c/nlsString_builtin.vcxproj.filters +++ b/modules/string/builtin/c/nlsString_builtin.vcxproj.filters @@ -84,6 +84,9 @@ Source Files + + Source Files + @@ -155,6 +158,9 @@ Header Files + + Header Files + diff --git a/modules/string/builtin/cpp/Gateway.cpp b/modules/string/builtin/cpp/Gateway.cpp index 32f4e71613..8db6c7f173 100644 --- a/modules/string/builtin/cpp/Gateway.cpp +++ b/modules/string/builtin/cpp/Gateway.cpp @@ -38,6 +38,7 @@ #include "stringBuiltin.hpp" #include "stringsBuiltin.hpp" #include "deblankBuiltin.hpp" +#include "convertStringsToCharsBuiltin.hpp" //============================================================================= using namespace Nelson; //============================================================================= @@ -68,7 +69,10 @@ static const nlsGateway gateway[] = { { "char", Nelson::StringGateway::charBuilt { "deblank", Nelson::StringGateway::deblankBuiltin, 1, 1, CPP_BUILTIN_WITH_EVALUATOR }, { "strlength", Nelson::StringGateway::strlengthBuiltin, 1, 1, CPP_BUILTIN_WITH_EVALUATOR }, { "string", Nelson::StringGateway::stringBuiltin, 1, 1, CPP_BUILTIN_WITH_EVALUATOR }, - { "strings", Nelson::StringGateway::stringsBuiltin, 1, -1, CPP_BUILTIN_WITH_EVALUATOR } }; + { "strings", Nelson::StringGateway::stringsBuiltin, 1, -1, CPP_BUILTIN_WITH_EVALUATOR }, + { "convertStringsToChars", Nelson::StringGateway::convertStringsToCharsBuiltin, -1, -1, + CPP_BUILTIN_WITH_EVALUATOR }, +}; //============================================================================= NLSGATEWAYFUNC(gateway) //============================================================================= diff --git a/modules/string/builtin/cpp/convertStringsToCharsBuiltin.cpp b/modules/string/builtin/cpp/convertStringsToCharsBuiltin.cpp new file mode 100644 index 0000000000..d4be40e9c3 --- /dev/null +++ b/modules/string/builtin/cpp/convertStringsToCharsBuiltin.cpp @@ -0,0 +1,34 @@ +//============================================================================= +// Copyright (c) 2016-2019 Allan CORNET (Nelson) +//============================================================================= +// LICENCE_BLOCK_BEGIN +// 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 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 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 . +// LICENCE_BLOCK_END +//============================================================================= +#include "ConvertStringsToChars.hpp" +#include "Error.hpp" +#include "convertStringsToCharsBuiltin.hpp" +//============================================================================= +using namespace Nelson; +//============================================================================= +ArrayOfVector +Nelson::StringGateway::convertStringsToCharsBuiltin( + Evaluator* eval, int nLhs, const ArrayOfVector& argIn) +{ + if (nLhs > argIn.size()) { + Error(_W("Number of Input arguments must the same as output.")); + } + return ConvertStringsToChars(argIn); +} +//============================================================================= \ No newline at end of file diff --git a/modules/string/builtin/include/convertStringsToCharsBuiltin.hpp b/modules/string/builtin/include/convertStringsToCharsBuiltin.hpp new file mode 100644 index 0000000000..7e1d479cb0 --- /dev/null +++ b/modules/string/builtin/include/convertStringsToCharsBuiltin.hpp @@ -0,0 +1,32 @@ +//============================================================================= +// Copyright (c) 2016-2019 Allan CORNET (Nelson) +//============================================================================= +// LICENCE_BLOCK_BEGIN +// 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 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 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 . +// LICENCE_BLOCK_END +//============================================================================= +#pragma once +//============================================================================= +#include "ArrayOf.hpp" +#include "Evaluator.hpp" +//============================================================================= +namespace Nelson { +//============================================================================= + namespace StringGateway { + ArrayOfVector + convertStringsToCharsBuiltin(Evaluator* eval, int nLhs, const ArrayOfVector& argIn); +} +//============================================================================= +} // namespace Nelson +//============================================================================= diff --git a/modules/string/help/en_US/xml/convertStringsToChars.xml b/modules/string/help/en_US/xml/convertStringsToChars.xml new file mode 100644 index 0000000000..3456d4c805 --- /dev/null +++ b/modules/string/help/en_US/xml/convertStringsToChars.xml @@ -0,0 +1,84 @@ + + + SAME AS NELSON SOFTWARE + + en_US + convertStringsToChars + Convert string arrays to character arrays. + + + C = convertStringsToChars(S) + [B1, B2, ..., BN] = convertStringsToChars(A1, A2, ..., AN) + + + + + S + if S is a string array, output C will be converted to an cell of strings or an character vector (if S is scalar). + + + A1, A2, ..., AN + variables to convert to char array if it is a string array. + + + + + + + C + a string array or unaltered variable + + + B1, B2, ..., BN + variables converted to char array if it is a string array. + + + + + +

convertStringsToChars converts string arrays to character arrays.

+
+ + + + + + + + + nelson + + + + + + + + + + + cellstr + + + string + + + char + + + + + + + 1.0.0 + initial version + + + + + Allan CORNET + +
+ + diff --git a/modules/string/src/c/nlsString.vcxproj b/modules/string/src/c/nlsString.vcxproj index 7a26f0e2a4..598be8aeb7 100644 --- a/modules/string/src/c/nlsString.vcxproj +++ b/modules/string/src/c/nlsString.vcxproj @@ -164,6 +164,7 @@ + @@ -187,6 +188,7 @@ + diff --git a/modules/string/src/c/nlsString.vcxproj.filters b/modules/string/src/c/nlsString.vcxproj.filters index 67eeb56c1e..7c36987ee0 100644 --- a/modules/string/src/c/nlsString.vcxproj.filters +++ b/modules/string/src/c/nlsString.vcxproj.filters @@ -72,6 +72,9 @@ Source Files + + Source Files + @@ -134,6 +137,9 @@ Header Files + + Header Files + diff --git a/modules/string/src/cpp/ConvertStringsToChars.cpp b/modules/string/src/cpp/ConvertStringsToChars.cpp new file mode 100644 index 0000000000..753d5d655f --- /dev/null +++ b/modules/string/src/cpp/ConvertStringsToChars.cpp @@ -0,0 +1,63 @@ +//============================================================================= +// Copyright (c) 2016-2019 Allan CORNET (Nelson) +//============================================================================= +// LICENCE_BLOCK_BEGIN +// 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 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 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 . +// LICENCE_BLOCK_END +//============================================================================= +#include "ConvertStringsToChars.hpp" +#include "Exception.hpp" +//============================================================================= +namespace Nelson { +ArrayOfVector +ConvertStringsToChars(const ArrayOfVector& A) +{ + ArrayOfVector res; + for (auto value : A) { + if (value.isStringArray()) { + Dimensions dims = value.getDimensions(); + if (dims.isEmpty(false)) { + ArrayOf valueAsCell = ArrayOf(NLS_CELL_ARRAY, dims, nullptr); + res.push_back(valueAsCell); + } else if (dims.isScalar()) { + auto* elementsStr = (ArrayOf*)value.getDataPointer(); + ArrayOf element = elementsStr[0]; + if (element.getDataClass() == NLS_CHAR) { + res.push_back( + ArrayOf::characterArrayConstructor(element.getContentAsWideString())); + } else { + res.push_back(ArrayOf::characterArrayConstructor("")); + } + } else { + auto* elementsCell = new_with_exception(dims.getElementCount(), false); + ArrayOf valueAsCell = ArrayOf(NLS_CELL_ARRAY, dims, elementsCell); + auto* elementsStr = (ArrayOf*)value.getDataPointer(); + for (indexType q = 0; q < dims.getElementCount(); q++) { + if (elementsStr[q].getDataClass() == NLS_CHAR) { + elementsCell[q] = elementsStr[q]; + } else { + elementsCell[q] = ArrayOf::characterArrayConstructor(""); + } + } + res.push_back(valueAsCell); + } + } else { + res.push_back(value); + } + } + return res; +} +//============================================================================= +} // namespace Nelson +//============================================================================= diff --git a/modules/string/src/cpp/StringCompare.cpp b/modules/string/src/cpp/StringCompare.cpp index d7c2546fda..f7d2003de2 100644 --- a/modules/string/src/cpp/StringCompare.cpp +++ b/modules/string/src/cpp/StringCompare.cpp @@ -43,7 +43,7 @@ compareString(std::wstring A, std::wstring B, bool bCaseSensitive, indexType len return compareString(strA, strB, false); } if (bCaseSensitive) { - bEq = (A.compare(B) == 0); + bEq = (A == B); } else { bEq = boost::iequals(A, B); } @@ -99,8 +99,8 @@ StringCompare(ArrayOf A, ArrayOf B, bool bCaseSensitive, indexType len) ArrayOf elementA = cellA[k]; ArrayOf elementB = cellB[k]; if (elementA.isRowVectorCharacterArray() && elementB.isRowVectorCharacterArray()) { - Cp[k] = compareString(elementA.getContentAsWideString(), - elementB.getContentAsWideString(), bCaseSensitive, len); + Cp[k] = static_cast(compareString(elementA.getContentAsWideString(), + elementB.getContentAsWideString(), bCaseSensitive, len)); } else if (elementA.isCharacterArray() && elementB.isCharacterArray()) { wstringVector s1 = elementA.getContentAsWideStringVector(); wstringVector s2 = elementB.getContentAsWideStringVector(); @@ -201,8 +201,8 @@ StringCompare(ArrayOf A, ArrayOf B, bool bCaseSensitive, indexType len) } else { ArrayOf elementA = cellA[k]; if (elementA.isCharacterArray() && scalar2.isCharacterArray()) { - Cp[k] = compareString(elementA.getContentAsWideString(), - scalar2.getContentAsWideString(), bCaseSensitive, len); + Cp[k] = static_cast(compareString(elementA.getContentAsWideString(), + scalar2.getContentAsWideString(), bCaseSensitive, len)); } else { Cp[k] = false; } diff --git a/modules/string/src/cpp/StringContains.cpp b/modules/string/src/cpp/StringContains.cpp index 7f207dd5d3..565f15e784 100644 --- a/modules/string/src/cpp/StringContains.cpp +++ b/modules/string/src/cpp/StringContains.cpp @@ -68,7 +68,7 @@ StringContains(ArrayOf A, ArrayOf Pattern, bool bCaseSensitive) auto* cellA = (ArrayOf*)(A.getDataPointer()); for (size_t k = 0; k < nbA; k++) { result[k] - = containsString(cellA[k].getContentAsWideString(), pattern, bCaseSensitive); + = static_cast(containsString(cellA[k].getContentAsWideString(), pattern, bCaseSensitive)); } res = ArrayOf(NLS_LOGICAL, dimA, result); } else if ((A.isStringArray() || IsCellOfString(A)) @@ -85,7 +85,7 @@ StringContains(ArrayOf A, ArrayOf Pattern, bool bCaseSensitive) bool val = containsString(cellA[k].getContentAsWideString(), cellPattern[l].getContentAsWideString(), bCaseSensitive); if (val) { - result[k] = val; + result[k] = static_cast(val); break; } } diff --git a/modules/string/src/cpp/StringEndsWith.cpp b/modules/string/src/cpp/StringEndsWith.cpp index 1a137a207f..429e0302ac 100644 --- a/modules/string/src/cpp/StringEndsWith.cpp +++ b/modules/string/src/cpp/StringEndsWith.cpp @@ -69,7 +69,7 @@ StringEndsWith(ArrayOf A, ArrayOf Pattern, bool bCaseSensitive) auto* cellA = (ArrayOf*)(A.getDataPointer()); for (size_t k = 0; k < nbA; k++) { result[k] - = endsWithString(cellA[k].getContentAsWideString(), pattern, bCaseSensitive); + = static_cast(endsWithString(cellA[k].getContentAsWideString(), pattern, bCaseSensitive)); } res = ArrayOf(NLS_LOGICAL, dimA, result); } else if ((A.isStringArray() || IsCellOfString(A)) @@ -86,7 +86,7 @@ StringEndsWith(ArrayOf A, ArrayOf Pattern, bool bCaseSensitive) bool val = endsWithString(cellA[k].getContentAsWideString(), cellPattern[l].getContentAsWideString(), bCaseSensitive); if (val) { - result[k] = val; + result[k] = static_cast(val); break; } } diff --git a/modules/string/src/cpp/StringStartsWith.cpp b/modules/string/src/cpp/StringStartsWith.cpp index c099aaf5fc..8364c8177a 100644 --- a/modules/string/src/cpp/StringStartsWith.cpp +++ b/modules/string/src/cpp/StringStartsWith.cpp @@ -69,7 +69,7 @@ StringStartsWith(ArrayOf A, ArrayOf Pattern, bool bCaseSensitive) auto* cellA = (ArrayOf*)(A.getDataPointer()); for (size_t k = 0; k < nbA; k++) { result[k] - = startsWithString(cellA[k].getContentAsWideString(), pattern, bCaseSensitive); + = static_cast(startsWithString(cellA[k].getContentAsWideString(), pattern, bCaseSensitive)); } res = ArrayOf(NLS_LOGICAL, dimA, result); } else if ((A.isStringArray() || IsCellOfString(A)) @@ -86,7 +86,7 @@ StringStartsWith(ArrayOf A, ArrayOf Pattern, bool bCaseSensitive) bool val = startsWithString(cellA[k].getContentAsWideString(), cellPattern[l].getContentAsWideString(), bCaseSensitive); if (val) { - result[k] = val; + result[k] = static_cast(val); break; } } diff --git a/modules/string/src/cpp/StringToDouble.cpp b/modules/string/src/cpp/StringToDouble.cpp index a2dc16a16c..4d145914c1 100644 --- a/modules/string/src/cpp/StringToDouble.cpp +++ b/modules/string/src/cpp/StringToDouble.cpp @@ -57,15 +57,15 @@ stringToDouble(const std::wstring& str, bool& wasConverted) wasConverted = true; } else { std::wstring STR = ToUpper(str); - if (STR.compare(ToUpper(NanString)) == 0 || STR.compare(ToUpper(NegNanString)) == 0 - || STR.compare(ToUpper(PosNanString)) == 0) { + if (STR == ToUpper(NanString) || STR == ToUpper(NegNanString) + || STR == ToUpper(PosNanString)) { res = nan(""); wasConverted = true; - } else if (STR.compare(ToUpper(NegInfString)) == 0) { + } else if (STR == ToUpper(NegInfString)) { res = returnInfinity(false); wasConverted = true; - } else if (STR.compare(ToUpper(InfString)) == 0 - || STR.compare(ToUpper(PosInfString)) == 0) { + } else if (STR == ToUpper(InfString) + || STR == ToUpper(PosInfString)) { res = returnInfinity(true); wasConverted = true; } else { diff --git a/modules/string/src/include/ConvertStringsToChars.hpp b/modules/string/src/include/ConvertStringsToChars.hpp new file mode 100644 index 0000000000..a9f4d61cca --- /dev/null +++ b/modules/string/src/include/ConvertStringsToChars.hpp @@ -0,0 +1,30 @@ +//============================================================================= +// Copyright (c) 2016-2019 Allan CORNET (Nelson) +//============================================================================= +// LICENCE_BLOCK_BEGIN +// 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 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 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 . +// LICENCE_BLOCK_END +//============================================================================= +#pragma once +//============================================================================= +#include "ArrayOf.hpp" +#include "nlsString_exports.h" +//============================================================================= +namespace Nelson { +//============================================================================= +NLSSTRING_IMPEXP ArrayOfVector +ConvertStringsToChars(const ArrayOfVector &A); +//============================================================================= +} +//============================================================================= diff --git a/modules/string/tests/test_convertStringsToChars.nls b/modules/string/tests/test_convertStringsToChars.nls new file mode 100644 index 0000000000..e494d6d9f7 --- /dev/null +++ b/modules/string/tests/test_convertStringsToChars.nls @@ -0,0 +1,42 @@ +//============================================================================= +// Copyright (c) 2016-2019 Allan CORNET (Nelson) +//============================================================================= +// LICENCE_BLOCK_BEGIN +// 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 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 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 . +// LICENCE_BLOCK_END +//============================================================================= +assert_isequal(nargin('convertStringsToChars'), -1); +assert_isequal(nargout('convertStringsToChars'), -1); +//============================================================================= +[A, B, C, D] = convertStringsToChars('one', 2, "three", ["four" ; "five"]); +assert_isequal(A, 'one'); +assert_isequal(B, 2); +assert_isequal(C, 'three'); +assert_isequal(D, {'four'; 'five'}); +//============================================================================= +[A, B, C, D] = convertStringsToChars('one', 2, "three", ["four" ; string(NaN) ; "five"]); +assert_isequal(A, 'one'); +assert_isequal(B, 2); +assert_isequal(C, 'three'); +assert_isequal(D, {'four'; ''; 'five'}); +//============================================================================= +[A, B, C, D] = convertStringsToChars('one', 2, string(NaN), ["four" ; string(NaN) ; "five"]); +assert_isequal(A, 'one'); +assert_isequal(B, 2); +assert_isequal(C, ''); +assert_isequal(D, {'four'; ''; 'five'}); +//============================================================================= +R = convertStringsToChars(string([])); +assert_isequal(R, {}); +//=============================================================================