[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