From 4b41030cacaa775bb44f52dae2d4d7d89e10664e Mon Sep 17 00:00:00 2001 From: "Avi Halachmi (:avih)" Date: Wed, 19 Jun 2019 18:02:40 +0300 Subject: [PATCH] test 104: simplify, parametrize, more robust on windows Previously test 104 used a combination of *nix tools and `system()` API, which generally works but can cause all sort of issues on windows due to required path conversions. Additionally, it used a hardcoded tcc binary path. Now the tools are used from a shell script which is generated and executed by the program, paths are relative such that no conversion is required, and the tcc binary path is taken from the environment (exported by the Makefile). FIXME: while better than before, it's still rather awkward. The correct way is probably as follows: - 104_inline_test.c should only contain what's currently at cFileContent - The makefile should do what the built-in script currently does, and compare the output of that. --- tests/tests2/104_inline_test.c | 119 +++++++++++++-------------------- tests/tests2/Makefile | 3 + 2 files changed, 51 insertions(+), 71 deletions(-) diff --git a/tests/tests2/104_inline_test.c b/tests/tests2/104_inline_test.c index cb288d2..1cab4ec 100644 --- a/tests/tests2/104_inline_test.c +++ b/tests/tests2/104_inline_test.c @@ -1,83 +1,60 @@ #include #include -#include #include -#if __linux__ || __APPLE__ -#define SYS_WHICH_NM "which nm >/dev/null 2>&1" -#define TCC_COMPILER "../../tcc" -#define SYS_AWK +/* + * requires the following in PATH: sh, touch, cat, nm, gawk, sort. + * we use CWD for temp files at main() and at the shell script because: + * - mktemp (shell) is non standard, mkstemps (API) is unavailable on windows. + * - we choose temp names which don't require quoting in shell or C strings. + * - a relative path with forward slashes is identical on *nix/windows + * (FILE APIs, shell, tcc CLI arguments), but absolute path on windows will + * require conversions between shell/API/CLI representations. + */ +#define SCRIPT_PATH "./tmp-tcc104.sh" +#define TMP1 "./tmp-tcc104.1" +#define TMP2 "./tmp-tcc104.2" -char c[]="/tmp/tcc-XXXXXX"; char o[]="/tmp/tcc-XXXXXX"; -static int mktempfile(char *buf) +int main(int argc, char **argv) { - return mkstemps(buf,0); -} -#elif defined(_WIN32) -#define SYS_WHICH_NM "which nm >nul 2>&1" - -#if defined(_WIN64) -#define TCC_COMPILER "..\\..\\win32\\x86_64-win32-tcc" -#else -#define TCC_COMPILER "..\\..\\win32\\i386-win32-tcc" -#endif - -char c[1024]; char o[1024]; -static int mktempfile(char *buf) -{ - /* - * WARNING, this simplified 'mktemp' like function - * create two temporary Windows files having always - * the same name. It is enought for tcc test suite. - */ - if (buf == c) { - sprintf(c, "%s\\tcc-temp1", getenv("LOCALAPPDATA")); - } else { - sprintf(o, "%s\\tcc-temp2", getenv("LOCALAPPDATA")); - } -} -#endif - -void rmh(int Sig) -{ - remove(c); - remove(o); - signal(Sig,SIG_DFL); - raise(Sig); -} -int str2file(char const *fnm, char const *str) -{ - FILE *f; - if(0==(f=fopen(fnm,"w"))) return -1; - if(0>fputs(str,f)) return -1; - if(0>fclose(f)) return -1; - return 0; -} -int main(int C, char **V) -{ - int r=0; - if (system(SYS_WHICH_NM)){ return 0; } - signal(SIGINT,SIG_IGN); - signal(SIGTERM,SIG_IGN); - if(0>mktempfile(c)) return perror("mkstemps"),1; - if(0>mktempfile(o)){ - if(0>remove(c)) perror("remove"); - return perror("mkstemps"),1; - } - signal(SIGINT,rmh); - signal(SIGTERM,rmh); extern char const cfileContents[]; - if(0>str2file(c, cfileContents)) { perror("write");r=1;goto out;} - char buf[1024]; - sprintf(buf, "%s -c -xc %s -o %s", V[1]?V[1]:TCC_COMPILER, c, o); if(0!=system(buf)){ r=1;goto out;} - sprintf(buf, "nm -Ptx %s > %s", o, c); if(system(buf)) {r=1;goto out;} - sprintf(buf, "gawk '{ if($2 == \"T\") print $1 }' %s > %s", c, o); if(system(buf)) {r=1;goto out;} - sprintf(buf, "sort %s", o); if(system(buf)) {r=1;goto out;} -out: - remove(c); - remove(o); + const char *tcc; + FILE *f; + int r; + + /* TESTED_TCC is bin + args, should stay unquoted */ + if (!(tcc = argc > 1 ? argv[1] : getenv("TESTED_TCC"))) + return perror("unknown tcc executable"), 1; + + if (!(f = fopen(SCRIPT_PATH, "wb"))) + return perror("cannot create script"), 1; + fprintf(f, + "set -e\n" + "LC_ALL=C; export LC_ALL\n" + + "tmp1=%s; touch $tmp1\n" + "tmp2=%s; touch $tmp2\n" + + "cat <<\\CFILE > $tmp1\n" + "%s\n" + "CFILE\n" + + "%s -c -xc $tmp1 -o $tmp2\n" + "nm -Ptx $tmp2 > $tmp1\n" + "gawk '{ if($2 == \"T\") print $1 }' $tmp1 > $tmp2\n" + "sort $tmp2\n" + , + TMP1, TMP2, cfileContents, tcc); + fclose(f); + + r = system("sh " SCRIPT_PATH); + remove(TMP1); + remove(TMP2); + remove(SCRIPT_PATH); + return r; } + char const cfileContents[]= "inline void inline_inline_2decl_only(void);\n" "inline void inline_inline_2decl_only(void);\n" diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile index a5789c9..4ea55bf 100644 --- a/tests/tests2/Makefile +++ b/tests/tests2/Makefile @@ -3,6 +3,9 @@ include $(TOP)/Makefile SRC = $(TOPSRC)/tests/tests2 VPATH = $(SRC) +# used by 104_inline_test.c +export TESTED_TCC = $(TCC) + TESTS = $(patsubst %.c,%.test,\ $(sort $(notdir $(wildcard $(SRC)/??_*.c)))\ $(sort $(notdir $(wildcard $(SRC)/???_*.c)))) -- 2.22.0