[Wine-devel] Eter's patch is applied to winehq repo 04/10/13

builder-robot на etersoft.ru builder-robot на etersoft.ru
Ср Апр 10 23:20:33 MSK 2013


New Etersoft's patches since last build time:
commit c7d2b1d5ccd9d2c1df317e03ea4ae35941c169a8
Author: Sergey Guralnik <serhio на etersoft.ru>

    extrac32: Use own parser for command line.

---

commit c7d2b1d5ccd9d2c1df317e03ea4ae35941c169a8
Author: Sergey Guralnik <serhio на etersoft.ru>
Date:   Tue Apr 9 14:15:01 2013 +0300

    extrac32: Use own parser for command line.

diff --git a/programs/extrac32/extrac32.c b/programs/extrac32/extrac32.c
index addd732..111d2a7 100644
--- a/programs/extrac32/extrac32.c
+++ b/programs/extrac32/extrac32.c
@@ -82,6 +82,98 @@ static void copy_file(LPCWSTR source, LPCWSTR destination)
     CopyFileW(source, destination, FALSE);
 }
 
+static LPWSTR *get_extrac_args(LPWSTR cmdline, int *pargc)
+{
+    enum {OUTSIDE_ARG, INSIDE_ARG, INSIDE_QUOTED_ARG} state;
+    LPWSTR str;
+    int argc;
+    LPWSTR *argv;
+    int max_argc = 16;
+    BOOL new_arg;
+
+    WINE_TRACE("cmdline: %s\n", wine_dbgstr_w(cmdline));
+    str = HeapAlloc(GetProcessHeap(), 0, (strlenW(cmdline) + 1) * sizeof(WCHAR));
+    if(!str) return NULL;
+    strcpyW(str, cmdline);
+    argv = HeapAlloc(GetProcessHeap(), 0, (max_argc + 1) * sizeof(LPWSTR));
+    if(!argv)
+    {
+        HeapFree(GetProcessHeap(), 0, str);
+        return NULL;
+    }
+
+    /* Split command line to separate arg-strings and fill argv */
+    state = OUTSIDE_ARG;
+    argc = 0;
+    while(*str)
+    {
+        new_arg = FALSE;
+        /* Check character */
+        if(isspaceW(*str))          /* white space */
+        {
+            if(state == INSIDE_ARG)
+            {
+                state = OUTSIDE_ARG;
+                *str = 0;
+            }
+        }
+        else if(*str == '"')        /* double quote */
+            switch(state)
+            {
+                case INSIDE_QUOTED_ARG:
+                    state = OUTSIDE_ARG;
+                    *str = 0;
+                    break;
+                case INSIDE_ARG:
+                    *str = 0;
+                    /* Fall through */
+                case OUTSIDE_ARG:
+                    if(!*++str) continue;
+                    state = INSIDE_QUOTED_ARG;
+                    new_arg = TRUE;
+                    break;
+            }
+        else                        /* regular character */
+            if(state == OUTSIDE_ARG)
+            {
+                state = INSIDE_ARG;
+                new_arg = TRUE;
+            }
+
+        /* Add new argv entry, if need */
+        if(new_arg)
+        {
+            if(argc >= max_argc - 1)
+            {
+                /* Realloc argv here because there always should be
+                   at least one reserved cell for terminating NULL */
+                max_argc *= 2;
+                argv = HeapReAlloc(GetProcessHeap(), 0, argv,
+                        (max_argc + 1) * sizeof(LPWSTR));
+                if(!argv)
+                {
+                    HeapFree(GetProcessHeap(), 0, str);
+                    return NULL;
+                }
+            }
+            argv[argc++] = str;
+        }
+
+        str++;
+    }
+
+    argv[argc] = NULL;
+    *pargc = argc;
+
+    if(TRACE_ON(extrac32))
+    {
+        int i;
+        for(i = 0; i < argc; i++)
+            WINE_TRACE("arg %d: %s\n", i, wine_dbgstr_w(argv[i]));
+    }
+    return argv;
+}
+
 int PASCAL wWinMain(HINSTANCE hInstance, HINSTANCE prev, LPWSTR cmdline, int show)
 {
     LPWSTR *argv;
@@ -93,11 +185,17 @@ int PASCAL wWinMain(HINSTANCE hInstance, HINSTANCE prev, LPWSTR cmdline, int sho
     LPCWSTR cabfile = NULL;
 
     path[0] = 0;
-    argv = CommandLineToArgvW(cmdline, &argc);
+
+    /* Do not use CommandLineToArgvW() or __wgetmainargs() to parse
+     * command line for this program. It should treat each quote as argument
+     * delimiter. This doesn't match with behavior of mentioned functions.
+     * Do not use args provided by wmain() for the same reason.
+     */
+    argv = get_extrac_args(cmdline, &argc);
 
     if(!argv)
     {
-        WINE_ERR("Bad command line arguments\n");
+        WINE_ERR("Command line parsing failed\n");
         return 0;
     }
 


Подробная информация о списке рассылки Wine-devel