Further improvements to parsing of arguments on the MATLAB command-line

Under GNU/Linux and macOS, double-quote arguments before passing them to the
shell. In particular, this allows passing single-quotes within those arguments.

We therefore have to escape the four characters that are interpreted within
double-quoted strings in POSIX shells: \, ", $ and `

On Windows, also systematically escape the backslashes.

Also move display of arguments before escaping, so that it remains readable.

Ref. #1696
time-shift
Sébastien Villemot 2020-02-10 16:36:52 +01:00
parent ae3f150c99
commit ae59f4dcb2
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
2 changed files with 23 additions and 22 deletions

View File

@ -334,9 +334,10 @@ by the ``dynare`` command.
Defines a macro-variable from the command line (the same effect as
using the Macro directive ``@#define`` in a model file, see
:ref:`macro-proc-lang`). Note that when passing a MACRO_EXPRESSION that
contains a space, you must surround the entire ``-D`` flag with single
quotes, as in the following example. Also note that an expression
passed on the command line can reference variables defined before it.
contains a space (or, under Octave, a double quote), you must surround
the entire ``-D`` flag with single quotes, as in the following example.
Also note that an expression passed on the command line can reference
variables defined before it.
*Example*

View File

@ -210,34 +210,34 @@ else
end
end
command = ['"' dynareroot 'preprocessor' arch_ext filesep 'dynare_m" ' fname] ;
command = [ command ' mexext=' mexext ' "matlabroot=' matlabroot '"'];
if ~isempty(varargin)
if ispc
varargincopy = varargin;
for i = 1:length(varargincopy)
if varargincopy{i}(end) == '\'
varargincopy{i} = [varargincopy{i} '\'];
end
end
varargincopy = strrep(varargincopy, '"', '\"');
dynare_varargin = ['"' strjoin(varargincopy, '" "') '"'];
else
dynare_varargin = ['''' strjoin(varargin, ''' ''') ''''];
end
command = [command ' ' dynare_varargin];
end
if preprocessoroutput
fprintf(['Starting Dynare (version ' dynare_version() ').\n']);
fprintf('Calling Dynare with arguments: ');
if isempty(varargin)
disp('none')
else
disp(dynare_varargin);
disp(strjoin(varargin, ' '));
end
end
command = ['"' dynareroot 'preprocessor' arch_ext filesep 'dynare_m" ' fname] ;
command = [ command ' mexext=' mexext ' "matlabroot=' matlabroot '"'];
% Properly quote arguments before passing them to the shell
if ~isempty(varargin)
varargincopy = varargin;
% Escape backslashes and double-quotes
varargincopy = strrep(varargincopy, '\', '\\');
varargincopy = strrep(varargincopy, '"', '\"');
if ~ispc
% On GNU/Linux and macOS, also escape dollars and backquotes
varargincopy = strrep(varargincopy, '$', '\$');
varargincopy = strrep(varargincopy, '`', '\`');
end
% Finally, enclose arguments within double quotes
dynare_varargin = ['"' strjoin(varargincopy, '" "') '"'];
command = [command ' ' dynare_varargin];
end
% Under Windows, make sure the MEX file is unloaded (in the use_dll case),
% otherwise the preprocessor can't recompile it
if isoctave