Use ParseCommandLineArgvw() on Windows again, instead of hand-rolled parser. Update Nmakefile to link in shell32.dll, where this function is defined

db4
Slava Pestov 2010-01-18 06:12:04 -06:00
parent c2bdb133d6
commit d36b83d6a9
5 changed files with 118 additions and 125 deletions

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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;
}
}

View File

@ -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);
}