diff options
author | Martin Storsjö <martin@martin.st> | 2023-08-30 23:29:15 +0300 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2023-09-01 19:47:52 +0300 |
commit | 2bcc0fdc58a220cb9921b47ec8a32c85f2511a47 (patch) | |
tree | 25bc002d21c15276c490824ed9ff4c43a350bdb1 /llvm/tools/llvm-rc/llvm-rc.cpp | |
parent | 79d06eba71d914a04aee3659b995c93611a3219e (diff) | |
download | llvm-2bcc0fdc58a220cb9921b47ec8a32c85f2511a47.zip llvm-2bcc0fdc58a220cb9921b47ec8a32c85f2511a47.tar.gz llvm-2bcc0fdc58a220cb9921b47ec8a32c85f2511a47.tar.bz2 |
[llvm-windres] Implement the windres flag --use-temp-file
Whether a temp file or a pipe is used for preprocessing is an
internal detail, this flag has a notable effect on the preprocessing
in GNU windres. Without this flag, GNU windres passes command
arguments as-is to popen(), which means they get evaluated by a
shell without being re-escaped for this case. To mimic this,
llvm-windres has manually tried to unescape arguments.
When GNU windres is given the --use-temp-file flag, it uses a
different API for invoking the preprocessor, and this API takes care
of preserving special characters in the command line arguments.
For users of GNU windres, this means that by using --use-temp-file,
they don't need to do the (quite terrible) double escaping of
quotes/spaces etc.
The xz project uses the --use-temp-file flag when invoking
GNU windres, see
https://github.com/tukaani-project/xz/commit/6b117d3b1fe91eb26d533ab16a2e552f84148d47.
However as llvm-windres didn't implement this flag and just
assumed the GNU windres popen() behaviour, they had to use a
different codepath for llvm-windres.
That separate codepath for llvm-windres broke later when llvm-windres
got slightly more accurate unescaping of lone quotes in
0f4c6b120f21d582ab7c5c4f2b2a475086c34938 /
https://reviews.llvm.org/D146848 (fixing a discrepancy to GNU
windres as found in https://github.com/llvm/llvm-project/issues/57334),
and this was reported in
https://github.com/mstorsjo/llvm-mingw/issues/363.
Not touching the implementation of the --preprocessor option
with respect to the --use-temp-file flag; that option is doubly
tricky as GNU windres changed its behaviour in a backwards incompatible
way recently (and llvm-windres currently matches the old behaviour).
(See
https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=21c33bcbe36377abf01614fb1b9be439a3b6de20,
https://sourceware.org/bugzilla/show_bug.cgi?id=27594 and
https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=5edb8e3f5ad8d74a83fc0df7f6e4514eed0aa77f;hp=3abbafc2aacc6706fea3e3e326e2f08d107c3672
for the behaviour change.)
Differential Revision: https://reviews.llvm.org/D159223
Diffstat (limited to 'llvm/tools/llvm-rc/llvm-rc.cpp')
-rw-r--r-- | llvm/tools/llvm-rc/llvm-rc.cpp | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/llvm/tools/llvm-rc/llvm-rc.cpp b/llvm/tools/llvm-rc/llvm-rc.cpp index e5bf623..b955347f 100644 --- a/llvm/tools/llvm-rc/llvm-rc.cpp +++ b/llvm/tools/llvm-rc/llvm-rc.cpp @@ -461,7 +461,14 @@ RcOptions parseWindresOptions(ArrayRef<const char *> ArgsArr, // done this double escaping) probably is confined to cases like these // quoted string defines, and those happen to work the same across unix // and windows. - std::string Unescaped = unescape(Arg->getValue()); + // + // If GNU windres is executed with --use-temp-file, it doesn't use + // popen() to invoke the preprocessor, but uses another function which + // actually preserves tricky characters better. To mimic this behaviour, + // don't unescape arguments here. + std::string Value = Arg->getValue(); + if (!InputArgs.hasArg(WINDRES_use_temp_file)) + Value = unescape(Value); switch (Arg->getOption().getID()) { case WINDRES_include_dir: // Technically, these are handled the same way as e.g. defines, but @@ -475,17 +482,19 @@ RcOptions parseWindresOptions(ArrayRef<const char *> ArgsArr, break; case WINDRES_define: Opts.PreprocessArgs.push_back("-D"); - Opts.PreprocessArgs.push_back(Unescaped); + Opts.PreprocessArgs.push_back(Value); break; case WINDRES_undef: Opts.PreprocessArgs.push_back("-U"); - Opts.PreprocessArgs.push_back(Unescaped); + Opts.PreprocessArgs.push_back(Value); break; case WINDRES_preprocessor_arg: - Opts.PreprocessArgs.push_back(Unescaped); + Opts.PreprocessArgs.push_back(Value); break; } } + // TODO: If --use-temp-file is set, we shouldn't be unescaping + // the --preprocessor argument either, only splitting it. if (InputArgs.hasArg(WINDRES_preprocessor)) Opts.PreprocessCmd = unescapeSplit(InputArgs.getLastArgValue(WINDRES_preprocessor)); |