winmain: Don't use SDL_malloc (or SDL_stack_alloc, which might be malloc).

Otherwise, we are using the allocator before the app can set up its own hooks.

Now we use VirtualAlloc, and WideCharToMultiByte (because SDL_iconv uses
SDL_malloc, too!) to get ready to call into SDL_main.

This also makes console_wmain() call into the same routines as everything
else, so we don't have to deal with those allocations, too. Hopefully we
end up with the same results from GetCommandLine() as we do in wargv.

Fixes Bugzilla #4340.
This commit is contained in:
Ryan C. Gordon 2018-10-29 20:00:03 -04:00
parent b43f427fa6
commit f434a98c26
1 changed files with 41 additions and 40 deletions

View File

@ -116,50 +116,65 @@ OutOfMemory(void)
# endif # endif
#endif #endif
/* WinMain, main, and wmain eventually call into here. */
static int
main_utf8(int argc, char *argv[])
{
SDL_SetMainReady();
/* Run the application main() code */
return SDL_main(argc, argv);
}
/* Gets the arguments with GetCommandLine, converts them to argc and argv /* Gets the arguments with GetCommandLine, converts them to argc and argv
and calls main_utf8 */ and calls SDL_main */
static int static int
main_getcmdline() main_getcmdline()
{ {
char **argv; char **argv;
int argc; int argc;
char *cmdline; char *cmdline = NULL;
int retval = 0; int retval = 0;
int cmdalloc = 0;
const TCHAR *text = GetCommandLine();
const TCHAR *ptr;
int argc_guess = 2; /* space for NULL and initial argument. */
int rc;
/* make a rough guess of command line arguments. Overestimates if there
are quoted things. */
for (ptr = text; *ptr; ptr++) {
if ((*ptr == ' ') || (*ptr == '\t')) {
argc_guess++;
}
}
/* Grab the command line */
TCHAR *text = GetCommandLine();
#if UNICODE #if UNICODE
cmdline = WIN_StringToUTF8(text); rc = WideCharToMultiByte(CP_UTF8, 0, text, -1, NULL, 0, NULL, NULL);
if (rc > 0) {
cmdalloc = rc + (sizeof (char *) * argc_guess);
argv = (char **) VirtualAlloc(NULL, cmdalloc, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
if (argv) {
cmdline = (char *) (argv + argc_guess);
const int rc2 = WideCharToMultiByte(CP_UTF8, 0, text, -1, cmdline, rc, NULL, NULL);
SDL_assert(rc2 == rc);
}
}
#else #else
/* !!! FIXME: are these in the system codepage? We need to convert to UTF-8. */ /* !!! FIXME: are these in the system codepage? We need to convert to UTF-8. */
cmdline = SDL_strdup(text); rc = ((int) SDL_strlen(text)) + 1;
cmdalloc = rc + (sizeof (char *) * argc_guess);
argv = (char **) VirtualAlloc(NULL, cmdalloc, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
if (argv) {
cmdline = (char *) (argv + argc_guess);
SDL_strcpy(cmdline, text);
}
#endif #endif
if (cmdline == NULL) { if (cmdline == NULL) {
return OutOfMemory(); return OutOfMemory();
} }
/* Parse it into argv and argc */ /* Parse it into argv and argc */
argc = ParseCommandLine(cmdline, NULL); SDL_assert(ParseCommandLine(cmdline, NULL) <= argc_guess);
argv = SDL_stack_alloc(char *, argc + 1); argc = ParseCommandLine(cmdline, argv);
if (argv == NULL) {
return OutOfMemory();
}
ParseCommandLine(cmdline, argv);
retval = main_utf8(argc, argv); SDL_SetMainReady();
SDL_stack_free(argv); /* Run the application main() code */
SDL_free(cmdline); retval = SDL_main(argc, argv);
VirtualFree(argv, cmdalloc, MEM_DECOMMIT);
VirtualFree(argv, 0, MEM_RELEASE);
return retval; return retval;
} }
@ -177,21 +192,7 @@ console_ansi_main(int argc, char *argv[])
int int
console_wmain(int argc, wchar_t *wargv[], wchar_t *wenvp) console_wmain(int argc, wchar_t *wargv[], wchar_t *wenvp)
{ {
int retval = 0; return main_getcmdline();
char **argv = SDL_stack_alloc(char*, argc + 1);
int i;
for (i = 0; i < argc; ++i) {
argv[i] = WIN_StringToUTF8(wargv[i]);
}
argv[argc] = NULL;
retval = main_utf8(argc, argv);
/* !!! FIXME: we are leaking all the elements of argv we allocated. */
SDL_stack_free(argv);
return retval;
} }
#endif #endif