From 3abe78d4e59c075273860ea3682bf7b4499617e2 Mon Sep 17 00:00:00 2001 From: Ray Donnelly Date: Fri, 14 Mar 2014 13:18:13 +0000 Subject: GCC 4.6-4.8: Only quote arguments in pex-win32.c that need it. .. it always quoted all arguments, irrespective of whether there was a need to. This means the 32k limit is getting hit more often than it needs to. --- gcc-4.6/libiberty/pex-win32.c | 47 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) (limited to 'gcc-4.6') diff --git a/gcc-4.6/libiberty/pex-win32.c b/gcc-4.6/libiberty/pex-win32.c index 442740674..47dda1bb7 100644 --- a/gcc-4.6/libiberty/pex-win32.c +++ b/gcc-4.6/libiberty/pex-win32.c @@ -343,17 +343,26 @@ argv_to_cmdline (char *const *argv) char *p; size_t cmdline_len; int i, j, k; + int needs_quotes; cmdline_len = 0; for (i = 0; argv[i]; i++) { - /* We quote every last argument. This simplifies the problem; - we need only escape embedded double-quotes and immediately + /* We only quote arguments that contain spaces, \n \t \v or " characters + to prevent wasting 2 chars per argument of the CreateProcess 32k char limit + We need only escape embedded double-quotes and immediately preceeding backslash characters. A sequence of backslach characters that is not follwed by a double quote character will not be escaped. */ + needs_quotes = 0; for (j = 0; argv[i][j]; j++) { + if (argv[i][j] == ' ' || argv[i][j] == '\n' || + argv[i][j] == '\t' || argv[i][j] == '"' ) + { + needs_quotes = 1; + } + if (argv[i][j] == '"') { /* Escape preceeding backslashes. */ @@ -365,16 +374,33 @@ argv_to_cmdline (char *const *argv) } /* Trailing backslashes also need to be escaped because they will be followed by the terminating quote. */ - for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--) - cmdline_len++; + if (needs_quotes) + { + for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--) + cmdline_len++; + } cmdline_len += j; - cmdline_len += 3; /* for leading and trailing quotes and space */ + cmdline_len += 1 + (needs_quotes<<1); /* for leading and trailing quotes and space */ } cmdline = XNEWVEC (char, cmdline_len); p = cmdline; for (i = 0; argv[i]; i++) { - *p++ = '"'; + needs_quotes = 0; + for (j = 0; argv[i][j]; j++) + { + if (argv[i][j] == ' ' || argv[i][j] == '\n' || + argv[i][j] == '\t' || argv[i][j] == '"' ) + { + needs_quotes = 1; + break; + } + } + + if (needs_quotes) + { + *p++ = '"'; + } for (j = 0; argv[i][j]; j++) { if (argv[i][j] == '"') @@ -385,9 +411,12 @@ argv_to_cmdline (char *const *argv) } *p++ = argv[i][j]; } - for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--) - *p++ = '\\'; - *p++ = '"'; + if (needs_quotes) + { + for (k = j - 1; k >= 0 && argv[i][k] == '\\'; k--) + *p++ = '\\'; + *p++ = '"'; + } *p++ = ' '; } p[-1] = '\0'; -- cgit v1.2.3