mirror of
git://repo.or.cz/tinycc.git
synced 2026-06-30 00:28:42 +08:00
win32: fix nested -run argv and exit callbacks
This commit is contained in:
parent
d349980ef4
commit
d683afdead
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -169,6 +169,8 @@ jobs:
|
|||||||
powershell -NoProfile -Command "$before = @(Get-ChildItem -Path $env:TEMP -Filter 'tcc*.tmp' -Name -ErrorAction SilentlyContinue); & .\tcc -B. -run ..\win32\test_run_exit.c; if ($LASTEXITCODE -ne 27) { exit 1 }; $after = @(Get-ChildItem -Path $env:TEMP -Filter 'tcc*.tmp' -Name -ErrorAction SilentlyContinue); if (Compare-Object $before $after) { Write-Host 'Temporary -run file cleanup mismatch'; Compare-Object $before $after; exit 1 }"
|
powershell -NoProfile -Command "$before = @(Get-ChildItem -Path $env:TEMP -Filter 'tcc*.tmp' -Name -ErrorAction SilentlyContinue); & .\tcc -B. -run ..\win32\test_run_exit.c; if ($LASTEXITCODE -ne 27) { exit 1 }; $after = @(Get-ChildItem -Path $env:TEMP -Filter 'tcc*.tmp' -Name -ErrorAction SilentlyContinue); if (Compare-Object $before $after) { Write-Host 'Temporary -run file cleanup mismatch'; Compare-Object $before $after; exit 1 }"
|
||||||
.\tcc -B. ..\win32\test_arm64.c -o test_arm64.exe && .\test_arm64.exe
|
.\tcc -B. ..\win32\test_arm64.c -o test_arm64.exe && .\test_arm64.exe
|
||||||
.\tcc -B. -run ..\examples\ex1.c
|
.\tcc -B. -run ..\examples\ex1.c
|
||||||
|
.\tcc -B. -run ..\tcc.c -B. -run ..\tcc.c -B. -run ..\examples\ex1.c > test_nested_run.out
|
||||||
|
findstr /x /c:"Hello World" test_nested_run.out
|
||||||
clang -O0 -I.. ..\win32\test_arm64_libtcc_context.c ..\win32\test_arm64_libtcc_context.S -o test_libtcc_context.exe
|
clang -O0 -I.. ..\win32\test_arm64_libtcc_context.c ..\win32\test_arm64_libtcc_context.S -o test_libtcc_context.exe
|
||||||
.\test_libtcc_context.exe
|
.\test_libtcc_context.exe
|
||||||
.\tcc -B. ..\win32\test_arm64_inline_asm.c -o test_inline_asm.exe && .\test_inline_asm.exe > test_inline_asm.out
|
.\tcc -B. ..\win32\test_arm64_inline_asm.c -o test_inline_asm.exe && .\test_inline_asm.exe > test_inline_asm.out
|
||||||
|
|||||||
2
tcc.c
2
tcc.c
@ -330,7 +330,9 @@ redo:
|
|||||||
argc = argc0, argv = argv0;
|
argc = argc0, argv = argv0;
|
||||||
s = s1 = tcc_new();
|
s = s1 = tcc_new();
|
||||||
opt = tcc_parse_args(s, &argc, &argv);
|
opt = tcc_parse_args(s, &argc, &argv);
|
||||||
|
#ifdef TCC_IS_NATIVE
|
||||||
s->run_arg_start = (int)(argv - argv0);
|
s->run_arg_start = (int)(argv - argv0);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|||||||
@ -48,9 +48,7 @@ __attribute__((weak)) char **__cdecl __rt_get_environ(void);
|
|||||||
#endif
|
#endif
|
||||||
__attribute__((weak)) int __cdecl __rt_get_run_argstart(void);
|
__attribute__((weak)) int __cdecl __rt_get_run_argstart(void);
|
||||||
|
|
||||||
void __tcc_run_on_exit(int ret);
|
__attribute__((weak)) void __run_on_exit(int ret);
|
||||||
int __tcc_on_exit(void *function, void *arg);
|
|
||||||
int __tcc_atexit(void (*function)(void));
|
|
||||||
void __attribute__((noreturn)) __tcc_exit(int code);
|
void __attribute__((noreturn)) __tcc_exit(int code);
|
||||||
|
|
||||||
#include "crtinit.c"
|
#include "crtinit.c"
|
||||||
@ -235,6 +233,28 @@ static wchar_t *dup_run_wstr(const wchar_t *s)
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static wchar_t *dup_run_wstr_from_tchar(const _TCHAR *s)
|
||||||
|
{
|
||||||
|
#ifdef UNICODE
|
||||||
|
return dup_run_wstr(s);
|
||||||
|
#else
|
||||||
|
size_t len;
|
||||||
|
wchar_t *copy;
|
||||||
|
|
||||||
|
len = mbstowcs(NULL, s, 0);
|
||||||
|
if ((size_t)-1 == len)
|
||||||
|
return NULL;
|
||||||
|
copy = malloc(sizeof(*copy) * (len + 1));
|
||||||
|
if (!copy)
|
||||||
|
return NULL;
|
||||||
|
if ((size_t)-1 == mbstowcs(copy, s, len + 1)) {
|
||||||
|
free(copy);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return copy;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void free_run_wargv(wchar_t **argv)
|
static void free_run_wargv(wchar_t **argv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -327,6 +347,39 @@ done:
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static wchar_t **build_run_wargv_from_targv(int src_argc, _TCHAR **src_argv, int base, int *prun_argc)
|
||||||
|
{
|
||||||
|
wchar_t **run_argv = NULL;
|
||||||
|
int run_argc = 0, i;
|
||||||
|
|
||||||
|
if (base < 0 || base >= src_argc)
|
||||||
|
return NULL;
|
||||||
|
for (i = base; i < src_argc; ++i) {
|
||||||
|
wchar_t *copy;
|
||||||
|
|
||||||
|
if (!src_argv[i])
|
||||||
|
continue;
|
||||||
|
copy = dup_run_wstr_from_tchar(src_argv[i]);
|
||||||
|
if (!copy)
|
||||||
|
goto fail;
|
||||||
|
if (_dowildcard && i > base && run_has_wildcard(copy)) {
|
||||||
|
if (run_expand_wildcard_arg(copy, &run_argv, &run_argc)) {
|
||||||
|
free(copy);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!append_run_warg(&run_argv, &run_argc, copy)) {
|
||||||
|
free(copy);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*prun_argc = run_argc;
|
||||||
|
return run_argv;
|
||||||
|
fail:
|
||||||
|
free_run_wargv(run_argv);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static wchar_t **build_run_wargv(int *prun_argc)
|
static wchar_t **build_run_wargv(int *prun_argc)
|
||||||
{
|
{
|
||||||
wchar_t **cmd_argv = NULL, **run_argv = NULL;
|
wchar_t **cmd_argv = NULL, **run_argv = NULL;
|
||||||
@ -337,6 +390,16 @@ static wchar_t **build_run_wargv(int *prun_argc)
|
|||||||
base = __rt_get_run_argstart();
|
base = __rt_get_run_argstart();
|
||||||
if (base < 0)
|
if (base < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
/* The active CRT argv slice is process-wide and already reflects the
|
||||||
|
current host `tcc -run ...` context, including nested runs. Reuse it
|
||||||
|
first so nested `-run tcc.c ... -run ...` keeps advancing through the
|
||||||
|
current slice instead of restarting from the original process command
|
||||||
|
line. */
|
||||||
|
run_argv = build_run_wargv_from_targv(__argc, __targv, base, &run_argc);
|
||||||
|
if (run_argv) {
|
||||||
|
*prun_argc = run_argc;
|
||||||
|
return run_argv;
|
||||||
|
}
|
||||||
cmd_argv = run_command_line_to_argv_w(&cmd_argc);
|
cmd_argv = run_command_line_to_argv_w(&cmd_argc);
|
||||||
if (!cmd_argv || base >= cmd_argc)
|
if (!cmd_argv || base >= cmd_argc)
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -439,7 +502,7 @@ int _runtmain(int argc, /* as tcc passed in */ char **argv)
|
|||||||
if (!argv_state.run_argv)
|
if (!argv_state.run_argv)
|
||||||
return 1;
|
return 1;
|
||||||
run_targv_tls = &argv_state;
|
run_targv_tls = &argv_state;
|
||||||
if (__tcc_atexit(restore_run_targv_atexit))
|
if (atexit(restore_run_targv_atexit))
|
||||||
goto fail;
|
goto fail;
|
||||||
__argc = run_argc;
|
__argc = run_argc;
|
||||||
__targv = argv_state.run_argv;
|
__targv = argv_state.run_argv;
|
||||||
@ -451,7 +514,8 @@ int _runtmain(int argc, /* as tcc passed in */ char **argv)
|
|||||||
run_ctors(__argc, __targv, env);
|
run_ctors(__argc, __targv, env);
|
||||||
ret = _tmain(__argc, __targv, env);
|
ret = _tmain(__argc, __targv, env);
|
||||||
run_dtors();
|
run_dtors();
|
||||||
__tcc_run_on_exit(ret);
|
if (__run_on_exit)
|
||||||
|
__run_on_exit(ret);
|
||||||
return ret;
|
return ret;
|
||||||
fail:
|
fail:
|
||||||
run_targv_tls = NULL;
|
run_targv_tls = NULL;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user