forked from ariadne/pkgconf
msvc: handle quoting correctly for cmd.exe
parent
5d6c9ba98c
commit
7cce958d78
|
@ -19,17 +19,18 @@
|
||||||
#include <libpkgconf/libpkgconf.h>
|
#include <libpkgconf/libpkgconf.h>
|
||||||
#include "renderer-msvc.h"
|
#include "renderer-msvc.h"
|
||||||
|
|
||||||
static inline char *
|
static inline bool
|
||||||
fragment_escape(const char *src)
|
fragment_should_quote(const pkgconf_fragment_t *frag)
|
||||||
{
|
{
|
||||||
ssize_t outlen = strlen(src) + 10;
|
const char *src;
|
||||||
char *out = calloc(outlen, 1);
|
|
||||||
char *dst = out;
|
|
||||||
|
|
||||||
while (*src)
|
if (frag->data == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (src = frag->data; *src; src++)
|
||||||
{
|
{
|
||||||
if (((*src < ' ') ||
|
if (((*src < ' ') ||
|
||||||
(*src > ' ' && *src < '$') ||
|
(*src >= (' ' + (frag->merged ? 1 : 0)) && *src < '$') ||
|
||||||
(*src > '$' && *src < '(') ||
|
(*src > '$' && *src < '(') ||
|
||||||
(*src > ')' && *src < '+') ||
|
(*src > ')' && *src < '+') ||
|
||||||
(*src > ':' && *src < '=') ||
|
(*src > ':' && *src < '=') ||
|
||||||
|
@ -37,34 +38,27 @@ fragment_escape(const char *src)
|
||||||
(*src > 'Z' && *src < '^') ||
|
(*src > 'Z' && *src < '^') ||
|
||||||
(*src == '`') ||
|
(*src == '`') ||
|
||||||
(*src > 'z' && *src < '~') ||
|
(*src > 'z' && *src < '~') ||
|
||||||
(*src > '~')) && *src != '\\')
|
(*src > '~')))
|
||||||
*dst++ = '\\';
|
return true;
|
||||||
|
|
||||||
*dst++ = *src++;
|
|
||||||
|
|
||||||
if ((ptrdiff_t)(dst - out) + 2 > outlen)
|
|
||||||
{
|
|
||||||
outlen *= 2;
|
|
||||||
out = realloc(out, outlen);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*dst = 0;
|
return false;
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t
|
static inline size_t
|
||||||
fragment_len(const pkgconf_fragment_t *frag, bool escape)
|
fragment_len(const pkgconf_fragment_t *frag)
|
||||||
{
|
{
|
||||||
size_t len = 1;
|
size_t len = 1;
|
||||||
|
|
||||||
if (!escape)
|
if (frag->type)
|
||||||
len += strlen(frag->data);
|
len += 2;
|
||||||
else
|
|
||||||
|
if (frag->data != NULL)
|
||||||
{
|
{
|
||||||
char *tmp = fragment_escape(frag->data);
|
len += strlen(frag->data);
|
||||||
len += strlen(tmp);
|
|
||||||
free(tmp);
|
if (fragment_should_quote(frag))
|
||||||
|
len += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
|
@ -79,6 +73,8 @@ allowed_fragment(const pkgconf_fragment_t *frag)
|
||||||
static size_t
|
static size_t
|
||||||
msvc_renderer_render_len(const pkgconf_list_t *list, bool escape)
|
msvc_renderer_render_len(const pkgconf_list_t *list, bool escape)
|
||||||
{
|
{
|
||||||
|
(void) escape;
|
||||||
|
|
||||||
size_t out = 1; /* trailing nul */
|
size_t out = 1; /* trailing nul */
|
||||||
pkgconf_node_t *node;
|
pkgconf_node_t *node;
|
||||||
|
|
||||||
|
@ -101,7 +97,7 @@ msvc_renderer_render_len(const pkgconf_list_t *list, bool escape)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out += fragment_len(frag, escape);
|
out += fragment_len(frag);
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
@ -119,11 +115,12 @@ msvc_renderer_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, b
|
||||||
{
|
{
|
||||||
const pkgconf_fragment_t *frag = node->data;
|
const pkgconf_fragment_t *frag = node->data;
|
||||||
size_t buf_remaining = buflen - (bptr - buf);
|
size_t buf_remaining = buflen - (bptr - buf);
|
||||||
|
size_t cnt;
|
||||||
|
|
||||||
if (!allowed_fragment(frag))
|
if (!allowed_fragment(frag))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (fragment_len(frag, escape) > buf_remaining)
|
if (fragment_len(frag) > buf_remaining)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (frag->type == 'L')
|
if (frag->type == 'L')
|
||||||
|
@ -133,21 +130,14 @@ msvc_renderer_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, b
|
||||||
buf_remaining -= cnt;
|
buf_remaining -= cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!escape)
|
escape = fragment_should_quote(frag);
|
||||||
{
|
|
||||||
size_t cnt = pkgconf_strlcpy(bptr, frag->data, buf_remaining);
|
|
||||||
bptr += cnt;
|
|
||||||
buf_remaining -= cnt;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char *tmp = fragment_escape(frag->data);
|
|
||||||
size_t cnt = pkgconf_strlcpy(bptr, tmp, buf_remaining);
|
|
||||||
free(tmp);
|
|
||||||
|
|
||||||
bptr += cnt;
|
if (escape)
|
||||||
buf_remaining -= cnt;
|
*bptr++ = '"';
|
||||||
}
|
|
||||||
|
cnt = pkgconf_strlcpy(bptr, frag->data, buf_remaining);
|
||||||
|
bptr += cnt;
|
||||||
|
buf_remaining -= cnt;
|
||||||
|
|
||||||
if (frag->type == 'l')
|
if (frag->type == 'l')
|
||||||
{
|
{
|
||||||
|
@ -156,6 +146,9 @@ msvc_renderer_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, b
|
||||||
buf_remaining -= cnt;
|
buf_remaining -= cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (escape)
|
||||||
|
*bptr++ = '"';
|
||||||
|
|
||||||
*bptr++ = ' ';
|
*bptr++ = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,3 +2,4 @@ Name: fragment-escaping-1
|
||||||
Version: 0
|
Version: 0
|
||||||
Description: fragment escaping test
|
Description: fragment escaping test
|
||||||
Cflags: "-IC:\\D E"
|
Cflags: "-IC:\\D E"
|
||||||
|
Libs: "-LC:\\D E" -lE
|
||||||
|
|
|
@ -27,7 +27,8 @@ tests_init \
|
||||||
fragment_quoting_2 \
|
fragment_quoting_2 \
|
||||||
fragment_quoting_3 \
|
fragment_quoting_3 \
|
||||||
fragment_quoting_5 \
|
fragment_quoting_5 \
|
||||||
fragment_quoting_7
|
fragment_quoting_7 \
|
||||||
|
msvc_fragment_quoting
|
||||||
|
|
||||||
comments_body()
|
comments_body()
|
||||||
{
|
{
|
||||||
|
@ -248,3 +249,11 @@ fragment_quoting_7a_body()
|
||||||
|
|
||||||
set +x
|
set +x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msvc_fragment_quoting_body()
|
||||||
|
{
|
||||||
|
export PKG_CONFIG_PATH="${selfdir}/lib1"
|
||||||
|
atf_check \
|
||||||
|
-o inline:'/libpath:"C:\D E" E.lib \n' \
|
||||||
|
pkgconf --libs --msvc-syntax fragment-escaping-1
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue