[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