From c217ce99436d32e9f072761445cbcdd5a38679d7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C3=B3ra=20Kocsis?= <dora@dynare.org>
Date: Fri, 27 Mar 2020 17:40:34 +0100
Subject: [PATCH] add initialize_mdbnomics, move functions to subroutines
 folder, add missing folder (fall-back implementations of MATLAB routines)

---
 src/initialize_mdbnomics.m                    |  67 +++++++++
 src/missing/get_cells_id/get_cells_id.m       |  22 +++
 .../get_file_extension/get_file_extension.m   |  36 +++++
 src/missing/iscolumn/iscolumn.m               |  20 +++
 src/missing/isint/isint.m                     | 129 ++++++++++++++++++
 src/missing/isoctave/isoctave.m               |  20 +++
 src/missing/isrow/isrow.m                     |  20 +++
 .../matlab_ver_less_than.m                    |  29 ++++
 src/missing/strjoin/strjoin.m                 |  63 +++++++++
 src/missing/strsplit/private/ischarint.m      |  27 ++++
 src/missing/strsplit/private/ischarnum.m      |  35 +++++
 src/missing/strsplit/strsplit.m               |  90 ++++++++++++
 .../user_has_octave_forge_package.m           |  30 ++++
 src/{ => subroutines}/fetch_series.m          |   0
 .../fetch_series_by_api_link.m                |   0
 src/{ => subroutines}/fetch_series_page.m     |   0
 src/{ => subroutines}/filter_series.m         |   0
 .../flatten_dbnomics_series.m                 |   0
 src/{ => subroutines}/flatten_editor_series.m |   0
 src/{ => subroutines}/iter_filtered_series.m  |   0
 src/{ => subroutines}/iter_series_info.m      |   0
 src/{ => subroutines}/normalize_period.m      |   0
 src/{ => subroutines}/normalize_value.m       |   0
 23 files changed, 588 insertions(+)
 create mode 100644 src/initialize_mdbnomics.m
 create mode 100644 src/missing/get_cells_id/get_cells_id.m
 create mode 100644 src/missing/get_file_extension/get_file_extension.m
 create mode 100644 src/missing/iscolumn/iscolumn.m
 create mode 100644 src/missing/isint/isint.m
 create mode 100644 src/missing/isoctave/isoctave.m
 create mode 100644 src/missing/isrow/isrow.m
 create mode 100644 src/missing/matlab_ver_less_than/matlab_ver_less_than.m
 create mode 100644 src/missing/strjoin/strjoin.m
 create mode 100644 src/missing/strsplit/private/ischarint.m
 create mode 100644 src/missing/strsplit/private/ischarnum.m
 create mode 100644 src/missing/strsplit/strsplit.m
 create mode 100644 src/missing/user_has_octave_forge_package/user_has_octave_forge_package.m
 rename src/{ => subroutines}/fetch_series.m (100%)
 rename src/{ => subroutines}/fetch_series_by_api_link.m (100%)
 rename src/{ => subroutines}/fetch_series_page.m (100%)
 rename src/{ => subroutines}/filter_series.m (100%)
 rename src/{ => subroutines}/flatten_dbnomics_series.m (100%)
 rename src/{ => subroutines}/flatten_editor_series.m (100%)
 rename src/{ => subroutines}/iter_filtered_series.m (100%)
 rename src/{ => subroutines}/iter_series_info.m (100%)
 rename src/{ => subroutines}/normalize_period.m (100%)
 rename src/{ => subroutines}/normalize_value.m (100%)

