From: Slava Pestov Date: Mon, 18 Jan 2010 12:12:04 +0000 (-0600) Subject: Use ParseCommandLineArgvw() on Windows again, instead of hand-rolled parser. Update... X-Git-Tag: 0.97~5053^2~8 X-Git-Url: https://gitweb.factorcode.org/gitweb.cgi?p=factor.git;a=commitdiff_plain;h=d36b83d6a90e8d460cef9f21a9f306d496d55fc7 Use ParseCommandLineArgvw() on Windows again, instead of hand-rolled parser. Update Nmakefile to link in shell32.dll, where this function is defined --- diff --git a/Nmakefile b/Nmakefile index e9384fdff8..405cf331e8 100755 --- a/Nmakefile +++ b/Nmakefile @@ -1,4 +1,4 @@ -LINK_CLFAGS = /nologo +LINK_FLAGS = /nologo shell32.lib CL_FLAGS = /nologo /O2 /W3 EXE_OBJS = factor.dll.lib vm\main-windows-nt.obj vm\factor.res @@ -66,6 +66,7 @@ factor.exe: $(EXE_OBJS) clean: del vm\*.obj + del factor.lib del factor.com del factor.exe del factor.dll diff --git a/vm/main-windows-ce.cpp b/vm/main-windows-ce.cpp index e0b1d3b626..ed5844167a 100755 --- a/vm/main-windows-ce.cpp +++ b/vm/main-windows-ce.cpp @@ -1,5 +1,120 @@ #include "master.hpp" +/* + Windows argument parsing ported to work on + int main(int argc, wchar_t **argv). + + Based on MinGW's public domain char** version. +*/ + +VM_C_API int parse_tokens(wchar_t *string, wchar_t ***tokens, int length) +{ + /* Extract whitespace- and quotes- delimited tokens from the given string + and put them into the tokens array. Returns number of tokens + extracted. Length specifies the current size of tokens[]. + THIS METHOD MODIFIES string. */ + + const wchar_t *whitespace = L" \t\r\n"; + wchar_t *tokenEnd = 0; + const wchar_t *quoteCharacters = L"\"\'"; + wchar_t *end = string + wcslen(string); + + if (string == NULL) + return length; + + while (1) + { + const wchar_t *q; + /* Skip over initial whitespace. */ + string += wcsspn(string, whitespace); + if (*string == '\0') + break; + + for (q = quoteCharacters; *q; ++q) + { + if (*string == *q) + break; + } + if (*q) + { + /* Token is quoted. */ + wchar_t quote = *string++; + tokenEnd = wcschr(string, quote); + /* If there is no endquote, the token is the rest of the string. */ + if (!tokenEnd) + tokenEnd = end; + } + else + { + tokenEnd = string + wcscspn(string, whitespace); + } + + *tokenEnd = '\0'; + + { + wchar_t **new_tokens; + int newlen = length + 1; + new_tokens = (wchar_t **)realloc (*tokens, sizeof (wchar_t**) * newlen); + if (!new_tokens) + { + /* Out of memory. */ + return -1; + } + + *tokens = new_tokens; + (*tokens)[length] = string; + length = newlen; + } + if (tokenEnd == end) + break; + string = tokenEnd + 1; + } + return length; +} + +VM_C_API void parse_args(int *argc, wchar_t ***argv, wchar_t *cmdlinePtrW) +{ + int cmdlineLen = 0; + + if (!cmdlinePtrW) + cmdlineLen = 0; + else + cmdlineLen = wcslen(cmdlinePtrW); + + /* gets realloc()'d later */ + *argc = 0; + *argv = (wchar_t **)malloc (sizeof (wchar_t**)); + + if (!*argv) + ExitProcess(1); + +#ifdef WINCE + wchar_t cmdnameBufW[MAX_UNICODE_PATH]; + + /* argv[0] is the path of invoked program - get this from CE. */ + cmdnameBufW[0] = 0; + GetModuleFileNameW(NULL, cmdnameBufW, sizeof (cmdnameBufW)/sizeof (cmdnameBufW[0])); + + (*argv)[0] = wcsdup(cmdnameBufW); + if(!(*argv[0])) + ExitProcess(1); + /* Add one to account for argv[0] */ + (*argc)++; +#endif + + if (cmdlineLen > 0) + { + wchar_t *string = wcsdup(cmdlinePtrW); + if(!string) + ExitProcess(1); + *argc = parse_tokens(string, argv, *argc); + if (*argc < 0) + ExitProcess(1); + } + (*argv)[*argc] = 0; + return; +} + int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, diff --git a/vm/main-windows-nt.cpp b/vm/main-windows-nt.cpp index 4fced136e8..64e2cce54b 100755 --- a/vm/main-windows-nt.cpp +++ b/vm/main-windows-nt.cpp @@ -21,7 +21,7 @@ int WINAPI WinMain( int argc; wchar_t **argv; - factor::parse_args(&argc, &argv, (wchar_t *)GetCommandLine()); + argv = CommandLineToArgvW(GetCommandLine(),&argc); wmain(argc,argv); // memory leak from malloc, wcsdup diff --git a/vm/os-windows.cpp b/vm/os-windows.cpp index ab55beacdb..df2a57f2e8 100755 --- a/vm/os-windows.cpp +++ b/vm/os-windows.cpp @@ -137,123 +137,4 @@ long getpagesize() return g_pagesize; } -/* - Windows argument parsing ported to work on - int main(int argc, wchar_t **argv). - - Based on MinGW's public domain char** version. - - Used by WinMain() implementation in main-windows-ce.cpp - and main-windows-nt.cpp. - -*/ - -VM_C_API int parse_tokens(wchar_t *string, wchar_t ***tokens, int length) -{ - /* Extract whitespace- and quotes- delimited tokens from the given string - and put them into the tokens array. Returns number of tokens - extracted. Length specifies the current size of tokens[]. - THIS METHOD MODIFIES string. */ - - const wchar_t *whitespace = L" \t\r\n"; - wchar_t *tokenEnd = 0; - const wchar_t *quoteCharacters = L"\"\'"; - wchar_t *end = string + wcslen(string); - - if (string == NULL) - return length; - - while (1) - { - const wchar_t *q; - /* Skip over initial whitespace. */ - string += wcsspn(string, whitespace); - if (*string == '\0') - break; - - for (q = quoteCharacters; *q; ++q) - { - if (*string == *q) - break; - } - if (*q) - { - /* Token is quoted. */ - wchar_t quote = *string++; - tokenEnd = wcschr(string, quote); - /* If there is no endquote, the token is the rest of the string. */ - if (!tokenEnd) - tokenEnd = end; - } - else - { - tokenEnd = string + wcscspn(string, whitespace); - } - - *tokenEnd = '\0'; - - { - wchar_t **new_tokens; - int newlen = length + 1; - new_tokens = (wchar_t **)realloc (*tokens, sizeof (wchar_t**) * newlen); - if (!new_tokens) - { - /* Out of memory. */ - return -1; - } - - *tokens = new_tokens; - (*tokens)[length] = string; - length = newlen; - } - if (tokenEnd == end) - break; - string = tokenEnd + 1; - } - return length; -} - -VM_C_API void parse_args(int *argc, wchar_t ***argv, wchar_t *cmdlinePtrW) -{ - int cmdlineLen = 0; - - if (!cmdlinePtrW) - cmdlineLen = 0; - else - cmdlineLen = wcslen(cmdlinePtrW); - - /* gets realloc()'d later */ - *argc = 0; - *argv = (wchar_t **)malloc (sizeof (wchar_t**)); - - if (!*argv) - ExitProcess(1); - -#ifdef WINCE - wchar_t cmdnameBufW[MAX_UNICODE_PATH]; - - /* argv[0] is the path of invoked program - get this from CE. */ - cmdnameBufW[0] = 0; - GetModuleFileNameW(NULL, cmdnameBufW, sizeof (cmdnameBufW)/sizeof (cmdnameBufW[0])); - - (*argv)[0] = wcsdup(cmdnameBufW); - if(!(*argv[0])) - ExitProcess(1); - /* Add one to account for argv[0] */ - (*argc)++; -#endif - - if (cmdlineLen > 0) - { - wchar_t *argv1 = wcsdup(cmdlinePtrW); - if(!argv1) - ExitProcess(1); - *argc = parse_tokens(argv1, argv, *argc); - if (*argc < 0) - ExitProcess(1); - } - (*argv)[*argc] = 0; - return; -} - } diff --git a/vm/os-windows.hpp b/vm/os-windows.hpp index 13db2035bc..8a2dfe38f5 100755 --- a/vm/os-windows.hpp +++ b/vm/os-windows.hpp @@ -51,8 +51,4 @@ u64 nano_count(); void sleep_nanos(u64 nsec); long getpagesize(); -/* Used by-main-windows-*.cpp */ -VM_C_API int parse_tokens(wchar_t* string, wchar_t*** tokens, int length); -VM_C_API void parse_args(int *argc, wchar_t ***argv, wchar_t *cmdlinePtrW); - }