History

w32: improve quoting when spawning cross-compiler

The previous code had few issues: - Didn't quote an empty string. - Didn't quote if the string contains tabs. - Didn't take into account existing backslashes at the string. E.g. previously broken (in POSIX sh, like cygwin or busybox-w32): - tcc -m 32 test.c -D 'CSTR="foo'$'\t''bar"' (wrongly rejected by tcc). - tcc -m 32 test.c -D 'CSTR="foo\"bar"' (incorrect CSTR at test.c). Both issues are fixed with the new code, and presumably any others. The empty/tabs issues could be fixed within the current code, but the backslashes issue is not worth shoehorning it, so this is a rewrite.

Avi Halachmi (:avih) committed 1 year ago

Commit 1cf33fe1 parent a6ef3181 file · +31 −14Browse files

Unified · Split

tcctools.c+31−14
@@ -497,21 +497,38 @@ ST_FUNC int tcc_tool_cross(TCCState *s1, char **argv, int option) · 496 unmodified lines
497#ifdef _WIN32497#ifdef _WIN32
498#include <process.h>498#include <process.h>
499 499
500/* quote quotes in string and quote string if it contains spaces */500/* - Empty argument or with space/tab (not newline) requires quoting.
501static char *quote_win32(const char *s0)501 * - Double-quotes at the value require '\'-escape, retardless of quoting.
502 * - Consecutive (or 1) backslashes at the value all need '\'-escape only if
503 * followed by [escaped] double quote, else taken literally, e.g. <x\\y\>
504 * remains literal without quoting or esc, but <x\\"y\> becomes <x\\\\\"y\>.
505 * - This "before double quote" rule applies also before delimiting quoting,
506 * e.g. <x\y \"z\> becomes <"x\y \\\"z\\"> (quoting required because space).
507 *
508 * https://learn.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments
509 */
510static char *quote_win32(const char *s)
502{511{
503 const char *s;512 char *o, *r = tcc_malloc(2 * strlen(s) + 3); /* max-esc, quotes, \0 */
504 char *p, *q;513 int cbs = 0, quoted = !*s; /* consecutive backslashes before current */
505 int a = 0, b = 0, c;514
506 for (s = s0; !!(c = *s); ++s)515 for (o = r; *s; *o++ = *s++) {
507 a += c == '"', b |= c == ' ';516 quoted |= *s == ' ' || *s == '\t';
508 q = p = tcc_malloc(s - s0 + a + b + b + 1);517 if (*s == '\\' || *s == '"')
509 *q = '"', q += b;518 *o++ = '\\';
510 for (s = s0; !!(c = *s); *q++ = c, ++s)519 else
511 if (c == '"')520 o -= cbs; /* undo cbs escpaes, if any (not followed by DQ) */
512 *q++ = '\\';521 cbs = *s == '\\' ? cbs + 1 : 0;
513 *q = '"', q += b, *q = '\0';522 }
514 return p;523 if (quoted) {
524 memmove(r + 1, r, o++ - r);
525 *r = *o++ = '"';
526 } else {
527 o -= cbs;
528 }
529
530 *o = 0;
531 return r; /* don't bother with realloc(r, o-r+1) */
515}532}
516 533
517static int execvp_win32(const char *prog, char **argv)534static int execvp_win32(const char *prog, char **argv)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t