mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Escape arguments to platform linker/compiler. (#1358)
* Escape arguments to platform linker/compiler.
This commit is contained in:
committed by
GitHub
parent
2a69f93605
commit
85c682f7e6
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"provides" : "clib",
|
||||
"c-sources" : ["hello2.c"],
|
||||
"c-sources" : ["hello2.c", "whitespace test.c"],
|
||||
"targets" : {
|
||||
"macos-x64" : {
|
||||
},
|
||||
|
||||
1
resources/testproject/lib/clib.c3l/whitespace test.c
Normal file
1
resources/testproject/lib/clib.c3l/whitespace test.c
Normal file
@@ -0,0 +1 @@
|
||||
#include <stdio.h>
|
||||
@@ -36,17 +36,6 @@ static const char *ld_target(ArchType arch_type)
|
||||
}
|
||||
|
||||
}
|
||||
static const char *string_esc(const char *str)
|
||||
{
|
||||
scratch_buffer_clear();
|
||||
size_t len = strlen(str);
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
if (i > 3 && !char_is_alphanum_(str[i])) scratch_buffer_append_char('\\');
|
||||
scratch_buffer_append_char(str[i]);
|
||||
}
|
||||
return strdup(scratch_buffer_to_string());
|
||||
}
|
||||
|
||||
static void linker_setup_windows(const char ***args_ref, Linker linker_type)
|
||||
{
|
||||
@@ -673,22 +662,20 @@ bool obj_format_linking_supported(ObjectFormatType format_type)
|
||||
|
||||
const char *concat_string_parts(const char **args)
|
||||
{
|
||||
unsigned size_needed = 0;
|
||||
scratch_buffer_clear();
|
||||
FOREACH(const char *, arg, args)
|
||||
{
|
||||
size_needed += strlen(arg) + 1;
|
||||
assert(arg != scratch_buffer.str && "Incorrectly passed a scratch buffer string as an argument.");
|
||||
if (PLATFORM_WINDOWS && arg == *args)
|
||||
{
|
||||
scratch_buffer_append(arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
scratch_buffer_append_argument(arg);
|
||||
}
|
||||
}
|
||||
char *output = malloc_string(size_needed);
|
||||
char *ptr = output;
|
||||
FOREACH(const char *, arg, args)
|
||||
{
|
||||
unsigned len = (unsigned)strlen(arg);
|
||||
memcpy(ptr, arg, len);
|
||||
ptr += len;
|
||||
*(ptr++) = ' ';
|
||||
}
|
||||
ptr[-1] = '\0';
|
||||
return output;
|
||||
return scratch_buffer_copy();
|
||||
}
|
||||
|
||||
|
||||
@@ -780,7 +767,7 @@ const char *cc_compiler(const char *cc, const char *file, const char *flags, con
|
||||
|
||||
FOREACH(const char *, include_dir, include_dirs)
|
||||
{
|
||||
vec_add(parts, str_printf(is_cl_exe ? "/I\"%s\"" : "-I\"%s\"", include_dir));
|
||||
vec_add(parts, str_printf(is_cl_exe ? "/I%s" : "-I%s", include_dir));
|
||||
}
|
||||
|
||||
const bool pie_set =
|
||||
@@ -799,7 +786,7 @@ const char *cc_compiler(const char *cc, const char *file, const char *flags, con
|
||||
vec_add(parts, file);
|
||||
if (is_cl_exe)
|
||||
{
|
||||
vec_add(parts, str_printf("/Fo:\"%s\"", out_name));
|
||||
vec_add(parts, str_printf("/Fo:%s", out_name));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -154,10 +154,12 @@ void slice_trim(StringSlice *slice);
|
||||
|
||||
void scratch_buffer_clear(void);
|
||||
void scratch_buffer_append(const char *string);
|
||||
UNUSED char *scratch_buffer_get_quoted(const char *string);
|
||||
UNUSED void scratch_buffer_append_quoted(const char *string);
|
||||
void scratch_buffer_append_argument(const char *string);
|
||||
void scratch_buffer_append_double_quoted(const char *string);
|
||||
void scratch_buffer_append_shell_escaped(const char *string);
|
||||
void scratch_buffer_append_len(const char *string, size_t len);
|
||||
void scratch_buffer_append_char(char c);
|
||||
void scratch_buffer_append_char_repeat(char c, size_t count);
|
||||
void scratch_buffer_append_signed_int(int64_t i);
|
||||
void scratch_buffer_append_double(double d);
|
||||
UNUSED void scratch_buffer_append_unsigned_int(uint64_t i);
|
||||
|
||||
@@ -320,37 +320,99 @@ void scratch_buffer_append_len(const char *string, size_t len)
|
||||
scratch_buffer.len += (uint32_t)len;
|
||||
}
|
||||
|
||||
char *scratch_buffer_get_quoted(const char *string)
|
||||
{
|
||||
scratch_buffer_clear();
|
||||
scratch_buffer_append_quoted(string);
|
||||
return scratch_buffer_to_string();
|
||||
}
|
||||
|
||||
void scratch_buffer_append_quoted(const char *string)
|
||||
#if PLATFORM_WINDOWS
|
||||
static bool contains_whitespace_or_quotes(const char *string)
|
||||
{
|
||||
char c;
|
||||
while ((c = string++[0]) != '\0')
|
||||
while ((c = *string++) != '\0')
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '"':
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void scratch_buffer_append_argument(const char *string)
|
||||
{
|
||||
if (scratch_buffer.len != 0) scratch_buffer_append_char(' ');
|
||||
#if PLATFORM_WINDOWS
|
||||
if (contains_whitespace_or_quotes(string))
|
||||
{
|
||||
scratch_buffer_append_double_quoted(string);
|
||||
}
|
||||
else
|
||||
{
|
||||
scratch_buffer_append(string);
|
||||
}
|
||||
#else
|
||||
scratch_buffer_append_shell_escaped(string);
|
||||
#endif
|
||||
}
|
||||
|
||||
void scratch_buffer_append_double_quoted(const char *string)
|
||||
{
|
||||
scratch_buffer_append_char('"');
|
||||
size_t len = strlen(string);
|
||||
for (size_t i = 0; i < len; )
|
||||
{
|
||||
char c = string[i++];
|
||||
switch (c)
|
||||
{
|
||||
case '"':
|
||||
scratch_buffer_append("\\\"");
|
||||
continue;
|
||||
case '\\':
|
||||
scratch_buffer_append("\\\\");
|
||||
{
|
||||
int backslash_count = 1;
|
||||
for (; i < len && string[i] == '\\'; i++, backslash_count++) {}
|
||||
if (i == len || string[i] == '"')
|
||||
{
|
||||
scratch_buffer_append_char_repeat('\\', backslash_count * 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
scratch_buffer_append_char_repeat('\\', backslash_count);
|
||||
}
|
||||
continue;
|
||||
case '\n':
|
||||
scratch_buffer_append("\\n");
|
||||
continue;
|
||||
case '\'':
|
||||
scratch_buffer_append("\\'");
|
||||
continue;
|
||||
default:
|
||||
scratch_buffer_append_char(c);
|
||||
continue;
|
||||
|
||||
}
|
||||
}
|
||||
scratch_buffer_append_char(c);
|
||||
}
|
||||
scratch_buffer_append_char('"');
|
||||
}
|
||||
|
||||
void scratch_buffer_append_shell_escaped(const char *string)
|
||||
{
|
||||
char c;
|
||||
while ((c = string++[0]) != '\0')
|
||||
{
|
||||
if ((unsigned)c < 0x80)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case LOWER_CHAR_CASE:
|
||||
case UPPER_CHAR_CASE:
|
||||
case NUMBER_CHAR_CASE:
|
||||
case '_':
|
||||
case '/':
|
||||
case '.':
|
||||
case ',':
|
||||
case '-':
|
||||
break;
|
||||
default:
|
||||
scratch_buffer_append_char('\\');
|
||||
break;
|
||||
}
|
||||
}
|
||||
scratch_buffer_append_char(c);
|
||||
}
|
||||
}
|
||||
void scratch_buffer_append(const char *string)
|
||||
@@ -407,6 +469,14 @@ void scratch_buffer_append_char(char c)
|
||||
scratch_buffer.str[scratch_buffer.len++] = c;
|
||||
}
|
||||
|
||||
void scratch_buffer_append_char_repeat(char c, size_t count)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
scratch_buffer_append_char(c);
|
||||
}
|
||||
}
|
||||
|
||||
char *scratch_buffer_to_string(void)
|
||||
{
|
||||
scratch_buffer.str[scratch_buffer.len] = '\0';
|
||||
|
||||
Reference in New Issue
Block a user