From 97ca0681bcf815afa04b2e602c4373ffff99586e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 4 May 2019 23:53:54 +0300 Subject: [PATCH] wrappers: Split out shared helpers for native wrapper executables to a header --- Dockerfile | 2 +- Dockerfile.cross | 2 +- Dockerfile.dev | 2 +- wrappers/clang-target-wrapper.c | 125 ++------------------------ wrappers/native-wrapper.h | 151 ++++++++++++++++++++++++++++++++ wrappers/windres-wrapper.c | 120 ++----------------------- 6 files changed, 168 insertions(+), 234 deletions(-) create mode 100644 wrappers/native-wrapper.h diff --git a/Dockerfile b/Dockerfile index e527040..c1dcd60 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,7 +24,7 @@ RUN ./build-llvm.sh $TOOLCHAIN_PREFIX && \ ARG TOOLCHAIN_ARCHS="i686 x86_64 armv7 aarch64" # Install the usual $TUPLE-clang binaries -COPY wrappers/*.sh wrappers/*.c ./wrappers/ +COPY wrappers/*.sh wrappers/*.c wrappers/*.h ./wrappers/ COPY install-wrappers.sh ./ RUN ./install-wrappers.sh $TOOLCHAIN_PREFIX && \ rm -rf /build/* diff --git a/Dockerfile.cross b/Dockerfile.cross index 610134d..fbb1529 100644 --- a/Dockerfile.cross +++ b/Dockerfile.cross @@ -34,7 +34,7 @@ ARG TOOLCHAIN_ARCHS="i686 x86_64 armv7 aarch64" COPY build-mingw-w64.sh ./ RUN ./build-mingw-w64.sh $CROSS_TOOLCHAIN_PREFIX --skip-include-triplet-prefix -COPY wrappers/*.sh wrappers/*.c ./wrappers/ +COPY wrappers/*.sh wrappers/*.c wrappers/*.h ./wrappers/ COPY install-wrappers.sh . RUN ./install-wrappers.sh $CROSS_TOOLCHAIN_PREFIX diff --git a/Dockerfile.dev b/Dockerfile.dev index 7d9d9b2..a2c1965 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -32,7 +32,7 @@ RUN ./strip-llvm.sh $TOOLCHAIN_PREFIX ARG TOOLCHAIN_ARCHS="i686 x86_64 armv7 aarch64" # Install the usual $TUPLE-clang binaries -COPY wrappers/*.sh wrappers/*.c ./wrappers/ +COPY wrappers/*.sh wrappers/*.c wrappers/*.h ./wrappers/ COPY install-wrappers.sh ./ RUN ./install-wrappers.sh $TOOLCHAIN_PREFIX diff --git a/wrappers/clang-target-wrapper.c b/wrappers/clang-target-wrapper.c index 0f3779e..06d461e 100644 --- a/wrappers/clang-target-wrapper.c +++ b/wrappers/clang-target-wrapper.c @@ -16,9 +16,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifdef UNICODE -#define _UNICODE -#endif +#include "native-wrapper.h" #ifndef CLANG #define CLANG "clang" @@ -27,90 +25,6 @@ #define DEFAULT_TARGET "x86_64-w64-mingw32" #endif -#include -#include -#include - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#define EXECVP_CAST -#else -#include -typedef char TCHAR; -#define _T(x) x -#define _tcsrchr strrchr -#define _tcschr strchr -#define _tcsdup strdup -#define _tcscpy strcpy -#define _tcslen strlen -#define _tcscmp strcmp -#define _tperror perror -#define _texecvp execvp -#define _tmain main -#define EXECVP_CAST (char **) -#endif - -#ifdef _UNICODE -#define TS "%ls" -#else -#define TS "%s" -#endif - -static TCHAR *escape(const TCHAR *str) { -#ifdef _WIN32 - TCHAR *out = malloc((_tcslen(str) * 2 + 3) * sizeof(*out)); - TCHAR *ptr = out; - int i; - *ptr++ = '"'; - for (i = 0; str[i]; i++) { - if (str[i] == '"') { - int j = i - 1; - // Before all double quotes, backslashes need to be escaped, but - // not elsewhere. - while (j >= 0 && str[j--] == '\\') - *ptr++ = '\\'; - // Escape the next double quote. - *ptr++ = '\\'; - } - *ptr++ = str[i]; - } - // Any final backslashes, before the quote around the whole argument, - // need to be doubled. - int j = i - 1; - while (j >= 0 && str[j--] == '\\') - *ptr++ = '\\'; - *ptr++ = '"'; - *ptr++ = '\0'; - return out; -#else - return _tcsdup(str); -#endif -} - -static TCHAR *concat(const TCHAR *prefix, const TCHAR *suffix) { - int prefixlen = _tcslen(prefix); - int suffixlen = _tcslen(suffix); - TCHAR *buf = malloc((prefixlen + suffixlen + 1) * sizeof(*buf)); - _tcscpy(buf, prefix); - _tcscpy(buf + prefixlen, suffix); - return buf; -} - -static TCHAR *_tcsrchrs(const TCHAR *str, TCHAR char1, TCHAR char2) { - TCHAR *ptr1 = _tcsrchr(str, char1); - TCHAR *ptr2 = _tcsrchr(str, char2); - if (!ptr1) - return ptr2; - if (!ptr2) - return ptr1; - if (ptr1 < ptr2) - return ptr2; - return ptr1; -} - #ifdef _WIN32 static int filter_line = 0, last_char = '\n'; static void filter_stderr(char *buf, int n) { @@ -222,39 +136,14 @@ static int exec_filtered(const TCHAR **argv) { #endif int _tmain(int argc, TCHAR* argv[]) { - const TCHAR *argv0 = argv[0]; - const TCHAR *sep = _tcsrchrs(argv0, '/', '\\'); - TCHAR *dir = _tcsdup(_T("")); - const TCHAR *basename = argv0; - if (sep) { - dir = _tcsdup(argv0); - dir[sep + 1 - argv0] = '\0'; - basename = sep + 1; - } -#ifdef _WIN32 - TCHAR module_path[8192]; - GetModuleFileName(NULL, module_path, sizeof(module_path)/sizeof(module_path[0])); - TCHAR *sep2 = _tcsrchr(module_path, '\\'); - if (sep2) { - sep2[1] = '\0'; - dir = _tcsdup(module_path); - } -#endif - basename = _tcsdup(basename); - TCHAR *period = _tcschr(basename, '.'); - if (period) - *period = '\0'; - TCHAR *dash = _tcsrchr(basename, '-'); - const TCHAR *target = basename; - const TCHAR *exe = basename; - if (dash) { - *dash = '\0'; - exe = dash + 1; - } else { + const TCHAR *dir; + const TCHAR *target; + const TCHAR *exe; + split_argv(argv[0], &dir, NULL, &target, &exe); + if (!target) target = _T(DEFAULT_TARGET); - } TCHAR *arch = _tcsdup(target); - dash = _tcschr(arch, '-'); + TCHAR *dash = _tcschr(arch, '-'); if (dash) *dash = '\0'; TCHAR *target_os = _tcsrchr(target, '-'); diff --git a/wrappers/native-wrapper.h b/wrappers/native-wrapper.h new file mode 100644 index 0000000..c5e4adc --- /dev/null +++ b/wrappers/native-wrapper.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2018 Martin Storsjo + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef UNICODE +#define _UNICODE +#endif + +#include +#include +#include + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#define EXECVP_CAST +#else +#include +typedef char TCHAR; +#define _T(x) x +#define _tcsrchr strrchr +#define _tcschr strchr +#define _tcsdup strdup +#define _tcscpy strcpy +#define _tcslen strlen +#define _tcscmp strcmp +#define _tcsncmp strncmp +#define _tperror perror +#define _texecvp execvp +#define _tmain main +#define _ftprintf fprintf +#define _vftprintf vfprintf +#define _tunlink unlink +#define EXECVP_CAST (char **) +#endif + +#ifdef _UNICODE +#define TS "%ls" +#else +#define TS "%s" +#endif + +static TCHAR *escape(const TCHAR *str) { +#ifdef _WIN32 + TCHAR *out = malloc((_tcslen(str) * 2 + 3) * sizeof(*out)); + TCHAR *ptr = out; + int i; + *ptr++ = '"'; + for (i = 0; str[i]; i++) { + if (str[i] == '"') { + int j = i - 1; + // Before all double quotes, backslashes need to be escaped, but + // not elsewhere. + while (j >= 0 && str[j--] == '\\') + *ptr++ = '\\'; + // Escape the next double quote. + *ptr++ = '\\'; + } + *ptr++ = str[i]; + } + // Any final backslashes, before the quote around the whole argument, + // need to be doubled. + int j = i - 1; + while (j >= 0 && str[j--] == '\\') + *ptr++ = '\\'; + *ptr++ = '"'; + *ptr++ = '\0'; + return out; +#else + return _tcsdup(str); +#endif +} + +static TCHAR *concat(const TCHAR *prefix, const TCHAR *suffix) { + int prefixlen = _tcslen(prefix); + int suffixlen = _tcslen(suffix); + TCHAR *buf = malloc((prefixlen + suffixlen + 1) * sizeof(*buf)); + _tcscpy(buf, prefix); + _tcscpy(buf + prefixlen, suffix); + return buf; +} + +static TCHAR *_tcsrchrs(const TCHAR *str, TCHAR char1, TCHAR char2) { + TCHAR *ptr1 = _tcsrchr(str, char1); + TCHAR *ptr2 = _tcsrchr(str, char2); + if (!ptr1) + return ptr2; + if (!ptr2) + return ptr1; + if (ptr1 < ptr2) + return ptr2; + return ptr1; +} + +static void split_argv(const TCHAR *argv0, const TCHAR **dir_ptr, const TCHAR **basename_ptr, const TCHAR **target_ptr, const TCHAR **exe_ptr) { + const TCHAR *sep = _tcsrchrs(argv0, '/', '\\'); + TCHAR *dir = _tcsdup(_T("")); + const TCHAR *basename = argv0; + if (sep) { + dir = _tcsdup(argv0); + dir[sep + 1 - argv0] = '\0'; + basename = sep + 1; + } +#ifdef _WIN32 + TCHAR module_path[8192]; + GetModuleFileName(NULL, module_path, sizeof(module_path)/sizeof(module_path[0])); + TCHAR *sep2 = _tcsrchr(module_path, '\\'); + if (sep2) { + sep2[1] = '\0'; + dir = _tcsdup(module_path); + } +#endif + basename = _tcsdup(basename); + TCHAR *period = _tcschr(basename, '.'); + if (period) + *period = '\0'; + TCHAR *target = _tcsdup(basename); + TCHAR *dash = _tcsrchr(target, '-'); + const TCHAR *exe = basename; + if (dash) { + *dash = '\0'; + exe = dash + 1; + } else { + target = NULL; + } + + if (dir_ptr) + *dir_ptr = dir; + if (basename_ptr) + *basename_ptr = basename; + if (target_ptr) + *target_ptr = target; + if (exe_ptr) + *exe_ptr = exe; +} diff --git a/wrappers/windres-wrapper.c b/wrappers/windres-wrapper.c index dd07742..5869085 100644 --- a/wrappers/windres-wrapper.c +++ b/wrappers/windres-wrapper.c @@ -27,42 +27,17 @@ * For more information, please refer to */ -#ifdef UNICODE -#define _UNICODE -#endif +#include "native-wrapper.h" #ifndef DEFAULT_TARGET #define DEFAULT_TARGET "x86_64-w64-mingw32" #endif -#include -#include -#include #include #ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#include -#include #else -#include -typedef char TCHAR; -#define _T(x) x -#define _tcsrchr strrchr -#define _tcschr strchr -#define _tcsdup strdup -#define _tcscpy strcpy -#define _tcslen strlen -#define _tcscmp strcmp -#define _tcsncmp strncmp -#define _tperror perror -#define _texecvp execvp -#define _tmain main #define _tspawnvp _spawnvp -#define _ftprintf fprintf -#define _vftprintf vfprintf -#define _tunlink unlink #include #include @@ -85,52 +60,6 @@ static int _spawnvp(int mode, const char *filename, const char * const *argv) { } #endif -#ifdef _UNICODE -#define TS "%ls" -#else -#define TS "%s" -#endif - -static TCHAR *escape(const TCHAR *str) { -#ifdef _WIN32 - TCHAR *out = malloc((_tcslen(str) * 2 + 3) * sizeof(*out)); - TCHAR *ptr = out; - int i; - *ptr++ = '"'; - for (i = 0; str[i]; i++) { - if (str[i] == '"') { - int j = i - 1; - // Before all double quotes, backslashes need to be escaped, but - // not elsewhere. - while (j >= 0 && str[j--] == '\\') - *ptr++ = '\\'; - // Escape the next double quote. - *ptr++ = '\\'; - } - *ptr++ = str[i]; - } - // Any final backslashes, before the quote around the whole argument, - // need to be doubled. - int j = i - 1; - while (j >= 0 && str[j--] == '\\') - *ptr++ = '\\'; - *ptr++ = '"'; - *ptr++ = '\0'; - return out; -#else - return _tcsdup(str); -#endif -} - -static TCHAR *concat(const TCHAR *prefix, const TCHAR *suffix) { - int prefixlen = _tcslen(prefix); - int suffixlen = _tcslen(suffix); - TCHAR *buf = malloc((prefixlen + suffixlen + 1) * sizeof(*buf)); - _tcscpy(buf, prefix); - _tcscpy(buf + prefixlen, suffix); - return buf; -} - // GNU binutils windres seem to require an extra level of escaping of // -D options to the preprocessor, which we need to undo here. // For defines that produce quoted strings, this windres frontend is @@ -219,48 +148,13 @@ static void check_num_args(int arg, int max_arg) { } } -static TCHAR *_tcsrchrs(const TCHAR *str, TCHAR char1, TCHAR char2) { - TCHAR *ptr1 = _tcsrchr(str, char1); - TCHAR *ptr2 = _tcsrchr(str, char2); - if (!ptr1) - return ptr2; - if (!ptr2) - return ptr1; - if (ptr1 < ptr2) - return ptr2; - return ptr1; -} - int _tmain(int argc, TCHAR* argv[]) { - const TCHAR *argv0 = argv[0]; - const TCHAR *sep = _tcsrchrs(argv0, '/', '\\'); - TCHAR *dir = _tcsdup(_T("")); - const TCHAR *basename = argv0; - if (sep) { - dir = _tcsdup(argv0); - dir[sep + 1 - argv0] = '\0'; - basename = sep + 1; - } -#ifdef _WIN32 - TCHAR module_path[8192]; - GetModuleFileName(NULL, module_path, sizeof(module_path)/sizeof(module_path[0])); - TCHAR *sep2 = _tcsrchr(module_path, '\\'); - if (sep2) { - sep2[1] = '\0'; - dir = _tcsdup(module_path); - } -#endif - basename = _tcsdup(basename); - TCHAR *period = _tcschr(basename, '.'); - if (period) - *period = '\0'; - TCHAR *dash = _tcsrchr(basename, '-'); - const TCHAR *target = basename; - if (dash) { - *dash = '\0'; - } else { + const TCHAR *dir; + const TCHAR *basename; + const TCHAR *target; + split_argv(argv[0], &dir, &basename, &target, NULL); + if (!target) target = _T(DEFAULT_TARGET); - } const TCHAR *input = _T("-"); @@ -348,7 +242,7 @@ int _tmain(int argc, TCHAR* argv[]) { } TCHAR *arch = _tcsdup(target); - dash = _tcschr(arch, '-'); + TCHAR *dash = _tcschr(arch, '-'); if (dash) *dash = '\0';