- Implemented wgetmainargs.
authorHartmut Birr <osexpert@googlemail.com>
Wed, 23 Nov 2005 21:14:06 +0000 (21:14 +0000)
committerHartmut Birr <osexpert@googlemail.com>
Wed, 23 Nov 2005 21:14:06 +0000 (21:14 +0000)
- Fixed the allocating of argv if a empty cmd line is given.
- Fixed the allocating of pgmptr.

svn path=/trunk/; revision=19501

reactos/lib/crt/misc/environ.c
reactos/lib/crt/misc/getargs.c
reactos/lib/msvcrt/dllmain.c
reactos/lib/msvcrt/msvcrt.def

index 07ec5c9..409b38b 100644 (file)
@@ -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
  */
index 7cc1622..52e0502 100644 (file)
@@ -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);
 }
index 4a837a1..bae034d 100644 (file)
@@ -90,7 +90,7 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved)
 
         if (BlockEnvToEnvironW() < 0)
         {
-            FreeEnvironment((char**)_wenviron);
+            FreeEnvironment(_environ);
             return FALSE;
         }
 
index c557728..08f1ca9 100644 (file)
@@ -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