From: Hartmut Birr Date: Wed, 23 Nov 2005 21:14:06 +0000 (+0000) Subject: - Implemented wgetmainargs. X-Git-Tag: backups/ros-branch-0_2_9@19949~427 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=ec55f4fec0b16a4868b8e22a7ce75b9008f35fd9 - Implemented wgetmainargs. - Fixed the allocating of argv if a empty cmd line is given. - Fixed the allocating of pgmptr. svn path=/trunk/; revision=19501 --- diff --git a/reactos/lib/crt/misc/environ.c b/reactos/lib/crt/misc/environ.c index 07ec5c99eb3..409b38bf8cc 100644 --- a/reactos/lib/crt/misc/environ.c +++ b/reactos/lib/crt/misc/environ.c @@ -31,6 +31,8 @@ char **__initenv = NULL; /* pointer to initial environment block */ wchar_t **__winitenv = NULL; /* pointer to initial environment block */ #undef _pgmptr char *_pgmptr = NULL; /* pointer to program name */ +#undef _wpgmptr +wchar_t *_wpgmptr = NULL; /* pointer to program name */ int __app_type = 0; //_UNKNOWN_APP; /* application type */ int __mb_cur_max = 1; @@ -271,8 +273,7 @@ int SetEnv(const wchar_t *option) * the environments are in sync and the option is at the * same position. */ free(_environ[index]); - for (; _environ[index] != NULL; index++) - _environ[index] = _environ[index + 1]; + memmove(&_environ[index], &_environ[index+1], (count - index) * sizeof(char*)); _environ = realloc(_environ, count * sizeof(char*)); result = SetEnvironmentVariableW(name, NULL) ? 0 : -1; @@ -372,6 +373,14 @@ char **__p__acmdln(void) return &_acmdln; } +/* + * @implemented + */ +wchar_t **__p__wcmdln(void) +{ + return &_wcmdln; +} + /* * @implemented */ @@ -428,6 +437,14 @@ char **__p__pgmptr(void) return &_pgmptr; } +/* + * @implemented + */ +wchar_t **__p__wpgmptr(void) +{ + return &_wpgmptr; +} + /* * @implemented */ diff --git a/reactos/lib/crt/misc/getargs.c b/reactos/lib/crt/misc/getargs.c index 7cc1622af06..52e0502b342 100644 --- a/reactos/lib/crt/misc/getargs.c +++ b/reactos/lib/crt/misc/getargs.c @@ -4,7 +4,11 @@ extern char*_acmdln; +extern wchar_t* _wcmdln; +#undef _pgmptr extern char*_pgmptr; +#undef _wpgmptr +extern wchar_t*_wpgmptr; #undef _environ extern char**_environ; @@ -31,10 +35,85 @@ char* strndup(char* name, int len) return s; } +wchar_t* wcsndup(wchar_t* name, int len) +{ + wchar_t *s = malloc((len + 1) * sizeof(wchar_t)); + if (s != NULL) + { + memcpy(s, name, len*sizeof(wchar_t)); + s[len] = 0; + } + return s; +} + #define SIZE (4096 / sizeof(char*)) -int add - (char* name) +int wadd(wchar_t* name) +{ + wchar_t** _new; + if ((__argc % SIZE) == 0) + { + if (__wargv == NULL) + _new = malloc(sizeof(wchar_t*) * (1 + SIZE)); + else + _new = realloc(__wargv, sizeof(wchar_t*) * (__argc + 1 + SIZE)); + if (_new == NULL) + return -1; + __wargv = _new; + } + __wargv[__argc++] = name; + __wargv[__argc] = NULL; + return 0; +} + +int wexpand(wchar_t* name, int expand_wildcards) +{ + wchar_t* s; + WIN32_FIND_DATAW fd; + HANDLE hFile; + BOOLEAN first = TRUE; + wchar_t buffer[256]; + int pos; + + if (expand_wildcards && (s = wcspbrk(name, L"*?"))) + { + hFile = FindFirstFileW(name, &fd); + if (hFile != INVALID_HANDLE_VALUE) + { + while(s != name && *s != L'/' && *s != L'\\') + s--; + pos = s - name; + if (*s == L'/' || *s == L'\\') + pos++; + wcsncpy(buffer, name, pos); + do + { + if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + wcscpy(&buffer[pos], fd.cFileName); + if (wadd(_wcsdup(buffer)) < 0) + { + FindClose(hFile); + return -1; + } + first = FALSE; + } + } + while(FindNextFileW(hFile, &fd)); + FindClose(hFile); + } + } + if (first) + { + if (wadd(name) < 0) + return -1; + } + else + free(name); + return 0; +} + +int aadd(char* name) { char** _new; if ((__argc % SIZE) == 0) @@ -52,7 +131,7 @@ int add return 0; } -int expand(char* name, int expand_wildcards) +int aexpand(char* name, int expand_wildcards) { char* s; WIN32_FIND_DATAA fd; @@ -77,8 +156,7 @@ int expand(char* name, int expand_wildcards) if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { strcpy(&buffer[pos], fd.cFileName); - if (add - (_strdup(buffer)) < 0) + if (aadd(_strdup(buffer)) < 0) { FindClose(hFile); return -1; @@ -92,8 +170,7 @@ int expand(char* name, int expand_wildcards) } if (first) { - if (add - (name) < 0) + if (aadd(name) < 0) return -1; } else @@ -137,7 +214,7 @@ void __getmainargs(int* argc, char*** argv, char*** env, int expand_wildcards, i if (_acmdln[i] == ' ' && !ignorespace) { - expand(strndup(_acmdln + afterlastspace, i - afterlastspace), doexpand); + aexpand(strndup(_acmdln + afterlastspace, i - afterlastspace), doexpand); i++; while (_acmdln[i]==' ') i++; @@ -152,15 +229,20 @@ void __getmainargs(int* argc, char*** argv, char*** env, int expand_wildcards, i if (_acmdln[afterlastspace] != 0) { - expand(strndup(_acmdln+afterlastspace, i - afterlastspace), doexpand); + aexpand(strndup(_acmdln+afterlastspace, i - afterlastspace), doexpand); } HeapValidate(hHeap, 0, NULL); *argc = __argc; + if (__argv == NULL) + { + __argv = (char**)malloc(sizeof(char*)); + __argv[0] = 0; + } *argv = __argv; *env = _environ; - _pgmptr = _strdup((char*)argv[0]); + _pgmptr = _strdup(__argv[0]); // if (new_mode) _set_new_mode(*new_mode); } @@ -171,9 +253,66 @@ void __getmainargs(int* argc, char*** argv, char*** env, int expand_wildcards, i void __wgetmainargs(int* argc, wchar_t*** wargv, wchar_t*** wenv, int expand_wildcards, int* new_mode) { + int i, afterlastspace, ignorespace, len, doexpand; + + /* missing threading init */ + + i = 0; + afterlastspace = 0; + ignorespace = 0; + doexpand = expand_wildcards; + + len = wcslen(_wcmdln); + + while (_wcmdln[i]) + { + if (_wcmdln[i] == L'"') + { + if(ignorespace) + { + ignorespace = 0; + } + else + { + ignorespace = 1; + doexpand = 0; + } + memmove(_wcmdln + i, _wcmdln + i + 1, (len - i) * sizeof(wchar_t)); + len--; + continue; + } + + if (_wcmdln[i] == L' ' && !ignorespace) + { + wexpand(wcsndup(_wcmdln + afterlastspace, i - afterlastspace), doexpand); + i++; + while (_wcmdln[i]==L' ') + i++; + afterlastspace=i; + doexpand = expand_wildcards; + } + else + { + i++; + } + } + + if (_wcmdln[afterlastspace] != 0) + { + wexpand(wcsndup(_wcmdln+afterlastspace, i - afterlastspace), doexpand); + } + + HeapValidate(hHeap, 0, NULL); + *argc = __argc; + if (__wargv == NULL) + { + __wargv = (wchar_t**)malloc(sizeof(wchar_t*)); + __wargv[0] = 0; + } *wargv = __wargv; *wenv = __winitenv; + _wpgmptr = _wcsdup(__wargv[0]); // if (new_mode) _set_new_mode(*new_mode); } diff --git a/reactos/lib/msvcrt/dllmain.c b/reactos/lib/msvcrt/dllmain.c index 4a837a1e67c..bae034d040e 100644 --- a/reactos/lib/msvcrt/dllmain.c +++ b/reactos/lib/msvcrt/dllmain.c @@ -90,7 +90,7 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) if (BlockEnvToEnvironW() < 0) { - FreeEnvironment((char**)_wenviron); + FreeEnvironment(_environ); return FALSE; } diff --git a/reactos/lib/msvcrt/msvcrt.def b/reactos/lib/msvcrt/msvcrt.def index c5577289281..08f1ca9ebfd 100644 --- a/reactos/lib/msvcrt/msvcrt.def +++ b/reactos/lib/msvcrt/msvcrt.def @@ -147,12 +147,12 @@ __p__pgmptr __p__pwctype __p__timezone __p__tzname=stub -__p__wcmdln=stub +__p__wcmdln __p__wenviron __p__winmajor __p__winminor __p__winver -__p__wpgmptr=stub +__p__wpgmptr __pioinfo __pxcptinfoptrs __set_app_type @@ -561,7 +561,7 @@ _waccess _wasctime _wchdir _wchmod -_wcmdln +_wcmdln DATA _wcreat _wcsdup _wcserror=stub