diff --git a/src/initialize_mdbnomics.m b/src/initialize_mdbnomics.m
new file mode 100644
index 0000000..c7c781d
--- /dev/null
+++ b/src/initialize_mdbnomics.m
@@ -0,0 +1,67 @@
+function initialize_mdbnomics()
+
+% Copyright (C) 2020 Dynare Team
+%
+% This file is part of Dynare.
+%
+% Dynare is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
+
+% Get the path to the dseries toolbox.
+mdbnomics_src_root = strrep(which('initialize_mdbnomics'), 'initialize_mdbnomics.m', '');
+
+% Set the subfolders to be added in the path.
+p = {'subroutines'};
+
+% Add missing routines if dynare is not in the path
+if ~exist('get_file_extension','file')
+    p{end+1} = 'missing/get_cells_id';
+end
+
+if ~exist('get_file_extension','file')
+    p{end+1} = 'missing/get_file_extension';
+end
+
+if ~exist('isint','file')
+    p{end+1} = 'missing/iscolumn';
+end
+
+if ~exist('isint','file')
+    p{end+1} = 'missing/isint';
+end
+
+if ~exist('isoctave','file')
+    p{end+1} = 'missing/isoctave';
+end
+
+if ~exist('matlab_ver_less_than','file')
+    p{end+1} = 'missing/matlab_ver_less_than';
+end
+
+if ~exist('OCTAVE_VERSION', 'builtin') && ~exist('strsplit','file')
+    p{end+1} = 'missing/strsplit';
+end
+
+if ~exist('OCTAVE_VERSION', 'builtin') && ~exist('strjoin','file')
+    p{end+1} = 'missing/strjoin';
+end
+
+if exist('OCTAVE_VERSION', 'builtin') && ~exist('user_has_octave_forge_package','file')
+    p{end+1} = 'missing/user_has_octave_forge_package';
+end
+
+% Set path
+P = cellfun(@(c)[mdbnomics_src_root c], p, 'uni', false);
+addpath(P{:});
+
+assignin('caller', 'mdbnomics_src_root', mdbnomics_src_root);
diff --git a/src/missing/get_cells_id/get_cells_id.m b/src/missing/get_cells_id/get_cells_id.m
new file mode 100644
index 0000000..c11c8a0
--- /dev/null
+++ b/src/missing/get_cells_id/get_cells_id.m
@@ -0,0 +1,22 @@
+function [B,C] = get_cells_id(str,sep)
+
+% Copyright (C) 2012-2017 Dynare Team
+%
+% This file is part of Dynare.
+%
+% Dynare is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
+
+sep_locations = transpose(strfind(str,sep));
+B = [1; sep_locations+1];
+C = [sep_locations-1; length(str)];
\ No newline at end of file
diff --git a/src/missing/get_file_extension/get_file_extension.m b/src/missing/get_file_extension/get_file_extension.m
new file mode 100644
index 0000000..dad9ee0
--- /dev/null
+++ b/src/missing/get_file_extension/get_file_extension.m
@@ -0,0 +1,36 @@
+function ext = get_file_extension(file)
+
+% returns the extension of a file.
+%
+% INPUTS
+%  o file      string, name of the file
+%
+% OUTPUTS
+%  o ext       string, extension.
+%
+% REMARKS
+%  If the provided file name has no extension, the routine will return an empty array.
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This file is part of Dynare.
+%
+% Dynare is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
+
+[dir, fname, ext] = fileparts(file);
+
+if ~isempty(ext)
+    % Removes the leading dot.
+    ext = ext(2:end);
+end
\ No newline at end of file
diff --git a/src/missing/iscolumn/iscolumn.m b/src/missing/iscolumn/iscolumn.m
new file mode 100644
index 0000000..0264efe
--- /dev/null
+++ b/src/missing/iscolumn/iscolumn.m
@@ -0,0 +1,20 @@
+function r = iscolumn(V)
+% Copyright (C) 2018 Dynare Team
+%
+% This file is part of Dynare.
+%
+% Dynare is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
+
+sz = size(V);
+r = (length(sz) == 2) && (sz(2) == 1);
diff --git a/src/missing/isint/isint.m b/src/missing/isint/isint.m
new file mode 100644
index 0000000..f01a016
--- /dev/null
+++ b/src/missing/isint/isint.m
@@ -0,0 +1,129 @@
+function [l,c,d] = isint(a) % --*-- Unitary tests --*--
+
+%  This function tests if the input argument is an integer.
+%
+%  INPUT
+%  - a    [double]   m*n matrix.
+%
+%  OUTPUT
+%  - l    [logical]  m*n matrix of true and false (1 and 0). l(i,j)=true if a(i,j) is an integer.
+%  - c    [integer]  p*1 vector of indices pointing to the integer elements of a.
+%  - d    [integer]  q*1 vector of indices pointing to the non integer elements of a.
+%
+%  REMARKS
+%  p+q is equal to the product of m by n.
+
+% Copyright (C) 2009-2017 Dynare Team
+%
+% This code is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare dates submodule is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
+
+if ~isnumeric(a)
+    l = false;
+    if nargout>1
+        c = [];
+        d = [];
+    end
+    return
+end
+
+l = abs(fix(a)-a)<1e-15;
+
+if nargout>1
+    c = find(l==true);
+    d = find(l==false);
+end
+
+%@test:1
+%$ a = 1938;
+%$ try
+%$     boolean = isint(a);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:1
+
+%@test:2
+%$ a = pi;
+%$ try
+%$     boolean = isint(a);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, false);
+%$ end
+%$
+%$ T = all(t);
+%@eof:2
+
+%@test:3
+%$ a = '1';
+%$ try
+%$     boolean = isint(a);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(boolean, false);
+%$ end
+%$
+%$ T = all(t);
+%@eof:3
+
+%@test:4
+%$ a = [1; 2; 3];
+%$ try
+%$     [boolean, iV, iF]  = isint(a);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(all(boolean), true);
+%$     t(3) = dassert(isequal(iV, [1; 2; 3]), true);
+%$     t(4) = dassert(isempty(iF), true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:4
+
+%@test:5
+%$ a = [1; pi; 3];
+%$ try
+%$     [boolean, iV, iF]  = isint(a);
+%$     t(1) = true;
+%$ catch
+%$     t(1) = false;
+%$ end
+%$
+%$ if t(1)
+%$     t(2) = dassert(all(boolean), false);
+%$     t(3) = dassert(isequal(iV, [1; 3]), true);
+%$     t(4) = dassert(isequal(iF, 2), true);
+%$ end
+%$
+%$ T = all(t);
+%@eof:5
\ No newline at end of file
diff --git a/src/missing/isoctave/isoctave.m b/src/missing/isoctave/isoctave.m
new file mode 100644
index 0000000..7f1b7db
--- /dev/null
+++ b/src/missing/isoctave/isoctave.m
@@ -0,0 +1,20 @@
+function l = isoctave()
+
+% Tests if Octave is used.
+
+% Copyright (C) 2013-2017 Dynare Team
+%
+% This code is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare dates submodule is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
+
+l = exist('OCTAVE_VERSION');
\ No newline at end of file
diff --git a/src/missing/isrow/isrow.m b/src/missing/isrow/isrow.m
new file mode 100644
index 0000000..ef53534
--- /dev/null
+++ b/src/missing/isrow/isrow.m
@@ -0,0 +1,20 @@
+function r = isrow(V)
+% Copyright (C) 2018 Dynare Team
+%
+% This file is part of Dynare.
+%
+% Dynare is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
+
+sz = size(V);
+r = (length(sz) == 2) && (sz(1) == 1);
diff --git a/src/missing/matlab_ver_less_than/matlab_ver_less_than.m b/src/missing/matlab_ver_less_than/matlab_ver_less_than.m
new file mode 100644
index 0000000..5735a54
--- /dev/null
+++ b/src/missing/matlab_ver_less_than/matlab_ver_less_than.m
@@ -0,0 +1,29 @@
+function r = matlab_ver_less_than(verstr)
+
+% Returns 1 if current Matlab version is strictly older than the one given in argument.
+%
+% INPUTS
+% - verstr  [string]  Matlab's version as 'x.y' or 'x.y.z'
+%
+% OUTPUTS
+% - r       [logical] true or false (0 or 1)
+%
+% REMARKS
+% 1. This function will fail under Octave.
+
+% Copyright (C) 2008-2017 Dynare Team
+%
+% This code is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare dates submodule is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
+
+r = verLessThan('matlab', verstr);
\ No newline at end of file
diff --git a/src/missing/strjoin/strjoin.m b/src/missing/strjoin/strjoin.m
new file mode 100644
index 0000000..666c5f8
--- /dev/null
+++ b/src/missing/strjoin/strjoin.m
@@ -0,0 +1,63 @@
+function rval = strjoin (cstr, delimiter)
+
+% Adapted from Octave's implementation of strjoin
+%
+% Limitation: escaped characters (e.g. '\n') in delimiters will not be
+% interpreted as the characters they represent.
+
+% Copyright (C) 2013-2019 Ben Abbott
+% Copyright (C) 2007 Muthiah Annamalai
+% Copyright (C) 2019 Dynare Team
+%
+% This file is part of Dynare.
+%
+% Dynare is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
+
+if nargin == 1
+    delimiter = ' ';
+elseif nargin < 1 || nargin > 2
+    error('strjoin: must have either one or two arguments')
+end
+if ~(iscellstr(cstr) && (ischar(delimiter) || iscellstr(delimiter)))
+    error('strjoin: first argument must be a cell array, second array either a char array or a cell array')
+end
+
+if numel(cstr) == 1
+    rval = cstr{1};
+    return;
+end
+
+if ischar(delimiter)
+                        % There is no equivalent to do_string_escapes in MATLAB
+                        %delimiter = do_string_escapes(delimiter);
+    delimiter = {delimiter};
+end
+
+num = numel(cstr);
+if numel(delimiter) == 1 && num > 1
+    delimiter = repmat(delimiter, 1, num);
+    delimiter(end) = {''};
+elseif num > 0 && numel(delimiter) ~= num - 1
+    error('strjoin: the number of delimiters does not match the number of strings');
+else
+    delimiter(end+1) = {''};
+end
+
+if num == 0
+    rval = '';
+else
+    tmp = [cstr(:).'; delimiter(:).'];
+    rval = [tmp{:}];
+end
+
diff --git a/src/missing/strsplit/private/ischarint.m b/src/missing/strsplit/private/ischarint.m
new file mode 100644
index 0000000..d325015
--- /dev/null
+++ b/src/missing/strsplit/private/ischarint.m
@@ -0,0 +1,27 @@
+function l = ischarint(x)
+
+% Returns true if and only if char x represents an integer.
+
+% Copyright © 2018 DynareTeam
+%
+% This file is part of Dynare.
+%
+% Dynare is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
+
+s = warning;
+warning off;
+
+l = isint(str2double(x));
+
+warning(s);
\ No newline at end of file
diff --git a/src/missing/strsplit/private/ischarnum.m b/src/missing/strsplit/private/ischarnum.m
new file mode 100644
index 0000000..57b7c7e
--- /dev/null
+++ b/src/missing/strsplit/private/ischarnum.m
@@ -0,0 +1,35 @@
+function l = ischarnum(x)
+
+% Returns true if and only if char x represents a real number.
+
+% Copyright © 2018 DynareTeam
+%
+% This file is part of Dynare.
+%
+% Dynare is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
+
+l = false;
+
+s = warning;
+warning off;
+
+number = str2double(x);
+
+warning(s);
+
+if ~isempty(number)
+    if isreal(number)
+        l = true;
+    end
+end
\ No newline at end of file
diff --git a/src/missing/strsplit/strsplit.m b/src/missing/strsplit/strsplit.m
new file mode 100644
index 0000000..926bb50
--- /dev/null
+++ b/src/missing/strsplit/strsplit.m
@@ -0,0 +1,90 @@
+function tok = strsplit(str, delimiters)
+
+% Splits a string into multiple terms.
+%
+% INPUTS
+% - str        [char]                String to be splitted.
+% - delimiters [char, cell(char)]    Delimiters.
+%
+% OUTPUTS
+% - tok        [cell(char)]          Terms.
+
+% Copyright © 2018 DynareTeam
+%
+% This file is part of Dynare.
+%
+% Dynare is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
+
+remove_empty = true;
+remove_numbers = false;
+
+% Check first input arguments
+assert(ischar(str) && ndims(str)==2 && size(str,1)<=1, 'The first arugment has to be a row char array!');
+
+% Set default value for second input arguments
+if nargin<2
+    delimiters = {' '};
+end
+
+% If second input argument is a char transform it into a sigleton cell of char
+if nargin>1
+    if ischar(delimiters)
+        assert(ndims(delimiters)==2 && size(delimiters,1)==1, 'The second input argument has to be be a char string!');
+        delimiters = {delimiters};
+    end
+end
+
+% Check that `delimiters` is a one dimensional cell
+assert(ndim(delimiters)<=1, 'The second input argument has to be a one dimensional cell array!')
+
+% Check that `delimiters` is a cell of row char arrays
+assert(all(cellfun(@ischar, delimiters)) && all(cellfun(@rows, delimiters)==1), 'The second input argument has to be a cell of row char arrays!')
+
+% If space is one of the delimiters obtain the index in `delimiters`
+idspace = strmatch(' ', delimiters);
+
+% Get the number of delimiters
+n = length(delimiters);
+
+% Remove unnecessary spaces
+delimiters(setdiff(1:n, idspace)) = strtrim(delimiters(setdiff(1:n, idspace)));
+
+% Join all the delimiters (strjoin is not available with matlab version less than R2013a)
+if n>1
+    delimiter = '';
+    for i=1:n
+        if isspace(delimiters{i})
+            delimiter = horzcat(delimiter, '\s');
+        else
+            delimiter = horzcat(delimiter, delimiters{i});
+        end
+        delimiter = horzcat(delimiter,'|');
+    end
+    delimiter = horzcat(delimiter, '\W');
+else
+    delimiter = delimiters{1};
+end
+
+% Get tokens
+tok = regexp(str, delimiter, 'split');
+
+if remove_empty
+    % Remove empty tokens
+    tok = tok(find(~cellfun(@isempty, tok)));
+end
+
+if remove_numbers
+    % Remove numbers
+    tok = tok(find(~cellfun(@ischarnum, tok)));
+end
\ No newline at end of file
diff --git a/src/missing/user_has_octave_forge_package/user_has_octave_forge_package.m b/src/missing/user_has_octave_forge_package/user_has_octave_forge_package.m
new file mode 100644
index 0000000..7aea062
--- /dev/null
+++ b/src/missing/user_has_octave_forge_package/user_has_octave_forge_package.m
@@ -0,0 +1,30 @@
+function [hasPackage] = user_has_octave_forge_package(package)
+% Checks for the availability of a given Octave Forge package
+
+% Copyright (C) 2012-2017 Dynare Team
+%
+% This file is part of Dynare.
+%
+% Dynare is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% Dynare is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
+
+[desc,flag] = pkg('describe', package);
+
+if isequal(flag{1,1}, 'Not installed')
+    hasPackage = 0;
+else
+    if isequal(flag{1,1}, 'Not loaded')
+        pkg('load', package);
+    end
+    hasPackage = 1;
+end
diff --git a/src/fetch_series.m b/src/subroutines/fetch_series.m
similarity index 100%
rename from src/fetch_series.m
rename to src/subroutines/fetch_series.m
diff --git a/src/fetch_series_by_api_link.m b/src/subroutines/fetch_series_by_api_link.m
similarity index 100%
rename from src/fetch_series_by_api_link.m
rename to src/subroutines/fetch_series_by_api_link.m
diff --git a/src/fetch_series_page.m b/src/subroutines/fetch_series_page.m
similarity index 100%
rename from src/fetch_series_page.m
rename to src/subroutines/fetch_series_page.m
diff --git a/src/filter_series.m b/src/subroutines/filter_series.m
similarity index 100%
rename from src/filter_series.m
rename to src/subroutines/filter_series.m
diff --git a/src/flatten_dbnomics_series.m b/src/subroutines/flatten_dbnomics_series.m
similarity index 100%
rename from src/flatten_dbnomics_series.m
rename to src/subroutines/flatten_dbnomics_series.m
diff --git a/src/flatten_editor_series.m b/src/subroutines/flatten_editor_series.m
similarity index 100%
rename from src/flatten_editor_series.m
rename to src/subroutines/flatten_editor_series.m
diff --git a/src/iter_filtered_series.m b/src/subroutines/iter_filtered_series.m
similarity index 100%
rename from src/iter_filtered_series.m
rename to src/subroutines/iter_filtered_series.m
diff --git a/src/iter_series_info.m b/src/subroutines/iter_series_info.m
similarity index 100%
rename from src/iter_series_info.m
rename to src/subroutines/iter_series_info.m
diff --git a/src/normalize_period.m b/src/subroutines/normalize_period.m
similarity index 100%
rename from src/normalize_period.m
rename to src/subroutines/normalize_period.m
diff --git a/src/normalize_value.m b/src/subroutines/normalize_value.m
similarity index 100%
rename from src/normalize_value.m
rename to src/subroutines/normalize_value.m
-- 
GitLab