[PATCH resend 1/2] winedbg: Adapt build_command_line() from winevdm

Robbert van der Helm mail at robbertvanderhelm.nl
Fri Nov 5 09:09:10 CDT 2021


The only difference between the two versions is that this one doesn't prefix the result with the
command line's length.

Signed-off-by: Robbert van der Helm <mail at robbertvanderhelm.nl>
---
Instead of having having four almost identical copies of this function spread around Wine's code
base (two for WCHAR*, two for char*), someone who's more familiar with Wine's code base than I am
should probably merge these and move them to somewhere in `include/wine/`.
---
 programs/winedbg/tgt_active.c | 110 ++++++++++++++++++++++++++++++++++
 1 file changed, 110 insertions(+)

diff --git a/programs/winedbg/tgt_active.c b/programs/winedbg/tgt_active.c
index 3372a001dfbb..ad46d6b5fc5e 100644
--- a/programs/winedbg/tgt_active.c
+++ b/programs/winedbg/tgt_active.c
@@ -770,6 +770,116 @@ static void output_system_info(void)
     }
 }
 
+/***********************************************************************
+ *           build_command_line
+ *
+ * Build the command line of a process from the argv array.
+ * Copied from winevdm, which in turn adapted it from ENV_BuildCommandLine. The difference between
+ * this and the winevdm version is the command line is not prefixed with its length.
+ */
+static char *build_command_line(char **argv)
+{
+    int len;
+    char *p, **arg, *cmd_line;
+
+    len = 0;
+    for (arg = argv; *arg; arg++)
+    {
+        BOOL has_space;
+        int bcount;
+        char* a;
+
+        has_space=FALSE;
+        bcount=0;
+        a=*arg;
+        if( !*a ) has_space=TRUE;
+        while (*a!='\0') {
+            if (*a=='\\') {
+                bcount++;
+            } else {
+                if (*a==' ' || *a=='\t') {
+                    has_space=TRUE;
+                } else if (*a=='"') {
+                    /* doubling of '\' preceding a '"',
+                     * plus escaping of said '"'
+                     */
+                    len+=2*bcount+1;
+                }
+                bcount=0;
+            }
+            a++;
+        }
+        len+=(a-*arg)+1 /* for the separating space */;
+        if (has_space)
+            len+=2; /* for the quotes */
+    }
+
+    if (!(cmd_line = HeapAlloc( GetProcessHeap(), 0, len ? len : 1 )))
+        return NULL;
+
+    p = cmd_line;
+    for (arg = argv; *arg; arg++)
+    {
+        BOOL has_space,has_quote;
+        char* a;
+
+        /* Check for quotes and spaces in this argument */
+        has_space=has_quote=FALSE;
+        a=*arg;
+        if( !*a ) has_space=TRUE;
+        while (*a!='\0') {
+            if (*a==' ' || *a=='\t') {
+                has_space=TRUE;
+                if (has_quote)
+                    break;
+            } else if (*a=='"') {
+                has_quote=TRUE;
+                if (has_space)
+                    break;
+            }
+            a++;
+        }
+
+        /* Now transfer it to the command line */
+        if (has_space)
+            *p++='"';
+        if (has_quote) {
+            int bcount;
+
+            bcount=0;
+            a=*arg;
+            while (*a!='\0') {
+                if (*a=='\\') {
+                    *p++=*a;
+                    bcount++;
+                } else {
+                    if (*a=='"') {
+                        int i;
+
+                        /* Double all the '\\' preceding this '"', plus one */
+                        for (i=0;i<=bcount;i++)
+                            *p++='\\';
+                        *p++='"';
+                    } else {
+                        *p++=*a;
+                    }
+                    bcount=0;
+                }
+                a++;
+            }
+        } else {
+            strcpy(p,*arg);
+            p+=strlen(*arg);
+        }
+        if (has_space)
+            *p++='"';
+        *p++=' ';
+    }
+    if (len) p--;  /* remove last space */
+    *p = '\0';
+    return cmd_line;
+}
+
 /******************************************************************
  *		dbg_active_attach
  *
-- 
2.33.1





More information about the wine-devel mailing list