progid is the programmatic identifier of the Automation server object and h is the handle to the default interface of the server object.
diff --git a/modules/core/src/cpp/Banner.cpp b/modules/core/src/cpp/Banner.cpp
index 2d4484a441..9c6621dcbc 100644
--- a/modules/core/src/cpp/Banner.cpp
+++ b/modules/core/src/cpp/Banner.cpp
@@ -15,11 +15,11 @@ void
Banner()
{
NelsonPrint(L"\n");
- NelsonPrint(L" __ _ __\n");
- NelsonPrint(L" /\\ \\ \\___| |/ _\\ ___ _ __\n");
- NelsonPrint(L" / \\/ / _ | |\\ \\ / _ \\| '_ \\\n");
- NelsonPrint(L"/ /\\ | __| |_\\ | (_) | | | |\n");
- NelsonPrint(L"\\_\\ \\/ \\___|_|\\__/\\___/|_| |_|\n");
+ NelsonPrint(L" _ __ __\n");
+ NelsonPrint(L" / | / /__ / /________ ____\n");
+ NelsonPrint(L" / |/ / _ \\/ / ___/ __ \\/ __ \\\n");
+ NelsonPrint(L" / /| / __/ (__ ) /_/ / / / /\n");
+ NelsonPrint(L"/_/ |_/\\___/_/____/\\____/_/ /_/\n");
}
//=============================================================================
} // namespace Nelson
diff --git a/modules/data_structures/help/en_US/xml/cellfun.xml b/modules/data_structures/help/en_US/xml/cellfun.xml
index ce52ca68bb..28263d7ae0 100644
--- a/modules/data_structures/help/en_US/xml/cellfun.xml
+++ b/modules/data_structures/help/en_US/xml/cellfun.xml
@@ -81,7 +81,7 @@ f = str2func('size');
y;
-endfunction
+end
function result = errorfun(S, varargin)
disp(nargin())
@@ -91,7 +91,7 @@ function result = errorfun(S, varargin)
disp(varargin{1})
disp(varargin{2})
result = false;
-endfunction]]>
+end]]>
diff --git a/modules/data_structures/help/en_US/xml/num2cellxml b/modules/data_structures/help/en_US/xml/num2cell.xml
similarity index 72%
rename from modules/data_structures/help/en_US/xml/num2cellxml
rename to modules/data_structures/help/en_US/xml/num2cell.xml
index 06ecacb074..82c7028c2f 100644
--- a/modules/data_structures/help/en_US/xml/num2cellxml
+++ b/modules/data_structures/help/en_US/xml/num2cell.xml
@@ -4,7 +4,8 @@
en_USnum2cell
- Convert array to cell array with consistently sized cells.
+ Convert array to cell array with consistently sized cells.C = num2cell(A)
@@ -19,7 +20,8 @@
dim
- positive integer value or positive vector of integers.
+ positive integer value or positive vector of integers.
@@ -33,8 +35,10 @@
-
num2cell function converts a numeric array into a cell array, where each element of the numeric array is placed in its own cell in the resulting cell array.
-
If A is a character array, num2cell will convert each row of the array into a separate cell in the resulting cell array.
+
num2cell function converts a numeric array into a cell array, where each element of the numeric array is placed in its own cell in the resulting cell array.
+
If A is a character array, num2cell will convert each row of the array into a separate cell in the resulting cell array.
diff --git a/modules/display_format/functions/formattedDisplayText.m b/modules/display_format/functions/formattedDisplayText.m
index e2a5bbd5c9..1002bee559 100644
--- a/modules/display_format/functions/formattedDisplayText.m
+++ b/modules/display_format/functions/formattedDisplayText.m
@@ -8,7 +8,7 @@
% LICENCE_BLOCK_END
%=============================================================================
function result = formattedDisplayText(varargin)
- nbArgsValid = (nargin >= 1) && (mod(nargin, 2) == 1);
+ nbArgsValid = mod(nargin, 2) == 1;
if ~nbArgsValid
error(_('Wrong number of input arguments.'));
end
@@ -25,23 +25,21 @@
validField = false;
name = lower(args{i});
value = args{i + 1};
- if strcmp(name, 'numericformat')
+ switch name
+ case 'numericformat'
validateNumericFormat(value, i + 1);
newFormat.NumericFormat = value;
validField = true;
- end
- if strcmp(name, 'linespacing')
+
+ case 'linespacing'
validateLineSpacing(value, i + 1);
newFormat.LineSpacing = value;
validField = true;
- end
- if strcmp(name, 'suppressmarkup')
- % not managed -> ignored
- validField = true;
- end
- if strcmp(name, 'usetruefalseforlogical')
+
+ case {'suppressmarkup', 'usetruefalseforlogical'}
% not managed -> ignored
validField = true;
+
end
if ~validField
msg = sprintf(_('Invalid name-value argument: %s.'), args{i});
diff --git a/modules/dynamic_link/help/en_US/xml/loadcompiler.xml b/modules/dynamic_link/help/en_US/xml/loadcompilerconf.xml
similarity index 100%
rename from modules/dynamic_link/help/en_US/xml/loadcompiler.xml
rename to modules/dynamic_link/help/en_US/xml/loadcompilerconf.xml
diff --git a/modules/interpreter/help/en_US/xml/switch.xml b/modules/interpreter/help/en_US/xml/switch.xml
index 30c1d44bca..e94b925429 100644
--- a/modules/interpreter/help/en_US/xml/switch.xml
+++ b/modules/interpreter/help/en_US/xml/switch.xml
@@ -36,7 +36,7 @@
otherwise
c = 'not sure';
end
-endfunction
+end
]]>
diff --git a/modules/memory_manager/help/en_US/xml/global.xml b/modules/memory_manager/help/en_US/xml/global.xml
index e5a9698794..b5799e4a3e 100644
--- a/modules/memory_manager/help/en_US/xml/global.xml
+++ b/modules/memory_manager/help/en_US/xml/global.xml
@@ -36,7 +36,7 @@
> 1) && isa(varargin{2}, 'DelimitedTextImportOptions')
- options = varargin{2};
- else
- options = detectImportOptions(filename);
- end
- ce = readcell(filename, options);
- variableNames = options.VariableNames;
- VariableNamesLine = options.VariableNamesLine;
- RowNamesColumn = options.RowNamesColumn;
- if ~isempty(variableNames) && (VariableNamesLine > 0)
- ce(VariableNamesLine, :) = [];
- end
- if RowNamesColumn > 0
- variableNames(VariableNamesLine) = [];
- rowNames = ce(:, RowNamesColumn);
- ce(:, RowNamesColumn) = [];
- else
- rowNames = {};
- end
- args = {};
- if ~isempty(variableNames)
- args = [args, 'VariableNames', {variableNames}];
- end
- if ~isempty(rowNames)
- args = [args, 'RowNames', {rowNames'}];
- end
- if isrow(ce)
- varargout{1} = table(ce{:}, args{:});
- else
- varargout{1} = table(ce, args{:});
- end
-end
-%=============================================================================
diff --git a/modules/spreadsheet/help/en_US/xml/detectImportOptions.xml b/modules/spreadsheet/help/en_US/xml/detectImportOptions.xml
new file mode 100644
index 0000000000..2d03e87a02
--- /dev/null
+++ b/modules/spreadsheet/help/en_US/xml/detectImportOptions.xml
@@ -0,0 +1,86 @@
+
+
+ SAME AS NELSON SOFTWARE
+
+ en_US
+ detectImportOptions
+ Create import options based on file content.
+
+
+ options = detectImportOptions(filename)
+
+
+
+
+ filename
+ a string: filename source.
+
+
+
+
+
+ options
+ DelimitedTextImportOptions object.
+
+
+
+
+
+
options = detectImportOptions(filename) identifies a table in a file and returns an import options object.
+
You can customize this object and use it with readtable, readcell or readmatrix to control how Nelson imports data as a table, cell array, or matrix.
+
The type of the returned options object depends on the file's extension.
C = readcell(filename) creates a cell array by importing column-oriented data from a text or spreadsheet file.
+
C = readcell(filename, opts) creates a cell array using the settings defined in the opts import options object. The import options object allows you to customize how readcell interprets the file, offering greater control, improved performance, and the ability to reuse the configuration compared to the default syntax.
T = readtable(filename) creates a table by importing column-oriented data from a text or spreadsheet file.
+
T = readtable(filename, opts) creates a table using the settings defined in the opts import options object. The import options object allows you to customize how readtable interprets the file, offering greater control, improved performance, and the ability to reuse the configuration compared to the default syntax.
+
+
+
+
+
+
+
+
+ nelson
+
+
+Names = {'John'; 'Alice'; 'Bob'; 'Diana'};
+Age = [28; 34; 22; 30];
+Height = [175; 160; 180; 165];
+Weight = [70; 55; 80; 60];
+T1 = table(Names, Age, Height, Weight);
+writetable(T1, [tempdir,'readtable_1.csv'])
+T2 = readtable([tempdir,'readtable_1.csv'])
+
+
+
+
+
+ nelson
+
+
+Names = {'John'; 'Alice'; 'Bob'; 'Diana'};
+Age = [28; 34; 22; 30];
+Height = [175; 160; 180; 165];
+Weight = [70; 55; 80; 60];
+T = table(Names, Age, Height, Weight);
+writetable(T, [tempdir,'readtable_1.csv'])
+options = detectImportOptions([tempdir,'readtable_1.csv']);
+T1 = readtable([tempdir,'readtable_1.csv'], options)
+options.DataLines = [1 Inf]
+T2 = readtable([tempdir,'readtable_1.csv'], options)
+
+
+
+
+
+
+
+ writetable
+
+
+ detectImportOptions
+
+
+ readcell
+
+
+ fileread
+
+
+
+
+
+ 1.10.0
+ initial version
+
+
+
+
+ Allan CORNET
+
+
diff --git a/modules/spreadsheet/src/cpp/DetectImportOptions.cpp b/modules/spreadsheet/src/cpp/DetectImportOptions.cpp
index fca143cf3b..28295ad657 100644
--- a/modules/spreadsheet/src/cpp/DetectImportOptions.cpp
+++ b/modules/spreadsheet/src/cpp/DetectImportOptions.cpp
@@ -156,7 +156,7 @@ struct DelimiterStats
size_t totalCount;
};
//=============================================================================
-static DelimiterStats
+DelimiterStats
analyzeDelimiterInLine(const std::string& line, const std::string& delimiter)
{
DelimiterStats stats { delimiter, 0.0, 0, 0 };
@@ -254,7 +254,7 @@ detectDelimiter(const std::vector& lines, detectImportOptions& opti
if (bestDelimiter != delimiterStats.end() && bestDelimiter->totalCount > 0) {
options.Delimiter = { bestDelimiter->delimiter };
stringVector defaultVariableNames;
- size_t nbElements = bestDelimiter->averageCount + 1;
+ size_t nbElements = (size_t)bestDelimiter->averageCount + 1;
defaultVariableNames.resize(nbElements);
for (size_t k = 0; k < nbElements; ++k) {
defaultVariableNames[k] = "Var" + std::to_string((int)(k + 1));
@@ -437,7 +437,7 @@ detectColumnsAndRowNames(std::vector& lines, const std::string& del
options.VariableNamesLine = 0;
} else {
options.VariableNames = columnNames;
- options.VariableNamesLine = headerLineIndex + 1;
+ options.VariableNamesLine = (int)(headerLineIndex + 1);
}
}
}
@@ -473,7 +473,7 @@ detectDataLines(std::vector& lines, detectImportOptions& options)
}
break;
}
- options.DataLines[0] = dataLineStart + 1;
+ options.DataLines[0] = (double)(dataLineStart + 1);
}
//=============================================================================
// Public Interface
diff --git a/modules/spreadsheet/src/cpp/ReadTable.cpp b/modules/spreadsheet/src/cpp/ReadTable.cpp
index 57c63e69e3..6debdfc887 100644
--- a/modules/spreadsheet/src/cpp/ReadTable.cpp
+++ b/modules/spreadsheet/src/cpp/ReadTable.cpp
@@ -292,8 +292,8 @@ ReadTable(
columnValues[c] = ArrayOf(NLS_DOUBLE, dims, ptr);
} break;
case NLS_DCOMPLEX: {
- std::complex* ptr
- = (std::complex*)ArrayOf::allocateArrayOf(NLS_DCOMPLEX, nbRows);
+ std::complex* ptr = reinterpret_cast*>(
+ ArrayOf::allocateArrayOf(NLS_DCOMPLEX, nbRows));
#if WITH_OPENMP
#pragma omp for
#endif
diff --git a/modules/spreadsheet/src/include/DetectImportOptions.hpp b/modules/spreadsheet/src/include/DetectImportOptions.hpp
index a1062d0ac5..5f6ec9f5ed 100644
--- a/modules/spreadsheet/src/include/DetectImportOptions.hpp
+++ b/modules/spreadsheet/src/include/DetectImportOptions.hpp
@@ -15,6 +15,10 @@
//=============================================================================
namespace Nelson {
//=============================================================================
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4251)
+#endif
class NLSSPREADSHEET_IMPEXP detectImportOptions
{
public:
@@ -28,6 +32,9 @@ class NLSSPREADSHEET_IMPEXP detectImportOptions
std::vector VariableNames;
std::vector DataLines;
};
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
//=============================================================================
NLSSPREADSHEET_IMPEXP void
initializeDetectImportOptions(detectImportOptions& options);
diff --git a/modules/spreadsheet/tests/test_readtable.m b/modules/spreadsheet/tests/test_readtable.m
index 0046e2e0a0..4014b5e0c9 100644
--- a/modules/spreadsheet/tests/test_readtable.m
+++ b/modules/spreadsheet/tests/test_readtable.m
@@ -43,14 +43,15 @@
R = readtable(csv_filename);
assert_isequal(R, REF)
%=============================================================================
-
-
-
-
-
-
-
-
-
-
-
+LastName = {'Sanchez';'Johnson';'Li';'Diaz';'Brown'};
+Age = [38;43;38;40;49];
+Smoker = [1;NaN;NaN;0;1];
+Height = [71;69;64;67;64];
+Weight = [176;163;131;133;119];
+BloodPressure_1 = [124; 109; 125; 117; 122];
+BloodPressure_2 = [93;77;83;75;80];
+REF = table(LastName, Age, Smoker, Height, Weight, BloodPressure_1, BloodPressure_2, 'VariableNames', {'Last Name','Age','Smoker','Height','Weight','BloodPressure 1','BloodPressure 2'});
+csv_filename = [modulepath('spreadsheet'), '/tests/test_readtable_4.csv'];
+R = readtable(csv_filename);
+assert_isequal(R, REF)
+%=============================================================================
diff --git a/modules/spreadsheet/tests/test_readtable_4.csv b/modules/spreadsheet/tests/test_readtable_4.csv
new file mode 100644
index 0000000000..09a19fee3b
--- /dev/null
+++ b/modules/spreadsheet/tests/test_readtable_4.csv
@@ -0,0 +1,6 @@
+Last Name,Age,Smoker,Height,Weight,BloodPressure 1,BloodPressure 2
+Sanchez,38,1,71,176,124,93
+Johnson,43,'0',69,163,109,77
+Li,38,'1',64,131,125,83
+Diaz,40,0,67,133,117,75
+Brown,49,1,64,119,122,80
diff --git a/modules/string/builtin/c/nlsString_builtin.vcxproj b/modules/string/builtin/c/nlsString_builtin.vcxproj
index 3e1e5fab76..577a07cbe5 100644
--- a/modules/string/builtin/c/nlsString_builtin.vcxproj
+++ b/modules/string/builtin/c/nlsString_builtin.vcxproj
@@ -192,6 +192,7 @@
+
@@ -204,6 +205,7 @@
+
@@ -250,6 +252,7 @@
+
@@ -262,6 +265,7 @@
+
diff --git a/modules/string/builtin/c/nlsString_builtin.vcxproj.filters b/modules/string/builtin/c/nlsString_builtin.vcxproj.filters
index 87ec5454c6..8fd3a708ab 100644
--- a/modules/string/builtin/c/nlsString_builtin.vcxproj.filters
+++ b/modules/string/builtin/c/nlsString_builtin.vcxproj.filters
@@ -108,6 +108,12 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
@@ -203,6 +209,12 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
diff --git a/modules/string/builtin/cpp/Gateway.cpp b/modules/string/builtin/cpp/Gateway.cpp
index 9e7ed789ab..5b888a668a 100644
--- a/modules/string/builtin/cpp/Gateway.cpp
+++ b/modules/string/builtin/cpp/Gateway.cpp
@@ -41,6 +41,8 @@
#include "strcatBuiltin.hpp"
#include "appendBuiltin.hpp"
#include "isletterBuiltin.hpp"
+#include "joinBuiltin.hpp"
+#include "strjustBuiltin.hpp"
//=============================================================================
using namespace Nelson;
//=============================================================================
@@ -83,6 +85,8 @@ static const nlsGateway gateway[] = {
{ "strcat", (ptrBuiltin)Nelson::StringGateway::strcatBuiltin, 1, -1 },
{ "append", (ptrBuiltin)Nelson::StringGateway::appendBuiltin, 1, -1 },
{ "isletter", (ptrBuiltin)Nelson::StringGateway::isletterBuiltin, 1, 1 },
+ { "join", (ptrBuiltin)Nelson::StringGateway::joinBuiltin, 1, -2 },
+ { "strjust", (ptrBuiltin)Nelson::StringGateway::strjustBuiltin, 1, 2 },
};
//=============================================================================
NLSGATEWAYFUNC(gateway)
diff --git a/modules/string/builtin/cpp/joinBuiltin.cpp b/modules/string/builtin/cpp/joinBuiltin.cpp
new file mode 100644
index 0000000000..29ca38a608
--- /dev/null
+++ b/modules/string/builtin/cpp/joinBuiltin.cpp
@@ -0,0 +1,76 @@
+//=============================================================================
+// Copyright (c) 2016-present Allan CORNET (Nelson)
+//=============================================================================
+// This file is part of the Nelson.
+//=============================================================================
+// LICENCE_BLOCK_BEGIN
+// SPDX-License-Identifier: LGPL-3.0-or-later
+// LICENCE_BLOCK_END
+//=============================================================================
+#include "joinBuiltin.hpp"
+#include "StringJoin.hpp"
+#include "Error.hpp"
+#include "i18n.hpp"
+#include "InputOutputArgumentsCheckers.hpp"
+#include "OverloadRequired.hpp"
+//=============================================================================
+using namespace Nelson;
+//=============================================================================
+ArrayOfVector
+Nelson::StringGateway::joinBuiltin(int nLhs, const ArrayOfVector& argIn)
+{
+ ArrayOfVector retval;
+ nargoutcheck(nLhs, 0, 1);
+ nargincheck(argIn, 1, 3);
+ ArrayOf delimiters;
+ ArrayOf A = argIn[0];
+ std::vector vec = A.getDimensions().getAsVector();
+ indexType dim = 0;
+ if (!A.isEmpty()) {
+ for (int k = static_cast(vec.size()) - 1; k >= 0; --k) {
+ if (vec[k] != 0 && vec[k] != 1) {
+ dim = k;
+ break;
+ }
+ }
+ }
+ dim += 1;
+ switch (argIn.size()) {
+ case 1: {
+ delimiters = ArrayOf::stringArrayConstructor(L" ");
+ } break;
+ case 2: {
+ if (argIn[1].isRowVectorCharacterArray()) {
+ delimiters = ArrayOf::stringArrayConstructor(argIn[1].getContentAsWideString());
+ } else if (argIn[1].isStringArray()) {
+ delimiters = argIn[1];
+ } else if (argIn[1].isCellArrayOfCharacterVectors()) {
+ delimiters = ArrayOf::stringArrayConstructor(
+ argIn[1].getContentAsWideStringVector(false), argIn[1].getDimensions());
+ } else {
+ dim = argIn[1].getContentAsScalarIndex(false, true);
+ delimiters = ArrayOf::stringArrayConstructor(" ");
+ }
+ } break;
+ case 3: {
+ if (argIn[1].isRowVectorCharacterArray()) {
+ delimiters = ArrayOf::stringArrayConstructor(argIn[1].getContentAsWideString());
+ } else if (argIn[1].isStringArray()) {
+ delimiters = argIn[1];
+ } else if (argIn[1].isCellArrayOfCharacterVectors()) {
+ delimiters = ArrayOf::stringArrayConstructor(
+ argIn[1].getContentAsWideStringVector(false), argIn[1].getDimensions());
+ } else {
+ Error(_W(
+ "Wrong type for argument #3: string, characters or cell of characters expected."));
+ }
+ dim = argIn[2].getContentAsScalarIndex(false, true);
+ } break;
+ default: {
+ Error(ERROR_WRONG_NUMBERS_INPUT_ARGS);
+ } break;
+ }
+ retval << StringJoin(A, delimiters, dim);
+ return retval;
+}
+//=============================================================================
diff --git a/modules/string/builtin/cpp/strjustBuiltin.cpp b/modules/string/builtin/cpp/strjustBuiltin.cpp
new file mode 100644
index 0000000000..b7c4bbf831
--- /dev/null
+++ b/modules/string/builtin/cpp/strjustBuiltin.cpp
@@ -0,0 +1,53 @@
+//=============================================================================
+// Copyright (c) 2016-present Allan CORNET (Nelson)
+//=============================================================================
+// This file is part of the Nelson.
+//=============================================================================
+// LICENCE_BLOCK_BEGIN
+// SPDX-License-Identifier: LGPL-3.0-or-later
+// LICENCE_BLOCK_END
+//=============================================================================
+#include "strjustBuiltin.hpp"
+#include "StringJustify.hpp"
+#include "Error.hpp"
+#include "i18n.hpp"
+#include "InputOutputArgumentsCheckers.hpp"
+#include "OverloadRequired.hpp"
+//=============================================================================
+using namespace Nelson;
+//=============================================================================
+ArrayOfVector
+Nelson::StringGateway::strjustBuiltin(int nLhs, const ArrayOfVector& argIn)
+{
+ ArrayOfVector retval;
+ nargincheck(argIn, 1, 2);
+ nargoutcheck(nLhs, 0, 1);
+ ArrayOf A = argIn[0];
+ if (A.isEmpty()) {
+ retval << A;
+ return retval;
+ }
+ if ((A.isNumeric() || A.isLogical()) && !A.isSparse()) {
+ A.promoteType(NLS_CHAR);
+ }
+ if (A.isCharacterArray() || A.isStringArray() || A.isCellArrayOfCharacterVectors()) {
+ STRINGJUSTIFY side = STRINGJUSTIFY::NLS_JUSTIFY_LEFT;
+ if (argIn.size() == 2) {
+ std::wstring style = argIn[1].getContentAsWideString();
+ if (style == L"left") {
+ side = STRINGJUSTIFY::NLS_JUSTIFY_LEFT;
+ } else if (style == L"center") {
+ side = STRINGJUSTIFY::NLS_JUSTIFY_CENTER;
+ } else if (style == L"right") {
+ side = STRINGJUSTIFY::NLS_JUSTIFY_RIGHT;
+ } else {
+ Error(_W("Wrong value for #2 argument: 'left', 'right', 'center' expected."));
+ }
+ }
+ retval << StringJustify(A, side);
+ } else {
+ OverloadRequired("strjust");
+ }
+ return retval;
+}
+//=============================================================================
diff --git a/modules/string/builtin/include/joinBuiltin.hpp b/modules/string/builtin/include/joinBuiltin.hpp
new file mode 100644
index 0000000000..cd2ff9b35a
--- /dev/null
+++ b/modules/string/builtin/include/joinBuiltin.hpp
@@ -0,0 +1,20 @@
+//=============================================================================
+// Copyright (c) 2016-present Allan CORNET (Nelson)
+//=============================================================================
+// This file is part of the Nelson.
+//=============================================================================
+// LICENCE_BLOCK_BEGIN
+// SPDX-License-Identifier: LGPL-3.0-or-later
+// LICENCE_BLOCK_END
+//=============================================================================
+#pragma once
+//=============================================================================
+#include "ArrayOf.hpp"
+//=============================================================================
+namespace Nelson::StringGateway {
+//=============================================================================
+ArrayOfVector
+joinBuiltin(int nLhs, const ArrayOfVector& argIn);
+//=============================================================================
+} // namespace Nelson
+//=============================================================================
diff --git a/modules/string/builtin/include/strjustBuiltin.hpp b/modules/string/builtin/include/strjustBuiltin.hpp
new file mode 100644
index 0000000000..e7f7d7fbfa
--- /dev/null
+++ b/modules/string/builtin/include/strjustBuiltin.hpp
@@ -0,0 +1,20 @@
+//=============================================================================
+// Copyright (c) 2016-present Allan CORNET (Nelson)
+//=============================================================================
+// This file is part of the Nelson.
+//=============================================================================
+// LICENCE_BLOCK_BEGIN
+// SPDX-License-Identifier: LGPL-3.0-or-later
+// LICENCE_BLOCK_END
+//=============================================================================
+#pragma once
+//=============================================================================
+#include "ArrayOf.hpp"
+//=============================================================================
+namespace Nelson::StringGateway {
+//=============================================================================
+ArrayOfVector
+strjustBuiltin(int nLhs, const ArrayOfVector& argIn);
+//=============================================================================
+} // namespace Nelson
+//=============================================================================
diff --git a/modules/string/functions/@cell/strjust.m b/modules/string/functions/@cell/strjust.m
deleted file mode 100644
index 6462cc7cfd..0000000000
--- a/modules/string/functions/@cell/strjust.m
+++ /dev/null
@@ -1,35 +0,0 @@
-%=============================================================================
-% Copyright (c) 2016-present Allan CORNET (Nelson)
-%=============================================================================
-% This file is part of the Nelson.
-%=============================================================================
-% LICENCE_BLOCK_BEGIN
-% SPDX-License-Identifier: LGPL-3.0-or-later
-% LICENCE_BLOCK_END
-%=============================================================================
-function varargout = strjust(varargin)
- narginchk(1, 2);
- nargoutchk(0, 1);
-
- if nargin == 1
- justify = 'right';
- else
- justify = lower(varargin{2});
- end
- mustBeMember(justify, ["left", "right", "center"], 2);
-
- str = varargin{1};
- if ~iscellstr(str)
- error(_('String, cell of chars or characters vector expected.'));
- end
- result = str;
- for k = 1:numel(str)
- if ischar(str{k})
- result{k} = strjust(str{k}, justify);
- else
- error(_('String, cell of chars or characters vector expected.'));
- end
- end
- varargout{1} = result;
-end
-%=============================================================================
diff --git a/modules/string/functions/@string/strjust.m b/modules/string/functions/@string/strjust.m
deleted file mode 100644
index fb0903010c..0000000000
--- a/modules/string/functions/@string/strjust.m
+++ /dev/null
@@ -1,32 +0,0 @@
-%=============================================================================
-% Copyright (c) 2016-present Allan CORNET (Nelson)
-%=============================================================================
-% This file is part of the Nelson.
-%=============================================================================
-% LICENCE_BLOCK_BEGIN
-% SPDX-License-Identifier: LGPL-3.0-or-later
-% LICENCE_BLOCK_END
-%=============================================================================
-function varargout = strjust(varargin)
- narginchk(1, 2);
- nargoutchk(0, 1);
-
- if nargin == 1
- justify = 'right';
- else
- justify = lower(varargin{2});
- end
- mustBeMember(justify, ["left", "right", "center"], 2);
-
- str = varargin{1};
- result = str;
- for k = 1:numel(str)
- if ischar(str{k})
- result{k} = strjust(str{k}, justify);
- else
- error(_('String, cell of chars or characters vector expected.'));
- end
- end
- varargout{1} = result;
-end
-%=============================================================================
diff --git a/modules/string/functions/strjust.m b/modules/string/functions/strjust.m
deleted file mode 100644
index 1374d4253b..0000000000
--- a/modules/string/functions/strjust.m
+++ /dev/null
@@ -1,83 +0,0 @@
-%=============================================================================
-% Copyright (c) 2016-present Allan CORNET (Nelson)
-%=============================================================================
-% This file is part of the Nelson.
-%=============================================================================
-% LICENCE_BLOCK_BEGIN
-% SPDX-License-Identifier: LGPL-3.0-or-later
-% LICENCE_BLOCK_END
-%=============================================================================
-function varargout = strjust(varargin)
- narginchk(1, 2);
- nargoutchk(0, 1);
-
- if nargin == 1
- justify = 'right';
- else
- justify = lower(varargin{2});
- end
- mustBeMember(justify, ["left", "right", "center"], 2);
-
- str = varargin{1};
- % Handle empty input
- if isempty(str)
- varargout{1} = str;
- return;
- end
-
- if isnumeric(str)
- str = char(str);
- end
-
- % Get the size of the input string
- [m, n] = size(str);
-
- % Initialize justifiedText as a space-filled matrix of the same size
- justifiedText = repmat(' ', m, n);
-
- % Determine the column to add spaces
- if (strcmp(justify, 'left') && ~any(str(:, 1) == ' ')) || (strcmp(justify, 'right') && ~any(str(:, n) == ' '))
- varargout{1} = char(str);
- return;
- end
- % Find row and column indices of non-space characters
- isChar = (str ~= 0 & str ~= ' ');
- [nr, nc] = find(isChar);
-
- % Determine how to justify the text
- if strcmp(justify, 'left')
- shift = shiftLeft(isChar);
- elseif strcmp(justify, 'right')
- shift = shiftRight(isChar);
- else
- shift = shiftCenter(isChar);
- end
-
- % Calculate input and output positions for character copying
- posIn = nr + (nc - 1) * m;
- posOut = nr + (nc + shift(nr)' - 1) * m;
- % Copy characters to the justifiedText matrix
- justifiedText(posOut) = str(posIn);
-
- varargout{1} = justifiedText;
-end
-%=============================================================================
-function shift = shiftLeft(isChar)
- % For left justification, find the leftmost non-space character in each row
- [dummy, shift] = max(isChar, [], 2);
- shift = 1 - shift;
-end
-%=============================================================================
-function shift = shiftRight(isChar)
- % For right justification, find the rightmost non-space character in each row
- [dummy, shift] = max(fliplr(isChar), [], 2);
- shift = shift - 1;
-end
-%=============================================================================
-function shift = shiftCenter(isChar)
- % For center justification, find the middle point between leftmost and rightmost non-space characters
- [dummy, shiftBefore] = max(isChar, [], 2);
- [dummy, shiftAfter] = max(fliplr(isChar), [], 2);
- shift = floor((shiftAfter - shiftBefore) / 2);
-end
-%=============================================================================
diff --git a/modules/string/help/en_US/xml/join.xml b/modules/string/help/en_US/xml/join.xml
new file mode 100644
index 0000000000..9876f1b146
--- /dev/null
+++ b/modules/string/help/en_US/xml/join.xml
@@ -0,0 +1,105 @@
+
+
+ SAME AS NELSON SOFTWARE
+
+ en_US
+ join
+ Combine strings.
+
+
+ res = join(str)
+ res = join(str, delimiter)
+ res = join(str, dim)
+ res = join(str, delimiter, dim)
+
+
+
+
+ str
+ a string, string array or cell of strings.
+
+
+ delimiter
+ a string, string array or cell of strings:Characters used to separate and join strings.
+
+
+ dim
+ positive integer: Dimension along which to join strings.
+
+
+
+
+
+
+ res
+ a string, string array or cell of strings.
+
+
+
+
+
res = join(str) combines the elements of str into a single text by joining them with a space character as the default delimiter.
+
The input, str, can be either a string array or a cell array of character vectors. The output, res, has the same data type as str.
+
+
If str is a 1-by-N or N-by-1 string array or cell array, res will be a string scalar or a cell array containing a single character vector.
+
If str is an M-by-N string array or cell array, res will be an M-by-1 string array or cell array.
+
For arrays of any size, join concatenates elements along the last dimension with a size greater than 1.
+
+
res = join(str, delimiter) joins the elements of str using the specified delimiter instead of the default space character.
+
If delimiter is an array of multiple delimiters, and str has N elements along the joining dimension, delimiter must have N–1 elements along the same dimension. All other dimensions of delimiter must either have size 1 or match the size of the corresponding dimensions of str.
+
res = join(str, dim) combines the elements of str along the specified dimension dim.
+
+
res = join(str, delimiter, dim) joins the elements of str along the specified dimension dim, using delimiter to separate them.
+
+
+
+
+
+
+
+ nelson
+
+
+
+
+
+
+
+
+ append
+
+
+ strcat
+
+
+
+
+
+
+ 1.10.0
+ initial version
+
+
+
+
+ Allan CORNET
+
+
diff --git a/modules/string/help/en_US/xml/strcat.xml b/modules/string/help/en_US/xml/strcat.xml
index 0327c22c58..a8967fd8d7 100644
--- a/modules/string/help/en_US/xml/strcat.xml
+++ b/modules/string/help/en_US/xml/strcat.xml
@@ -60,6 +60,10 @@ C = strcat(A, B)]]>
append
+
+ join
+
+
diff --git a/modules/string/module.iss b/modules/string/module.iss
index 6ffcbdca77..0274ddae7f 100644
--- a/modules/string/module.iss
+++ b/modules/string/module.iss
@@ -17,8 +17,6 @@ Source: {#RootPath}modules\{#MODULE_NAME}\etc\startup.m; DestDir: {app}\modules\
Source: {#RootPath}modules\{#MODULE_NAME}\etc\finish.m; DestDir: {app}\modules\{#MODULE_NAME}\etc\;
;==============================================================================
Source: {#RootPath}modules\{#MODULE_NAME}\functions\*.m; DestDir: {app}\modules\{#MODULE_NAME}\functions\;
-Source: {#RootPath}modules\{#MODULE_NAME}\functions\@cell\*.m; DestDir: {app}\modules\{#MODULE_NAME}\functions\@cell;
-Source: {#RootPath}modules\{#MODULE_NAME}\functions\@string\*.m; DestDir: {app}\modules\{#MODULE_NAME}\functions\@string;
;==============================================================================
Source: {#RootPath}modules\{#MODULE_NAME}\help\*.qch; DestDir: {app}\modules\{#MODULE_NAME}\help\; Flags: recursesubdirs;Components: {#COMPONENT_HELP_FILES} and {#COMPONENT_HELP_BROWSER};
;==============================================================================
diff --git a/modules/string/src/c/nlsString.vcxproj b/modules/string/src/c/nlsString.vcxproj
index b9003ab902..3293e8d38a 100644
--- a/modules/string/src/c/nlsString.vcxproj
+++ b/modules/string/src/c/nlsString.vcxproj
@@ -189,6 +189,8 @@
+
+
@@ -218,6 +220,8 @@
+
+
diff --git a/modules/string/src/c/nlsString.vcxproj.filters b/modules/string/src/c/nlsString.vcxproj.filters
index d434eaea8f..99e19e8570 100644
--- a/modules/string/src/c/nlsString.vcxproj.filters
+++ b/modules/string/src/c/nlsString.vcxproj.filters
@@ -90,6 +90,12 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
@@ -167,6 +173,12 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
diff --git a/modules/string/src/cpp/StringJoin.cpp b/modules/string/src/cpp/StringJoin.cpp
new file mode 100644
index 0000000000..bdc6dda9d9
--- /dev/null
+++ b/modules/string/src/cpp/StringJoin.cpp
@@ -0,0 +1,756 @@
+//=============================================================================
+// Copyright (c) 2016-present Allan CORNET (Nelson)
+//=============================================================================
+// This file is part of the Nelson.
+//=============================================================================
+// LICENCE_BLOCK_BEGIN
+// SPDX-License-Identifier: LGPL-3.0-or-later
+// LICENCE_BLOCK_END
+//=============================================================================
+#include "StringJoin.hpp"
+#include "Error.hpp"
+#include "i18n.hpp"
+#include "nlsBuildConfig.h"
+//=============================================================================
+namespace Nelson {
+//=============================================================================
+static ArrayOf
+StringJoinCharacters(const ArrayOf& A, const ArrayOf& delimiters, size_t dimension);
+//=============================================================================
+static ArrayOf
+StringJoinCellCharacters(const ArrayOf& A, const ArrayOf& delimiters, size_t dimension);
+static ArrayOf
+StringJoinCellCharactersScalarDelimiter(
+ const ArrayOf& A, const ArrayOf& delimiter, size_t dimension);
+static ArrayOf
+StringJoinCellCharactersRowVectorDelimiter(
+ const ArrayOf& A, const ArrayOf& delimiters, size_t dimension);
+static ArrayOf
+StringJoinCellCharactersColumnVectorDelimiter(
+ const ArrayOf& A, const ArrayOf& delimiters, size_t dimension);
+static ArrayOf
+StringJoinCellCharactersMatrixDelimiter(
+ const ArrayOf& A, const ArrayOf& delimiters, size_t dimension);
+//=============================================================================
+static ArrayOf
+StringJoinStringArray(const ArrayOf& A, const ArrayOf& delimiters, size_t dimension);
+static ArrayOf
+StringJoinStringArrayScalarDelimiter(const ArrayOf& A, const ArrayOf& delimiter, size_t dimension);
+static ArrayOf
+StringJoinStringArrayRowVectorDelimiter(
+ const ArrayOf& A, const ArrayOf& delimiters, size_t dimension);
+static ArrayOf
+StringJoinStringArrayColumnVectorDelimiter(
+ const ArrayOf& A, const ArrayOf& delimiters, size_t dimension);
+static ArrayOf
+StringJoinStringArrayMatrixDelimiter(const ArrayOf& A, const ArrayOf& delimiters, size_t dimension);
+//=============================================================================
+static bool
+validateDelimiterDimensions(const ArrayOf& input, const ArrayOf& delimiters, size_t dimension);
+//=============================================================================
+ArrayOf
+StringJoin(const ArrayOf& A, const ArrayOf& delimiters, size_t dimension)
+{
+ if ((dimension > 2 || dimension < 1)
+ || !validateDelimiterDimensions(A, delimiters, dimension)) {
+ Error(_W("Invalid delimiter dimensions."));
+ }
+ if (!delimiters.isStringArray()) {
+ Error(_W("Invalid delimiter type."));
+ }
+ switch (A.getDataClass()) {
+ case NLS_CHAR: {
+ return StringJoinCharacters(A, delimiters, dimension);
+ } break;
+ case NLS_CELL_ARRAY: {
+ return StringJoinCellCharacters(A, delimiters, dimension);
+ } break;
+ case NLS_STRING_ARRAY: {
+ return StringJoinStringArray(A, delimiters, dimension);
+ } break;
+ default: {
+ Error(_W("Type not supported."));
+ } break;
+ }
+ return {};
+}
+//=============================================================================
+bool
+validateDelimiterDimensions(const ArrayOf& input, const ArrayOf& delimiters, size_t dimension)
+{
+ Dimensions inputDims = input.getDimensions();
+ Dimensions delimDims = delimiters.getDimensions();
+
+ // Case 1: Scalar delimiter
+ if (delimiters.isScalar()) {
+ return true;
+ }
+
+ // Case 2: Vector delimiter
+ if (delimiters.isRowVector()) {
+ if (dimension == 1) {
+ return (delimDims.getColumns() == inputDims.getRows() - 1);
+ }
+ if (dimension == 2) {
+ return (delimDims.getColumns() == inputDims.getColumns() - 1);
+ }
+ }
+ if (delimiters.isColumnVector()) {
+ if (dimension == 1) {
+ return (delimDims.getRows() == inputDims.getRows() - 1);
+ }
+ if (dimension == 2) {
+ return delimDims.getColumns() == inputDims.getColumns() - 1;
+ }
+ }
+
+ // Case 3: Matrix delimiter
+ if (!delimiters.isVector()) {
+ if (dimension == 1) {
+ return (delimDims.getRows() == inputDims.getRows() - 1
+ && delimDims.getColumns() == inputDims.getColumns());
+ }
+ if (dimension == 2) {
+ return (delimDims.getRows() == inputDims.getRows()
+ && delimDims.getColumns() == inputDims.getColumns() - 1);
+ }
+ }
+
+ return false;
+}
+//=============================================================================
+ArrayOf
+StringJoinCharacters(const ArrayOf& A, const ArrayOf& delimiters, size_t dimension)
+{
+ if (A.isEmpty()) {
+ return ArrayOf::characterArrayConstructor("");
+ }
+ std::wstring strdelimiter;
+ if ((delimiters.isCellArrayOfCharacterVectors() && delimiters.isScalar())
+ || delimiters.isScalarStringArray() || delimiters.isRowVectorCharacterArray()) {
+ strdelimiter = delimiters.getContentAsWideString();
+ } else {
+ Error(_W("Invalid delimiter dimensions."));
+ }
+ return A;
+}
+//=============================================================================
+ArrayOf
+StringJoinCellCharacters(const ArrayOf& A, const ArrayOf& delimiters, size_t dimension)
+{
+ if (A.isEmpty()) {
+ Dimensions dims(0, 1);
+ return ArrayOf::emptyCell(dims);
+ }
+ if (delimiters.isScalar()) {
+ return StringJoinCellCharactersScalarDelimiter(A, delimiters, dimension);
+ }
+ if (delimiters.isVector()) {
+ if (delimiters.isRowVector()) {
+ return StringJoinCellCharactersRowVectorDelimiter(A, delimiters, dimension);
+ }
+ return StringJoinCellCharactersColumnVectorDelimiter(A, delimiters, dimension);
+ }
+ return StringJoinCellCharactersMatrixDelimiter(A, delimiters, dimension);
+}
+//=============================================================================
+ArrayOf
+StringJoinStringArrayScalarDelimiter(const ArrayOf& A, const ArrayOf& delimiter, size_t dimension)
+{
+ ArrayOf* strs = (ArrayOf*)A.getDataPointer();
+ ArrayOf* delim = (ArrayOf*)delimiter.getDataPointer();
+ size_t nbRows = A.getRows();
+ size_t nbCols = A.getColumns();
+
+ if (dimension == 1) {
+ // Join by rows - output will have nbCols columns
+ Dimensions dims(1, nbCols);
+ ArrayOf* elements = (ArrayOf*)ArrayOf::allocateArrayOf(NLS_STRING_ARRAY, nbCols);
+ ArrayOf strArray = ArrayOf(NLS_STRING_ARRAY, dims, elements);
+
+ // Process each column
+#ifdef WITH_OPENMP
+#pragma omp parallel for
+#endif
+ for (ompIndexType c = 0; c < (ompIndexType)nbCols; c++) {
+ std::wstring joined;
+ bool isMissing = false;
+ // Join rows within this column
+ for (size_t r = 0; r < nbRows && !isMissing; r++) {
+ if (r > 0) {
+ if (delim[0].isRowVectorCharacterArray()) {
+ joined += delim[0].getContentAsWideString();
+ } else {
+ isMissing = true;
+ }
+ }
+ isMissing = isMissing || !strs[r + c * nbRows].isRowVectorCharacterArray();
+ if (!isMissing) {
+ joined += strs[r + c * nbRows].getContentAsWideString();
+ }
+ }
+ elements[c] = isMissing ? ArrayOf::doubleConstructor(std::nan("NaN"))
+ : ArrayOf::characterArrayConstructor(joined);
+ }
+ return strArray;
+ } else {
+ // Join by columns - output will have nbRows rows
+ Dimensions dims(nbRows, 1);
+ ArrayOf* elements = (ArrayOf*)ArrayOf::allocateArrayOf(NLS_STRING_ARRAY, nbRows);
+ ArrayOf strArray = ArrayOf(NLS_STRING_ARRAY, dims, elements);
+
+ // Process each row
+#ifdef WITH_OPENMP
+#pragma omp parallel for
+#endif
+ for (ompIndexType r = 0; r < (ompIndexType)nbRows; r++) {
+ std::wstring joined;
+ bool isMissing = false;
+ // Join columns within this row
+ for (size_t c = 0; c < nbCols && !isMissing; c++) {
+ if (c > 0) {
+ if (delim[0].isRowVectorCharacterArray()) {
+ joined += delim[0].getContentAsWideString();
+ } else {
+ isMissing = true;
+ }
+ }
+ isMissing = isMissing || !strs[r + c * nbRows].isRowVectorCharacterArray();
+ if (!isMissing) {
+ joined += strs[r + c * nbRows].getContentAsWideString();
+ }
+ }
+ elements[r] = isMissing ? ArrayOf::doubleConstructor(std::nan("NaN"))
+ : ArrayOf::characterArrayConstructor(joined);
+ }
+ return strArray;
+ }
+}
+//=============================================================================
+ArrayOf
+StringJoinStringArrayRowVectorDelimiter(
+ const ArrayOf& A, const ArrayOf& delimiters, size_t dimension)
+{
+ ArrayOf* strs = (ArrayOf*)A.getDataPointer();
+ ArrayOf* delim = (ArrayOf*)delimiters.getDataPointer();
+ size_t nbRows = A.getRows();
+ size_t nbCols = A.getColumns();
+
+ if (dimension == 1) {
+ // Join by rows - output will have nbCols columns
+ Dimensions dims(1, nbCols);
+ ArrayOf* elements = (ArrayOf*)ArrayOf::allocateArrayOf(NLS_STRING_ARRAY, nbCols);
+ ArrayOf strArray = ArrayOf(NLS_STRING_ARRAY, dims, elements);
+
+ // Process each column
+#ifdef WITH_OPENMP
+#pragma omp parallel for
+#endif
+ for (ompIndexType c = 0; c < (ompIndexType)nbCols; c++) {
+ std::wstring joined;
+ bool isMissing = false;
+ // Join rows within this column
+ for (size_t r = 0; r < nbRows && !isMissing; r++) {
+ if (r > 0) {
+ if (delim[r - 1].isRowVectorCharacterArray()) {
+ joined += delim[r - 1].getContentAsWideString();
+ } else {
+ isMissing = true;
+ }
+ }
+ isMissing = isMissing || !strs[r + c * nbRows].isRowVectorCharacterArray();
+ if (!isMissing) {
+ joined += strs[r + c * nbRows].getContentAsWideString();
+ }
+ }
+ elements[c] = isMissing ? ArrayOf::doubleConstructor(std::nan("NaN"))
+ : ArrayOf::characterArrayConstructor(joined);
+ }
+ return strArray;
+ } else /* dimension == 2 */ {
+ // Join by columns - output will have nbRows rows
+ Dimensions dims(nbRows, 1);
+ ArrayOf* elements = (ArrayOf*)ArrayOf::allocateArrayOf(NLS_STRING_ARRAY, nbRows);
+ ArrayOf strArray = ArrayOf(NLS_STRING_ARRAY, dims, elements);
+
+ // Process each row
+#ifdef WITH_OPENMP
+#pragma omp parallel for
+#endif
+ for (ompIndexType r = 0; r < (ompIndexType)nbRows; r++) {
+ std::wstring joined;
+ bool isMissing = false;
+ // Join columns within this row
+ for (size_t c = 0; c < nbCols && !isMissing; c++) {
+ if (c > 0) {
+ if (delim[c - 1].isRowVectorCharacterArray()) {
+ joined += delim[c - 1].getContentAsWideString();
+ } else {
+ isMissing = true;
+ }
+ }
+ isMissing = isMissing || !strs[r + c * nbRows].isRowVectorCharacterArray();
+ if (!isMissing) {
+ joined += strs[r + c * nbRows].getContentAsWideString();
+ }
+ }
+ elements[r] = isMissing ? ArrayOf::doubleConstructor(std::nan("NaN"))
+ : ArrayOf::characterArrayConstructor(joined);
+ }
+ return strArray;
+ }
+ return {};
+}
+//=============================================================================
+ArrayOf
+StringJoinStringArrayColumnVectorDelimiter(
+ const ArrayOf& A, const ArrayOf& delimiters, size_t dimension)
+{
+ ArrayOf* strs = (ArrayOf*)A.getDataPointer();
+ ArrayOf* delim = (ArrayOf*)delimiters.getDataPointer();
+ size_t nbRows = A.getRows();
+ size_t nbCols = A.getColumns();
+
+ if (dimension == 1) {
+ // Join by rows - output will have nbCols columns
+ Dimensions dims(1, nbCols);
+ ArrayOf* elements = (ArrayOf*)ArrayOf::allocateArrayOf(NLS_STRING_ARRAY, nbCols);
+ ArrayOf strArray = ArrayOf(NLS_STRING_ARRAY, dims, elements);
+#ifdef WITH_OPENMP
+#pragma omp parallel for
+#endif
+ for (ompIndexType c = 0; c < (ompIndexType)nbCols; c++) {
+ std::wstring joined;
+ bool isMissing = false;
+ for (size_t r = 0; r < nbRows && !isMissing; r++) {
+ if (r > 0) {
+ if (delim[r - 1].isRowVectorCharacterArray()) {
+ joined += delim[r - 1].getContentAsWideString();
+ } else {
+ isMissing = true;
+ }
+ }
+ isMissing = isMissing || !strs[r + c * nbRows].isRowVectorCharacterArray();
+ if (!isMissing) {
+ joined += strs[r + c * nbRows].getContentAsWideString();
+ }
+ }
+ elements[c] = isMissing ? ArrayOf::doubleConstructor(std::nan("NaN"))
+ : ArrayOf::characterArrayConstructor(joined);
+ }
+ return strArray;
+
+ } else /* dimension == 2 */ {
+ // Join by columns - output will have nbRows rows
+ Dimensions dims(nbRows, 1);
+ ArrayOf* elements = (ArrayOf*)ArrayOf::allocateArrayOf(NLS_STRING_ARRAY, nbRows);
+ ArrayOf strArray = ArrayOf(NLS_STRING_ARRAY, dims, elements);
+#ifdef WITH_OPENMP
+#pragma omp parallel for
+#endif
+ for (ompIndexType r = 0; r < (ompIndexType)nbRows; r++) {
+ std::wstring joined;
+ bool isMissing = false;
+ for (size_t c = 0; c < nbCols && !isMissing; c++) {
+ if (c > 0) {
+ if (delim[c - 1].isRowVectorCharacterArray()) {
+ joined += delim[c - 1].getContentAsWideString();
+ } else {
+ isMissing = true;
+ }
+ }
+ isMissing = isMissing || !strs[r + c * nbRows].isRowVectorCharacterArray();
+ if (!isMissing) {
+ joined += strs[r + c * nbRows].getContentAsWideString();
+ }
+ }
+ elements[r] = isMissing ? ArrayOf::doubleConstructor(std::nan("NaN"))
+ : ArrayOf::characterArrayConstructor(joined);
+ }
+ return strArray;
+ }
+}
+//=============================================================================
+ArrayOf
+StringJoinStringArrayMatrixDelimiter(const ArrayOf& A, const ArrayOf& delimiters, size_t dimension)
+{
+ ArrayOf* strs = (ArrayOf*)A.getDataPointer();
+ ArrayOf* delims = (ArrayOf*)delimiters.getDataPointer();
+ size_t nbRows = A.getRows();
+ size_t nbCols = A.getColumns();
+
+ if (dimension == 1) {
+ // Join by rows - output will have nbCols columns
+ Dimensions dims(1, nbCols);
+ ArrayOf* elements = (ArrayOf*)ArrayOf::allocateArrayOf(NLS_STRING_ARRAY, nbCols);
+ ArrayOf strArray = ArrayOf(NLS_STRING_ARRAY, dims, elements);
+
+#ifdef WITH_OPENMP
+#pragma omp parallel for
+#endif
+ for (ompIndexType c = 0; c < (ompIndexType)nbCols; c++) {
+ std::wstring joined;
+ bool isMissing = false;
+ for (size_t r = 0; r < nbRows && !isMissing; r++) {
+ if (r > 0) {
+ if (delims[(r - 1) + c * (nbRows - 1)].isRowVectorCharacterArray()) {
+ joined += delims[(r - 1) + c * (nbRows - 1)].getContentAsWideString();
+ } else {
+ isMissing = true;
+ }
+ }
+ isMissing = isMissing || !strs[r + c * nbRows].isRowVectorCharacterArray();
+ if (!isMissing) {
+ joined += strs[r + c * nbRows].getContentAsWideString();
+ }
+ }
+ elements[c] = isMissing ? ArrayOf::doubleConstructor(std::nan("NaN"))
+ : ArrayOf::characterArrayConstructor(joined);
+ }
+ return strArray;
+
+ } else /* dimension == 2 */ {
+ // Join by columns - output will have nbRows rows
+ Dimensions dims(nbRows, 1);
+ ArrayOf* elements = (ArrayOf*)ArrayOf::allocateArrayOf(NLS_STRING_ARRAY, nbRows);
+ ArrayOf strArray = ArrayOf(NLS_STRING_ARRAY, dims, elements);
+#ifdef WITH_OPENMP
+#pragma omp parallel for
+#endif
+ for (ompIndexType r = 0; r < (ompIndexType)nbRows; r++) {
+ std::wstring joined;
+ bool isMissing = false;
+ for (size_t c = 0; c < nbCols && !isMissing; c++) {
+ if (c > 0) {
+ if (delims[r + (c - 1) * nbRows].isRowVectorCharacterArray()) {
+ joined += delims[r + (c - 1) * nbRows].getContentAsWideString();
+
+ } else {
+ isMissing = true;
+ }
+ }
+ isMissing = !isMissing && !strs[r + c * nbRows].isRowVectorCharacterArray();
+ if (!isMissing) {
+ joined += strs[r + c * nbRows].getContentAsWideString();
+ }
+ }
+ elements[r] = isMissing ? ArrayOf::doubleConstructor(std::nan("NaN"))
+ : ArrayOf::characterArrayConstructor(joined);
+ }
+ return strArray;
+ }
+}
+//=============================================================================
+ArrayOf
+StringJoinStringArray(const ArrayOf& A, const ArrayOf& delimiters, size_t dimension)
+{
+ if (A.isEmpty()) {
+ Dimensions dims(0, 1);
+ return ArrayOf::stringArrayConstructor(wstringVector(), dims);
+ }
+ if (delimiters.isScalar()) {
+ return StringJoinStringArrayScalarDelimiter(A, delimiters, dimension);
+ }
+ if (delimiters.isVector()) {
+ if (delimiters.isRowVector()) {
+ return StringJoinStringArrayRowVectorDelimiter(A, delimiters, dimension);
+ }
+ return StringJoinStringArrayColumnVectorDelimiter(A, delimiters, dimension);
+ }
+ return StringJoinStringArrayMatrixDelimiter(A, delimiters, dimension);
+}
+//=============================================================================
+ArrayOf
+StringJoinCellCharactersScalarDelimiter(
+ const ArrayOf& A, const ArrayOf& delimiter, size_t dimension)
+{
+ ArrayOf* strs = (ArrayOf*)A.getDataPointer();
+ ArrayOf* delim = (ArrayOf*)delimiter.getDataPointer();
+ size_t nbRows = A.getRows();
+ size_t nbCols = A.getColumns();
+
+ if (dimension == 1) {
+ // Join by rows - output will have nbCols columns
+ Dimensions dims(1, nbCols);
+ ArrayOf* elements = (ArrayOf*)ArrayOf::allocateArrayOf(NLS_CELL_ARRAY, nbCols);
+ ArrayOf strArray = ArrayOf(NLS_CELL_ARRAY, dims, elements);
+
+ // Process each column
+#ifdef WITH_OPENMP
+#pragma omp parallel for
+#endif
+ for (ompIndexType c = 0; c < (ompIndexType)nbCols; c++) {
+ std::wstring joined;
+ bool isMissing = false;
+ // Join rows within this column
+ for (size_t r = 0; r < nbRows && !isMissing; r++) {
+ if (r > 0) {
+ if (delim[0].isRowVectorCharacterArray()) {
+ joined += delim[0].getContentAsWideString();
+ } else {
+ isMissing = true;
+ joined = L"";
+ }
+ }
+ if (isMissing) {
+ joined = L"";
+ } else {
+ joined += strs[r + c * nbRows].getContentAsWideString();
+ }
+ }
+ elements[c] = ArrayOf::characterArrayConstructor(joined);
+ }
+ return strArray;
+ } else {
+ // Join by columns - output will have nbRows rows
+ Dimensions dims(nbRows, 1);
+ ArrayOf* elements = (ArrayOf*)ArrayOf::allocateArrayOf(NLS_CELL_ARRAY, nbRows);
+ ArrayOf strArray = ArrayOf(NLS_CELL_ARRAY, dims, elements);
+
+ // Process each row
+#ifdef WITH_OPENMP
+#pragma omp parallel for
+#endif
+ for (ompIndexType r = 0; r < (ompIndexType)nbRows; r++) {
+ std::wstring joined;
+ bool isMissing = false;
+ // Join columns within this row
+ for (size_t c = 0; c < nbCols && !isMissing; c++) {
+ if (c > 0) {
+ if (delim[0].isRowVectorCharacterArray()) {
+ joined += delim[0].getContentAsWideString();
+ } else {
+ isMissing = true;
+ }
+ }
+ if (!isMissing) {
+ joined += strs[r + c * nbRows].getContentAsWideString();
+ } else {
+ joined = L"";
+ }
+ }
+ elements[r] = ArrayOf::characterArrayConstructor(joined);
+ }
+ return strArray;
+ }
+}
+//=============================================================================
+ArrayOf
+StringJoinCellCharactersRowVectorDelimiter(
+ const ArrayOf& A, const ArrayOf& delimiters, size_t dimension)
+{
+ ArrayOf* strs = (ArrayOf*)A.getDataPointer();
+ ArrayOf* delim = (ArrayOf*)delimiters.getDataPointer();
+ size_t nbRows = A.getRows();
+ size_t nbCols = A.getColumns();
+
+ if (dimension == 1) {
+ // Join by rows - output will have nbCols columns
+ Dimensions dims(1, nbCols);
+ ArrayOf* elements = (ArrayOf*)ArrayOf::allocateArrayOf(NLS_CELL_ARRAY, nbCols);
+ ArrayOf strArray = ArrayOf(NLS_CELL_ARRAY, dims, elements);
+
+ // Process each column
+#ifdef WITH_OPENMP
+#pragma omp parallel for
+#endif
+ for (ompIndexType c = 0; c < (ompIndexType)nbCols; c++) {
+ std::wstring joined;
+ bool isMissing = false;
+ // Join rows within this column
+ for (size_t r = 0; r < nbRows && !isMissing; r++) {
+ if (r > 0) {
+ if (delim[r - 1].isRowVectorCharacterArray()) {
+ joined += delim[r - 1].getContentAsWideString();
+ } else {
+ joined = L"";
+ isMissing = true;
+ }
+ }
+ if (!isMissing) {
+ joined += strs[r + c * nbRows].getContentAsWideString();
+ } else {
+ joined = L"";
+ }
+ }
+ elements[c] = ArrayOf::characterArrayConstructor(joined);
+ }
+ return strArray;
+ } else /* dimension == 2 */ {
+ // Join by columns - output will have nbRows rows
+ Dimensions dims(nbRows, 1);
+ ArrayOf* elements = (ArrayOf*)ArrayOf::allocateArrayOf(NLS_CELL_ARRAY, nbRows);
+ ArrayOf strArray = ArrayOf(NLS_CELL_ARRAY, dims, elements);
+
+ // Process each row
+#ifdef WITH_OPENMP
+#pragma omp parallel for
+#endif
+ for (ompIndexType r = 0; r < (ompIndexType)nbRows; r++) {
+ std::wstring joined;
+ bool isMissing = false;
+ // Join columns within this row
+ for (size_t c = 0; c < nbCols && !isMissing; c++) {
+ if (c > 0) {
+ if (delim[c - 1].isRowVectorCharacterArray()) {
+ joined += delim[c - 1].getContentAsWideString();
+ } else {
+ joined = L"";
+ }
+ }
+ if (!isMissing) {
+ joined += strs[r + c * nbRows].getContentAsWideString();
+ } else {
+ joined = L"";
+ }
+ }
+ elements[r] = ArrayOf::characterArrayConstructor(joined);
+ }
+ return strArray;
+ }
+ return {};
+}
+//=============================================================================
+ArrayOf
+StringJoinCellCharactersColumnVectorDelimiter(
+ const ArrayOf& A, const ArrayOf& delimiters, size_t dimension)
+{
+ ArrayOf* strs = (ArrayOf*)A.getDataPointer();
+ ArrayOf* delim = (ArrayOf*)delimiters.getDataPointer();
+ size_t nbRows = A.getRows();
+ size_t nbCols = A.getColumns();
+
+ if (dimension == 1) {
+ // Join by rows - output will have nbCols columns
+ Dimensions dims(1, nbCols);
+ ArrayOf* elements = (ArrayOf*)ArrayOf::allocateArrayOf(NLS_CELL_ARRAY, nbCols);
+ ArrayOf strArray = ArrayOf(NLS_CELL_ARRAY, dims, elements);
+
+#ifdef WITH_OPENMP
+#pragma omp parallel for
+#endif
+ for (ompIndexType c = 0; c < (ompIndexType)nbCols; c++) {
+ std::wstring joined;
+ bool isMissing = false;
+ for (size_t r = 0; r < nbRows && !isMissing; r++) {
+ if (r > 0) {
+ if (delim[r - 1].isRowVectorCharacterArray()) {
+ joined += delim[r - 1].getContentAsWideString();
+ } else {
+ isMissing = true;
+ joined = L"";
+ }
+ }
+ if (!isMissing) {
+ joined += strs[r + c * nbRows].getContentAsWideString();
+ } else {
+ joined = L"";
+ }
+ }
+ elements[c] = ArrayOf::characterArrayConstructor(joined);
+ }
+ return strArray;
+ } else /* dimension == 2 */ {
+ // Join by columns - output will have nbRows rows
+ Dimensions dims(nbRows, 1);
+ ArrayOf* elements = (ArrayOf*)ArrayOf::allocateArrayOf(NLS_CELL_ARRAY, nbRows);
+ ArrayOf strArray = ArrayOf(NLS_CELL_ARRAY, dims, elements);
+#ifdef WITH_OPENMP
+#pragma omp parallel for
+#endif
+ for (ompIndexType r = 0; r < (ompIndexType)nbRows; r++) {
+ std::wstring joined;
+ bool isMissing = false;
+ for (size_t c = 0; c < nbCols && !isMissing; c++) {
+ if (c > 0) {
+ if (delim[c - 1].isRowVectorCharacterArray()) {
+ joined += delim[c - 1].getContentAsWideString();
+ isMissing = true;
+ } else {
+ joined = L"";
+ }
+ }
+ if (!isMissing) {
+ joined += strs[r + c * nbRows].getContentAsWideString();
+ } else {
+ joined = L"";
+ }
+ }
+ elements[r] = ArrayOf::characterArrayConstructor(joined);
+ }
+ return strArray;
+ }
+}
+//=============================================================================
+ArrayOf
+StringJoinCellCharactersMatrixDelimiter(
+ const ArrayOf& A, const ArrayOf& delimiters, size_t dimension)
+{
+ ArrayOf* strs = (ArrayOf*)A.getDataPointer();
+ ArrayOf* delims = (ArrayOf*)delimiters.getDataPointer();
+ size_t nbRows = A.getRows();
+ size_t nbCols = A.getColumns();
+
+ if (dimension == 1) {
+ // Join by rows - output will have nbCols columns
+ Dimensions dims(1, nbCols);
+ ArrayOf* elements = (ArrayOf*)ArrayOf::allocateArrayOf(NLS_CELL_ARRAY, nbCols);
+ ArrayOf strArray = ArrayOf(NLS_CELL_ARRAY, dims, elements);
+#ifdef WITH_OPENMP
+#pragma omp parallel for
+#endif
+ for (ompIndexType c = 0; c < (ompIndexType)nbCols; c++) {
+ std::wstring joined;
+ bool isMissing = false;
+ for (size_t r = 0; r < nbRows && !isMissing; r++) {
+ if (r > 0) {
+ if (delims[(r - 1) + c * (nbRows - 1)].isRowVectorCharacterArray()) {
+ joined += delims[(r - 1) + c * (nbRows - 1)].getContentAsWideString();
+ } else {
+ isMissing = true;
+ joined = L"";
+ }
+ }
+ if (!isMissing) {
+ joined += strs[r + c * nbRows].getContentAsWideString();
+ } else {
+ joined = L"";
+ }
+ }
+ elements[c] = ArrayOf::characterArrayConstructor(joined);
+ }
+ return strArray;
+
+ } else /* dimension == 2 */ {
+ Dimensions dims(nbRows, 1);
+ ArrayOf* elements = (ArrayOf*)ArrayOf::allocateArrayOf(NLS_CELL_ARRAY, nbRows);
+ ArrayOf strArray = ArrayOf(NLS_CELL_ARRAY, dims, elements);
+#ifdef WITH_OPENMP
+#pragma omp parallel for
+#endif
+ for (ompIndexType r = 0; r < (ompIndexType)nbRows; r++) {
+ std::wstring joined;
+ bool isMissing = false;
+ for (size_t c = 0; c < nbCols && !isMissing; c++) {
+ if (c > 0) {
+ if (delims[r + (c - 1) * nbRows].isRowVectorCharacterArray()) {
+ joined += delims[r + (c - 1) * nbRows].getContentAsWideString();
+ } else {
+ isMissing = true;
+ joined = L"";
+ }
+ }
+ if (!isMissing) {
+ joined += strs[r + c * nbRows].getContentAsWideString();
+ } else {
+ joined = L"";
+ }
+ }
+ elements[r] = ArrayOf::characterArrayConstructor(joined);
+ }
+ return strArray;
+ }
+}
+//=============================================================================
+} // namespace Nelson
+//=============================================================================
diff --git a/modules/string/src/cpp/StringJustify.cpp b/modules/string/src/cpp/StringJustify.cpp
new file mode 100644
index 0000000000..4bc9210a3d
--- /dev/null
+++ b/modules/string/src/cpp/StringJustify.cpp
@@ -0,0 +1,98 @@
+//=============================================================================
+// Copyright (c) 2016-present Allan CORNET (Nelson)
+//=============================================================================
+// This file is part of the Nelson.
+//=============================================================================
+// LICENCE_BLOCK_BEGIN
+// SPDX-License-Identifier: LGPL-3.0-or-later
+// LICENCE_BLOCK_END
+//=============================================================================
+#ifdef _MSC_VER
+#define _SCL_SECURE_NO_WARNINGS
+#endif
+#define FMT_HEADER_ONLY
+#include
+#include
+#include
+#include "StringJustify.hpp"
+#include "Error.hpp"
+#include "i18n.hpp"
+#include "nlsBuildConfig.h"
+//=============================================================================
+namespace Nelson {
+//=============================================================================
+static inline std::wstring_view
+stringTrimView(const std::wstring& str)
+{
+ auto start = str.find_first_not_of(L' ');
+ if (start == std::wstring::npos)
+ return std::wstring_view();
+ auto end = str.find_last_not_of(L' ');
+ return std::wstring_view(str.data() + start, end - start + 1);
+}
+//=============================================================================
+static inline std::wstring
+stringJustifyLeft(const std::wstring& str)
+{
+ return fmt::format(L"{:<{}}", stringTrimView(str), str.length());
+}
+//=============================================================================
+static inline std::wstring
+stringJustifyCenter(const std::wstring& str)
+{
+ return fmt::format(L"{:^{}}", stringTrimView(str), str.length());
+}
+//=============================================================================
+static inline std::wstring
+stringJustifyRight(const std::wstring& str)
+{
+ return fmt::format(L"{:>{}}", stringTrimView(str), str.length());
+}
+//=============================================================================
+ArrayOf
+StringJustify(const ArrayOf& stringArrayOf, STRINGJUSTIFY style)
+{
+ switch (stringArrayOf.getDataClass()) {
+ case NLS_CHAR: {
+ std::wstring str = stringArrayOf.getContentAsWideString();
+ switch (style) {
+ case STRINGJUSTIFY::NLS_JUSTIFY_CENTER: {
+ return ArrayOf::characterArrayConstructor(stringJustifyCenter(str));
+ } break;
+ case STRINGJUSTIFY::NLS_JUSTIFY_RIGHT: {
+ return ArrayOf::characterArrayConstructor(stringJustifyRight(str));
+ } break;
+ default:
+ case STRINGJUSTIFY::NLS_JUSTIFY_LEFT: {
+ return ArrayOf::characterArrayConstructor(stringJustifyLeft(str));
+ } break;
+ }
+ } break;
+ case NLS_CELL_ARRAY:
+ case NLS_STRING_ARRAY: {
+ ArrayOf* ptr = (ArrayOf*)stringArrayOf.getDataPointer();
+ ArrayOf* elements = (ArrayOf*)ArrayOf::allocateArrayOf(
+ stringArrayOf.getDataClass(), stringArrayOf.getElementCount());
+ ArrayOf cell
+ = ArrayOf(stringArrayOf.getDataClass(), stringArrayOf.getDimensions(), elements);
+#if WITH_OPENMP
+#pragma omp parallel for
+#endif
+ for (ompIndexType k = 0; k < (ompIndexType)stringArrayOf.getElementCount(); ++k) {
+ if (ptr[k].isRowVectorCharacterArray()) {
+ elements[k] = StringJustify(ptr[k], style);
+ } else {
+ elements[k] = ArrayOf::doubleConstructor(std::nan("NaN"));
+ }
+ }
+ return cell;
+ } break;
+ default: {
+ Error(_W("Type not managed."));
+ } break;
+ }
+ return {};
+}
+//=============================================================================
+};
+//=============================================================================
diff --git a/modules/string/src/include/StringJoin.hpp b/modules/string/src/include/StringJoin.hpp
new file mode 100644
index 0000000000..1cf7603f31
--- /dev/null
+++ b/modules/string/src/include/StringJoin.hpp
@@ -0,0 +1,21 @@
+//=============================================================================
+// Copyright (c) 2016-present Allan CORNET (Nelson)
+//=============================================================================
+// This file is part of the Nelson.
+//=============================================================================
+// LICENCE_BLOCK_BEGIN
+// SPDX-License-Identifier: LGPL-3.0-or-later
+// LICENCE_BLOCK_END
+//=============================================================================
+#pragma once
+//=============================================================================
+#include "ArrayOf.hpp"
+#include "nlsString_exports.h"
+//=============================================================================
+namespace Nelson {
+//=============================================================================
+NLSSTRING_IMPEXP ArrayOf
+StringJoin(const ArrayOf& A, const ArrayOf& delimiter, size_t dimension);
+//=============================================================================
+}
+//=============================================================================
diff --git a/modules/string/src/include/StringJustify.hpp b/modules/string/src/include/StringJustify.hpp
new file mode 100644
index 0000000000..fd79bc2bad
--- /dev/null
+++ b/modules/string/src/include/StringJustify.hpp
@@ -0,0 +1,28 @@
+//=============================================================================
+// Copyright (c) 2016-present Allan CORNET (Nelson)
+//=============================================================================
+// This file is part of the Nelson.
+//=============================================================================
+// LICENCE_BLOCK_BEGIN
+// SPDX-License-Identifier: LGPL-3.0-or-later
+// LICENCE_BLOCK_END
+//=============================================================================
+#pragma once
+//=============================================================================
+#include "ArrayOf.hpp"
+#include "nlsString_exports.h"
+//=============================================================================
+namespace Nelson {
+//=============================================================================
+enum STRINGJUSTIFY
+{
+ NLS_JUSTIFY_LEFT = 0,
+ NLS_JUSTIFY_CENTER = 1,
+ NLS_JUSTIFY_RIGHT = 2,
+};
+//=============================================================================
+NLSSTRING_IMPEXP ArrayOf
+StringJustify(const ArrayOf& stringArrayOf, STRINGJUSTIFY style);
+//=============================================================================
+}
+//=============================================================================
diff --git a/modules/string/tests/bench_join.m b/modules/string/tests/bench_join.m
new file mode 100644
index 0000000000..ef0c3ab34e
--- /dev/null
+++ b/modules/string/tests/bench_join.m
@@ -0,0 +1,11 @@
+%=============================================================================
+% Copyright (c) 2016-present Allan CORNET (Nelson)
+%=============================================================================
+% This file is part of the Nelson.
+%=============================================================================
+% LICENCE_BLOCK_BEGIN
+% SPDX-License-Identifier: LGPL-3.0-or-later
+% LICENCE_BLOCK_END
+%=============================================================================
+A = string(zeros(3000, 3000));
+tic(); R = join(A, ","); toc()
\ No newline at end of file
diff --git a/modules/string/tests/test_join.m b/modules/string/tests/test_join.m
new file mode 100644
index 0000000000..d5835b7d08
--- /dev/null
+++ b/modules/string/tests/test_join.m
@@ -0,0 +1,230 @@
+%=============================================================================
+% Copyright (c) 2016-present Allan CORNET (Nelson)
+%=============================================================================
+% This file is part of the Nelson.
+%=============================================================================
+% LICENCE_BLOCK_BEGIN
+% SPDX-License-Identifier: LGPL-3.0-or-later
+% LICENCE_BLOCK_END
+%=============================================================================
+assert_isequal(nargin('join'), -2);
+assert_isequal(nargout('join'), 1);
+%=============================================================================
+R = join('addd', " ");
+REF = 'addd';
+assert_isequal(R, REF);
+%=============================================================================
+R = join('', "ab");
+REF = '';
+assert_isequal(R, REF);
+%=============================================================================
+str = ["a", "b", "c"];
+R = join(str);
+REF = "a b c";
+assert_isequal(R, REF);
+%=============================================================================
+str = ["a", "b", "c"];
+R = join(str, "-");
+REF = "a-b-c";
+assert_isequal(R, REF);
+%=============================================================================
+C = {'a', 'b', 'c'};
+R = join(C);
+REF = {'a b c'};
+assert_isequal(R, REF);
+%=============================================================================
+C = {'a', 'b', 'c'};
+R = join(C, '+');
+REF = {'a+b+c'};
+assert_isequal(R, REF);
+%=============================================================================
+M = ["a" "b"; "c" "d"];
+R = join(M, "-");
+REF = ["a-b"; "c-d"];
+assert_isequal(R, REF);
+%=============================================================================
+M = ["a" "b"; "c" "d"];
+R = join(M, "-", 1);
+REF = ["a-c" "b-d"];
+assert_isequal(R, REF);
+%=============================================================================
+M = ["a" "b"; "c" "d"];
+R = join(M, "-", 2);
+REF = ["a-b"; "c-d"];
+assert_isequal(R, REF);
+%=============================================================================
+R = join(string([]), "-");
+REF = string(zeros(0, 1));
+assert_isequal(R, REF);
+%=============================================================================
+R = join({}, "-");
+REF = cell(0, 1);
+assert_isequal(R, REF);
+%=============================================================================
+str = ["a", "b", "c"];
+R = join(str, [":", ";"]);
+REF = "a:b;c";
+assert_isequal(R, REF);
+%=============================================================================
+str = ["x","y","z"; "a","b","c"];
+delimiters = [" + "," = "; " - "," = "];
+R = join(str, delimiters);
+REF = ["x + y = z"; "a - b = c"];
+assert_isequal(R, REF);
+%=============================================================================
+M = ["x","y","z";
+ "a","b","c";
+ "d","e","f";
+ "g","h","i"];
+L = ["A","B";
+"C","D";
+"E", "F";
+"G", "H"];
+R = join(M, L);
+REF = ["xAyBz";
+"aCbDc";
+"dEeFf";
+"gGhHi"];
+assert_isequal(R, REF);
+%=============================================================================
+M = ["x","y","z";
+ "a","b","c";
+ "d","e","f";
+ "g","h","i"];
+L = ["A","B"];
+R = join(M, L);
+REF = ["xAyBz";
+ "aAbBc";
+ "dAeBf";
+ "gAhBi"];
+assert_isequal(R, REF);
+%=============================================================================
+M = ["x","y";
+ "a","b";
+ "d","e";
+ "g","h"];
+L = ["A";"B";"C";"D"];
+R = join(M, L);
+REF = ["xAy";
+"aAb";
+"dAe";
+"gAh"];
+assert_isequal(R, REF);
+%=============================================================================
+M = [string(NaN), "b", "c"];
+R = join(M);
+REF = string(NaN);
+assert_isequal(R, REF);
+%=============================================================================
+M = [string(NaN), "b"; "c", string(NaN)];
+R = join(M);
+REF = [string(NaN); string(NaN)];
+assert_isequal(R, REF);
+%=============================================================================
+m = ["a",string(NaN),"b"; "c", "e","d"];
+R = join(m, "-");
+REF = [string(NaN); "c-e-d"];
+assert_isequal(R, REF);
+%=============================================================================
+m = [string(NaN),string(NaN),string(NaN)];
+R = join(m, 1);
+REF = [string(NaN), string(NaN), string(NaN)];
+assert_isequal(R, REF);
+%=============================================================================
+m = [string(NaN),string(NaN),string(NaN)];
+R= join(m, 2);
+REF = string(NaN);
+assert_isequal(R, REF);
+%=============================================================================
+str = ["x","y","z"; "a","b","c"];
+R = join(str, string(NaN), 1);
+REF = [string(NaN),string(NaN),string(NaN)];
+assert_isequal(R, REF);
+%=============================================================================
+str = ["x","y","z"; "a","b","c"];
+R = join(str, string(NaN), 2);
+REF = [string(NaN);string(NaN)];
+assert_isequal(R, REF);
+%=============================================================================
+M = ["x","y","z";
+ "a","b","c";
+ "d","e","f";
+ "g","h","i"];
+%=============================================================================
+R = join(M, "A");
+REF = ["xAyAz";
+"aAbAc";
+"dAeAf";
+"gAhAi"];
+assert_isequal(R, REF);
+%=============================================================================
+cmd = "R = join(M, [""A"";""B""])";
+msg = _('Invalid delimiter dimensions.');
+assert_checkerror(cmd, msg);
+%=============================================================================
+R = join(M, ["A"; "B";"C"], 1);
+REF = [ "xAaBdCg", "yAbBeCh", "zAcBfCi"];
+assert_isequal(R, REF);
+%=============================================================================
+R = "join(M, [""A""; ""B"";""C""], 2)";
+msg = _('Invalid delimiter dimensions.');
+assert_checkerror(cmd, msg);
+%=============================================================================
+R = join(M, ["A", "B","C"], 1);
+REF = [ "xAaBdCg", "yAbBeCh", "zAcBfCi"];
+assert_isequal(R, REF);
+%=============================================================================
+R = "join(M, [""A"", ""B"",""C""], 2)";
+msg = _('Invalid delimiter dimensions.');
+assert_checkerror(cmd, msg);
+%=============================================================================
+R = "join(M, [""A"",""B"";""C"",""D""], 1)";
+msg = _('Invalid delimiter dimensions.');
+assert_checkerror(cmd, msg);
+%=============================================================================
+R = "join(M, [""A"",""B"";""C"",""D""], 2)";
+msg = _('Invalid delimiter dimensions.');
+assert_checkerror(cmd, msg);
+%=============================================================================
+M = ["x", "y", "z", "c";
+ "a", "b", "c", "c";
+ "d", "e", "f", "c";
+ "g", "h", "i", "c"];
+L = ["5", "6", "7", "8";
+ "9", "10", "11", "12";
+ "13", "14", "15", "16"];
+R = join(M, L, 1);
+REF = ["x5a9d13g", "y6b10e14h", "z7c11f15i", "c8c12c16c"];
+assert_isequal(R, REF);
+%=============================================================================
+M = {'x', 'y', 'z', 'c';
+ 'a', 'b', 'c', 'c';
+ 'd', 'e', 'f', 'c';
+ 'g', 'h', 'i', 'c'};
+L = {'5', '6', '7', '8';
+ '9', '10', '11', '12';
+ '13', '14', '15', '16'};
+R = join(M, L, 1);
+REF = {'x5a9d13g', 'y6b10e14h', 'z7c11f15i', 'c8c12c16c'};
+assert_isequal(R, REF);
+%=============================================================================
+str = {'x','y','z'; 'a','b','c'};
+R = join(str, string(NaN), 2);
+REF = {'';''};
+assert_isequal(R, REF);
+%=============================================================================
+M = {'x','y','z';
+ 'a','b','c';
+ 'd','e','f';
+ 'g','h','i'};
+L = ["A","B";
+"C","D";
+string(NaN), "F";
+"G", "H"];
+R = join(M, L);
+REF = {'xAyBz';
+'aCbDc';
+'';
+'gGhHi'};
+assert_isequal(R, REF);
+%=============================================================================
diff --git a/modules/table/functions/@table/disp.m b/modules/table/functions/@table/disp.m
index 64d15e3147..37cc10ea5c 100644
--- a/modules/table/functions/@table/disp.m
+++ b/modules/table/functions/@table/disp.m
@@ -13,17 +13,110 @@ function disp(varargin)
if isempty(T)
return;
end
+ numRows = height(T);
+ NB_LINES_TO_DISPLAY = 20;
+ if (numRows > NB_LINES_TO_DISPLAY)
+ dispTableCompact(T);
+ else
+ dispTableFull(T);
+ end
currentFormat = format();
isLineSpacing = strcmp(currentFormat.LineSpacing, 'loose');
-
+ if isLineSpacing
+ disp(' ');
+ end
+end
+%=============================================================================
+function dispTableCompact(T)
+ NB_LINES_BEFORE = 5;
+ NB_LINES_AFTER = 5;
+ NB_LINES_ELLIPSIS = 3;
+
varNames = T.Properties.VariableNames;
numCols = width(T);
numRows = height(T);
haveRowsNames = ~isempty(T.Properties.RowNames);
- % Display Header
+ head = T(1:NB_LINES_BEFORE, :);
+ tail = T(size(T, 1) - NB_LINES_AFTER + 1:size(T, 1), :);
+
+ nbColsToDisplay = numCols + 1;
+ nbRowsToDisplay = NB_LINES_BEFORE + NB_LINES_AFTER + NB_LINES_ELLIPSIS + 1;
+ strs = string(cell(nbRowsToDisplay, nbColsToDisplay));
+ % Add variable names
+ for j = 1:numCols
+ strs{1, j+1} = varNames{j};
+ end
+
+ for j = 1:numCols
+ for i = 1:NB_LINES_BEFORE
+ t = head{i,j};
+ value = t;
+ is2d = length(size(value));
+ if is2d < 3
+ isString = isa(value, 'string');
+ value = formattedDisplayText(value);
+ if isString
+ value = """" + value + """";
+ end
+ value = char(value);
+ value = strtrim(value(1:end));
+ if length(value) > 15
+ strs{i + 1, j + 1} = sizeAsString(t);
+ else
+ strs{i + 1, j + 1} = value;
+ end
+ else
+ strs{i + 1, j + 1} = sizeAsString(value);
+ end
+ end
+ end
+
+ for j = 1:numCols
+ for i = NB_LINES_BEFORE + 1:NB_LINES_BEFORE + NB_LINES_ELLIPSIS
+ strs{i + 1, j + 1} = ':';
+ end
+ end
+
+ for j = 1:numCols
+ for i = 1:NB_LINES_AFTER
+ t = tail{i,j};
+ value = t;
+ is2d = length(size(value));
+ idx = NB_LINES_BEFORE + NB_LINES_ELLIPSIS + i + 1;
+ if is2d < 3
+ isString = isa(value, 'string');
+ value = formattedDisplayText(value);
+ if isString
+ value = """" + value + """";
+ end
+ value = char(value);
+ value = strtrim(value(1:end));
+ if length(value) > 15
+ strs{idx, j + 1} = sizeAsString(t);
+ else
+ strs{idx, j + 1} = value;
+ end
+ else
+ strs{idx, j + 1} = sizeAsString(value);
+ end
+ end
+ end
+
+ formatTableDisplay(strs, haveRowsNames);
+
+end
+%=============================================================================
+function dispTableFull(T)
+
+ varNames = T.Properties.VariableNames;
+ numCols = width(T);
+ numRows = height(T);
+
+ haveRowsNames = ~isempty(T.Properties.RowNames);
strs = string(cell(numRows + 1, numCols + 1));
+
for j = 1:numCols
for i = 1:numRows
t = T{i,j};
@@ -60,6 +153,18 @@ function disp(varargin)
end
end
+ formatTableDisplay(strs, haveRowsNames)
+
+end
+%=============================================================================
+function s = sizeAsString(value)
+ sz = size(value);
+ sizeStr = sprintf('%dx', sz(1:end));
+ sizeStr = sizeStr(1:end-1);
+ s = [sizeStr, ' ', class(value)];
+end
+%=============================================================================
+function formatTableDisplay(strs, haveRowsNames)
numCols = size(strs, 2);
% Create a new row with empty strings, matching the number of columns in A
@@ -69,10 +174,9 @@ function disp(varargin)
strs = [strs(1,:); newRow; newRow; strs(2:end,:)];
maxLenPerCol = max(strlength(strs), [], 1);
+ startIndex = 1;
if haveRowsNames
startIndex = 2;
- else
- startIndex = 1;
end
for j = startIndex:numCols
@@ -82,6 +186,7 @@ function disp(varargin)
% Initialize the adjusted array with the same size
B = strings(size(strs));
+
% Adjust each string in the array to be centered based on the column's max length of each column
for j = 1:size(strs, 2)
for i = 1:size(strs, 1)
@@ -97,22 +202,8 @@ function disp(varargin)
startIndex = 2;
end
for i = 1:size(B, 1)
- line = blanksSeparator;
- for j = startIndex:size(B, 2)
- line = line + B(i, j) + blanksSeparator;
- end
+ line = blanksSeparator + join(B(i, startIndex:end), blanksSeparator) + blanksSeparator;
disp(line);
end
-
- if isLineSpacing
- disp(' ');
- end
-end
-%=============================================================================
-function s = sizeAsString(value)
- sz = size(value);
- sizeStr = sprintf('%dx', sz(1:end));
- sizeStr = sizeStr(1:end-1);
- s = [sizeStr, ' ', class(value)];
end
%=============================================================================
diff --git a/modules/table/functions/@table/subsref.m b/modules/table/functions/@table/subsref.m
index 71d8045c5e..58b91abb99 100644
--- a/modules/table/functions/@table/subsref.m
+++ b/modules/table/functions/@table/subsref.m
@@ -66,43 +66,47 @@
end
%=============================================================================
function R = braceSubsref(T, sref)
+
+ if (length(sref(1).subs) ~= 2)
+ error('Unsupported subscript type. Brace indexing requires two subscripts (row and column).');
+ end
+
st = struct(T);
-
- if (length(sref(1).subs) == 2)
- rowIdx = sref(1).subs{1};
- colSub = sref(1).subs{2};
+
+ rowIdx = sref(1).subs{1};
+ colSub = sref(1).subs{2};
- if ischar(rowIdx) || isstring(rowIdx) || iscellstr(rowIdx)
- if (isscalar(rowIdx) && rowIdx == ":")
- rowIdx = 1:height(T);
- else
- rowIdx = find(ismember(st.Properties.RowNames, rowIdx));
- if any(rowIdx == 0)
- error(_('One or more row names not found.'));
- end
- end
- elseif (isnumeric(rowIdx) || islogical(rowIdx))
- rowIdx = rowIdx(:);
+ if ischar(rowIdx) || isstring(rowIdx) || iscellstr(rowIdx)
+ if (isscalar(rowIdx) && rowIdx == ":")
+ rowIdx = 1:height(T);
else
- error(_('Invalid row subscript type.'));
+ rowIdx = find(ismember(st.Properties.RowNames, rowIdx));
+ if any(rowIdx == 0)
+ error(_('One or more row names not found.'));
+ end
end
+ elseif (isnumeric(rowIdx) || islogical(rowIdx))
+ rowIdx = rowIdx(:);
+ else
+ error(_('Invalid row subscript type.'));
+ end
- if (ischar(colSub) || isstring(colSub) || iscellstr(colSub))
- if (isscalar(colSub) && colSub == ":")
- colSub = 1:width(T);
- else
- colSub = find(contains(st.Properties.VariableNames, colSub) == true);
- end
- elseif (isnumeric(colSub) || islogical(colSub))
- colSub = colSub(:);
+ if (ischar(colSub) || isstring(colSub) || iscellstr(colSub))
+ if (isscalar(colSub) && colSub == ":")
+ colSub = 1:width(T);
else
- error(_('Invalid column subscript type.'));
+ colSub = find(contains(st.Properties.VariableNames, colSub) == true);
end
+ elseif (isnumeric(colSub) || islogical(colSub))
+ colSub = colSub(:);
else
- error(_('Unsupported subscript type. Brace indexing requires two subscripts (row and column).'));
+ error(_('Invalid column subscript type.'));
end
+ numRows = length(rowIdx);
+ numCols = length(colSub);
R = [];
- for i = 1:length(colSub)
+
+ for i = 1:numCols
variable = st.Properties.VariableNames{colSub(i)};
tempdata = st.data.(variable);
if isnumeric(tempdata) || islogical(tempdata) || isstring(tempdata) || ischar(tempdata)
diff --git a/modules/types/src/cpp/ArrayOf_StringType.cpp b/modules/types/src/cpp/ArrayOf_StringType.cpp
index 2ab7e5b2d8..1be61df111 100644
--- a/modules/types/src/cpp/ArrayOf_StringType.cpp
+++ b/modules/types/src/cpp/ArrayOf_StringType.cpp
@@ -90,7 +90,7 @@ ArrayOf::stringArrayConstructorAllMissing(Dimensions& dims)
}
//=============================================================================
ArrayOf
-ArrayOf::stringArrayConstructor(const stringVector& values, Dimensions& dims)
+ArrayOf::stringArrayConstructor(const stringVector& values, const Dimensions& dims)
{
ArrayOf* elements = nullptr;
size_t nbElements = dims.getElementCount();
@@ -111,7 +111,7 @@ ArrayOf::stringArrayConstructor(const stringVector& values, Dimensions& dims)
}
//=============================================================================
ArrayOf
-ArrayOf::stringArrayConstructor(const wstringVector& values, Dimensions& dims)
+ArrayOf::stringArrayConstructor(const wstringVector& values, const Dimensions& dims)
{
ArrayOf* elements = nullptr;
size_t nbElements = dims.getElementCount();
diff --git a/modules/types/src/include/ArrayOf.hpp b/modules/types/src/include/ArrayOf.hpp
index adf0801460..b75f61c552 100644
--- a/modules/types/src/include/ArrayOf.hpp
+++ b/modules/types/src/include/ArrayOf.hpp
@@ -1392,7 +1392,7 @@ class NLSTYPES_IMPEXP ArrayOf
* @return An ArrayOf object representing the string array.
*/
static ArrayOf
- stringArrayConstructor(const stringVector& values, Dimensions& dims);
+ stringArrayConstructor(const stringVector& values, const Dimensions& dims);
/**
* @brief Constructs a string array from a vector of wstrings and dimensions.
@@ -1401,7 +1401,7 @@ class NLSTYPES_IMPEXP ArrayOf
* @return An ArrayOf object representing the string array.
*/
static ArrayOf
- stringArrayConstructor(const wstringVector& values, Dimensions& dims);
+ stringArrayConstructor(const wstringVector& values, const Dimensions& dims);
/**
* Converts a variable to a string array with the content
diff --git a/tools/missing_help/help_ignore.txt b/tools/missing_help/help_ignore.txt
index 959036d98e..d3c908b8af 100644
--- a/tools/missing_help/help_ignore.txt
+++ b/tools/missing_help/help_ignore.txt
@@ -1,175 +1,181 @@
-COM_class
-COM_disp
-COM_isvalid
-MPI_Comm_disp
-MPI_Comm_isvalid
-QObject_delete
-QObject_disp
-QObject_fieldnames
-QObject_invoke
-QObject_ismethod
-QObject_isprop
-QObject_isvalid
-QObject_properties
-audioplayer_disp
-audioplayer_ismethod
-audioplayer_isprop
-audioplayer_isvalid
-audioplayer_play
-audioplayer_playblocking
-audioplayer_properties
-audioplayer_resume
-dllib_delete
-dllib_disp
-dllib_fieldnames
-dllib_get
-dllib_ismethod
-dllib_isprop
-dllib_isvalid
-dlsym_disp
-dlsym_fieldnames
-dlsym_get
-dlsym_ismethod
-dlsym_isprop
-dlsym_isvalid
-function_handle_disp
-function_handle_extraction
-function_handle_fieldnames
-function_handle_isequal
-function_handle_isequaln
-function_handle_isequalto
-generic_eq_handle
-handle_delete
-handle_disp
-handle_eq_generic
-handle_eq_handle
-handle_fieldnames
-handle_get
-handle_horzcat_handle
-handle_invoke
-handle_isequal
-handle_isequaln
-handle_isequalto
-handle_ismethod
-handle_isprop
-handle_isvalid
-handle_methods
-handle_properties
-handle_set
-handle_vertcat_handle
-libpointer_disp
-libpointer_fieldnames
-libpointer_get
-libpointer_ismethod
-libpointer_isprop
-libpointer_isvalid
-sparsedouble_ctranspose
-sparsedouble_disp
-sparsedouble_horzcat_sparsedouble
-sparsedouble_imag
-sparsedouble_real
-sparsedouble_transpose
-sparsedouble_uminus
-sparsedouble_vertcat_sparsedouble
-sparselogical_ctranspose
-sparselogical_disp
-sparselogical_horzcat
-sparselogical_imag
-sparselogical_real
-sparselogical_transpose
-sparselogical_uminus
-sparselogical_vertcat
-test_parsetags
-cell_vertcat_struct
-sparsedouble_abs
-sparsedouble_acos
-sparsedouble_asin
-sparsedouble_atan
-sparsedouble_ceil
-sparsedouble_conj
-sparsedouble_cos
-sparsedouble_cosh
-sparsedouble_exp
-sparsedouble_expm
-sparsedouble_fix
-sparsedouble_floor
-sparsedouble_int2str
-sparsedouble_isapprox
-sparsedouble_isequal
-sparsedouble_isequaln
-sparsedouble_isequalto
-sparsedouble_isfinite
-sparsedouble_isinf
-sparsedouble_isnan
-sparsedouble_mat2str
-sparsedouble_prod
-sparsedouble_round
-sparsedouble_sin
-sparsedouble_sinh
-sparsedouble_tan
-sparsedouble_tanh
-sparselogical_abs
-sparselogical_int2str
-sparselogical_isequal
-sparselogical_isequaln
-sparselogical_isequalto
-sparselogical_isfinite
-sparselogical_isinf
-sparselogical_isnan
-sparselogical_mat2str
-sparselogical_prod
-dllib_eq_dllib
-dllib_horzcat
-dllib_isequal
-dllib_isequaln
-dllib_isequalto
-dllib_ne_dllib
-dllib_vertcat
-dlsym_eq_dlsym
-dlsym_horzcat
-dlsym_isequal
-dlsym_isequaln
-dlsym_isequalto
-dlsym_ne_dlsym
-dlsym_vertcat
-libpointer_eq
-libpointer_horzcat
-libpointer_isequal
-libpointer_isequaln
-libpointer_isequalto
-libpointer_plus_generic
-libpointer_vertcat
-sparsedouble_datevec
-generic_ne_handle
-handle_ne_generic
-handle_ne_handle
-QObject_eq_QObject
-QObject_eq_generic
-QObject_horzcat
-QObject_isequal
-QObject_isequaln
-QObject_isequalto
-QObject_ne_QObject
-QObject_ne_generic
-QObject_vertcat
-generic_eq_QObject
-generic_ne_QObject
-COM_eq_COM
-COM_eq_generic
-COM_horzcat_COM
-COM_isequal
-COM_isequaln
-COM_isequalto
-COM_ne_COM
-COM_ne_generic
-COM_vertcat_COM
+@AfterAllFuture/delete
+@AfterAllFuture/disp
+@AfterAllFuture/display
+@AfterAllFuture/get
+@AfterEachFuture/delete
+@AfterEachFuture/disp
+@AfterEachFuture/display
+@AfterEachFuture/get
+@COM/class
+@COM/delete
+@COM/disp
+@COM/display
+@COM/fieldnames
+@COM/get
+@COM/invoke
+@COM/ismethod
+@COM/isprop
+@COM/isvalid
+@COM/methods
+@COM/set
+@FevalFuture/delete
+@FevalFuture/disp
+@FevalFuture/display
+@FevalFuture/get
+@FevalQueue/delete
+@FevalQueue/disp
+@FevalQueue/display
+@FevalQueue/get
+@MException/fieldnames
+@PythonEnvironment/disp
+@PythonEnvironment/display
+@PythonEnvironment/get
+@PythonEnvironment/set
+@PythonEnvironment/struct
+@QObject/delete
+@QObject/disp
+@QObject/display
+@QObject/fieldnames
+@QObject/get
+@QObject/invoke
+@QObject/ismethod
+@QObject/isprop
+@QObject/isvalid
+@QObject/methods
+@QObject/properties
+@QObject/set
+@audioplayer/delete
+@audioplayer/disp
+@audioplayer/display
+@audioplayer/fieldnames
+@audioplayer/get
+@audioplayer/ismethod
+@audioplayer/isprop
+@audioplayer/isvalid
+@audioplayer/pause
+@audioplayer/play
+@audioplayer/playblocking
+@audioplayer/properties
+@audioplayer/resume
+@audioplayer/set
+@audioplayer/stop
+@backgroundPool/delete
+@backgroundPool/disp
+@backgroundPool/display
+@backgroundPool/fieldnames
+@backgroundPool/get
+@backgroundPool/struct
+@class/subsasgn
+@dllib/delete
+@dllib/disp
+@dllib/display
+@dllib/fieldnames
+@dllib/get
+@dllib/ismethod
+@dllib/isprop
+@dllib/isvalid
+@dlsym/delete
+@dlsym/disp
+@dlsym/display
+@dlsym/fieldnames
+@dlsym/get
+@dlsym/ismethod
+@dlsym/isprop
+@dlsym/isvalid
+@function_handle/disp
+@function_handle/display
+@function_handle/fieldnames
+@function_handle/isequal
+@function_handle/isequaln
+@function_handle/isequalto
+@function_handle/subsref
+@graphics_object/delete
+@graphics_object/disp
+@graphics_object/display
+@graphics_object/eq
+@graphics_object/get
+@graphics_object/isequal
+@graphics_object/isequaln
+@graphics_object/isequalto
+@graphics_object/isprop
+@graphics_object/properties
+@graphics_object/set
+@handle/delete
+@handle/disp
+@handle/display
+@handle/eq
+@handle/fieldnames
+@handle/get
+@handle/horzcat
+@handle/invoke
+@handle/isequal
+@handle/isequaln
+@handle/isequalto
+@handle/ismethod
+@handle/isprop
+@handle/isvalid
+@handle/methods
+@handle/properties
+@handle/set
+@handle/vertcat
+@libpointer/delete
+@libpointer/disp
+@libpointer/display
+@libpointer/fieldnames
+@libpointer/get
+@libpointer/isNull
+@libpointer/ismethod
+@libpointer/isprop
+@libpointer/isvalid
+@libpointer/plus
+@libpointer/reshape
+@libpointer/setdatatype
+@py/class
+@py/disp
+@py/display
+@py/get
+@py/invoke
+@py/isequal
+@py/isequalto
+@sparsedouble/horzcat
+@sparsedouble/imag
+@sparsedouble/real
+@sparsedouble/vertcat
+@sparselogical/horzcat
+@sparselogical/imag
+@sparselogical/real
+@sparselogical/vertcat
+AfterAllFuture_used
+AfterEachFuture_used
+FevalFuture_used
+FevalFuture_used
+FevalQueue_used
+SLICOTWrapper
+backgroundPool_used
+webREST
+__subsref__
+mfilename
+test_runfile
+SEEK_CUR
+SEEK_END
+SEEK_SET
+dos
+stderr
+stdin
+stdout
+endfunction
+history_manager
COM_xlsformat
-generic_eq_COM
-generic_ne_COM
-MPI_Comm_horzcat
-MPI_Comm_ismethod
-MPI_Comm_isprop
-MPI_Comm_vertcat
-audioplayer_horzcat
-audioplayer_vertcat
-webREST
\ No newline at end of file
+nig_header_license
+nig_version
+test_parsetags
+qhelpgenerator
+qcollectiongenerator
+nmm_build_dependencies
+case
+catch
+else
+elseif
+otherwise
+parfor
+return
From bbffaf99950bddf8078c98ce3d107feaa664e905 Mon Sep 17 00:00:00 2001
From: Allan CORNET
Date: Sun, 8 Dec 2024 16:55:08 +0100
Subject: [PATCH 3/4] readmatrix function
---
.../builtin/c/nlsSpreadsheet_builtin.vcxproj | 2 +
.../c/nlsSpreadsheet_builtin.vcxproj.filters | 6 +
modules/spreadsheet/builtin/cpp/Gateway.cpp | 3 +-
.../builtin/cpp/readmatrixBuiltin.cpp | 123 ++++++++
.../builtin/include/readmatrixBuiltin.hpp | 20 ++
.../spreadsheet/src/c/nlsSpreadsheet.vcxproj | 6 +
.../src/c/nlsSpreadsheet.vcxproj.filters | 18 ++
.../spreadsheet/src/cpp/CSVTypeConverters.cpp | 243 ++++++++++++++++
.../spreadsheet/src/cpp/CSVTypeConverters.hpp | 61 ++++
.../src/cpp/DetectImportOptions.cpp | 20 +-
modules/spreadsheet/src/cpp/ReadCell.cpp | 197 ++-----------
.../spreadsheet/src/cpp/ReadLinesFromFile.cpp | 54 ++++
.../spreadsheet/src/cpp/ReadLinesFromFile.hpp | 21 ++
modules/spreadsheet/src/cpp/ReadMatrix.cpp | 270 ++++++++++++++++++
modules/spreadsheet/src/cpp/ReadTable.cpp | 144 +---------
.../spreadsheet/src/include/ReadMatrix.hpp | 21 ++
modules/spreadsheet/tests/readmatrix_1.csv | 5 +
modules/spreadsheet/tests/readmatrix_2.csv | 5 +
modules/spreadsheet/tests/readmatrix_3.csv | 6 +
modules/spreadsheet/tests/readmatrix_4.csv | 6 +
modules/spreadsheet/tests/readmatrix_5.csv | 6 +
modules/spreadsheet/tests/readmatrix_6.csv | 2 +
modules/spreadsheet/tests/readmatrix_7.csv | 2 +
modules/spreadsheet/tests/test_readmatrix.m | 64 +++++
24 files changed, 992 insertions(+), 313 deletions(-)
create mode 100644 modules/spreadsheet/builtin/cpp/readmatrixBuiltin.cpp
create mode 100644 modules/spreadsheet/builtin/include/readmatrixBuiltin.hpp
create mode 100644 modules/spreadsheet/src/cpp/CSVTypeConverters.cpp
create mode 100644 modules/spreadsheet/src/cpp/CSVTypeConverters.hpp
create mode 100644 modules/spreadsheet/src/cpp/ReadLinesFromFile.cpp
create mode 100644 modules/spreadsheet/src/cpp/ReadLinesFromFile.hpp
create mode 100644 modules/spreadsheet/src/cpp/ReadMatrix.cpp
create mode 100644 modules/spreadsheet/src/include/ReadMatrix.hpp
create mode 100644 modules/spreadsheet/tests/readmatrix_1.csv
create mode 100644 modules/spreadsheet/tests/readmatrix_2.csv
create mode 100644 modules/spreadsheet/tests/readmatrix_3.csv
create mode 100644 modules/spreadsheet/tests/readmatrix_4.csv
create mode 100644 modules/spreadsheet/tests/readmatrix_5.csv
create mode 100644 modules/spreadsheet/tests/readmatrix_6.csv
create mode 100644 modules/spreadsheet/tests/readmatrix_7.csv
create mode 100644 modules/spreadsheet/tests/test_readmatrix.m
diff --git a/modules/spreadsheet/builtin/c/nlsSpreadsheet_builtin.vcxproj b/modules/spreadsheet/builtin/c/nlsSpreadsheet_builtin.vcxproj
index f324f4789e..be99a388a9 100644
--- a/modules/spreadsheet/builtin/c/nlsSpreadsheet_builtin.vcxproj
+++ b/modules/spreadsheet/builtin/c/nlsSpreadsheet_builtin.vcxproj
@@ -218,6 +218,7 @@
+
@@ -227,6 +228,7 @@
+
diff --git a/modules/spreadsheet/builtin/c/nlsSpreadsheet_builtin.vcxproj.filters b/modules/spreadsheet/builtin/c/nlsSpreadsheet_builtin.vcxproj.filters
index 93c863e34c..e6effe7ea4 100644
--- a/modules/spreadsheet/builtin/c/nlsSpreadsheet_builtin.vcxproj.filters
+++ b/modules/spreadsheet/builtin/c/nlsSpreadsheet_builtin.vcxproj.filters
@@ -53,6 +53,9 @@
Source Files
+
+ Source Files
+
@@ -76,5 +79,8 @@
Header Files
+
+ Header Files
+
\ No newline at end of file
diff --git a/modules/spreadsheet/builtin/cpp/Gateway.cpp b/modules/spreadsheet/builtin/cpp/Gateway.cpp
index 837820ddf4..e1b18eb376 100644
--- a/modules/spreadsheet/builtin/cpp/Gateway.cpp
+++ b/modules/spreadsheet/builtin/cpp/Gateway.cpp
@@ -9,6 +9,7 @@
//=============================================================================
#include "NelsonGateway.hpp"
#include "readcellBuiltin.hpp"
+#include "readmatrixBuiltin.hpp"
#include "readtableBuiltin.hpp"
#include "dlmreadBuiltin.hpp"
#include "dlmwriteBuiltin.hpp"
@@ -21,6 +22,7 @@ const std::wstring gatewayName = L"spreadsheet";
//=============================================================================
static const nlsGateway gateway[] = {
{ "readcell", (ptrBuiltin)Nelson::SpreadsheetGateway::readcellBuiltin, 1, 1 },
+ { "readmatrix", (ptrBuiltin)Nelson::SpreadsheetGateway::readmatrixBuiltin, 1, 1 },
{ "readtable", (ptrBuiltin)Nelson::SpreadsheetGateway::readtableBuiltin, 1, 1 },
{ "dlmread", (ptrBuiltin)Nelson::SpreadsheetGateway::dlmreadBuiltin, 1, 4 },
{ "dlmwrite", (ptrBuiltin)Nelson::SpreadsheetGateway::dlmwriteBuiltin, 0, -3,
@@ -28,7 +30,6 @@ static const nlsGateway gateway[] = {
{ "writetable", (ptrBuiltin)Nelson::SpreadsheetGateway::writetableBuiltin, 0, 4 },
{ "detectImportOptions", (ptrBuiltin)Nelson::SpreadsheetGateway::detectImportOptionsBuiltin, 1,
-1 },
-
};
//=============================================================================
NLSGATEWAYFUNC(gateway)
diff --git a/modules/spreadsheet/builtin/cpp/readmatrixBuiltin.cpp b/modules/spreadsheet/builtin/cpp/readmatrixBuiltin.cpp
new file mode 100644
index 0000000000..fa396aec26
--- /dev/null
+++ b/modules/spreadsheet/builtin/cpp/readmatrixBuiltin.cpp
@@ -0,0 +1,123 @@
+//=============================================================================
+// Copyright (c) 2016-present Allan CORNET (Nelson)
+//=============================================================================
+// This file is part of the Nelson.
+//=============================================================================
+// LICENCE_BLOCK_BEGIN
+// SPDX-License-Identifier: LGPL-3.0-or-later
+// LICENCE_BLOCK_END
+//=============================================================================
+#include