main: implement a MSVC renderer (only some fragments supported) (closes #161)
parent
19d91e90e5
commit
0b09c111ed
|
@ -98,7 +98,7 @@ ADD_SUBDIRECTORY(libpkgconf)
|
||||||
#-------- Build and install executable --------
|
#-------- Build and install executable --------
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(${libpkgconf_BINARY_DIR})
|
INCLUDE_DIRECTORIES(${libpkgconf_BINARY_DIR})
|
||||||
ADD_EXECUTABLE(pkgconf main.c getopt_long.c)
|
ADD_EXECUTABLE(pkgconf main.c getopt_long.c renderer-msvc.c)
|
||||||
TARGET_LINK_LIBRARIES(pkgconf libpkgconf)
|
TARGET_LINK_LIBRARIES(pkgconf libpkgconf)
|
||||||
INSTALL(TARGETS pkgconf DESTINATION bin)
|
INSTALL(TARGETS pkgconf DESTINATION bin)
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ dist_man_MANS = \
|
||||||
man/pkg.m4.7
|
man/pkg.m4.7
|
||||||
|
|
||||||
pkgconf_LDADD = libpkgconf.la
|
pkgconf_LDADD = libpkgconf.la
|
||||||
pkgconf_SOURCES = main.c getopt_long.c
|
pkgconf_SOURCES = main.c getopt_long.c renderer-msvc.c
|
||||||
pkgconf_CPPFLAGS = -Ilibpkgconf
|
pkgconf_CPPFLAGS = -Ilibpkgconf
|
||||||
noinst_HEADERS = getopt_long.h
|
noinst_HEADERS = getopt_long.h
|
||||||
|
|
||||||
|
|
7
main.c
7
main.c
|
@ -18,6 +18,7 @@
|
||||||
#include <libpkgconf/libpkgconf.h>
|
#include <libpkgconf/libpkgconf.h>
|
||||||
#include "libpkgconf/config.h"
|
#include "libpkgconf/config.h"
|
||||||
#include "getopt_long.h"
|
#include "getopt_long.h"
|
||||||
|
#include "renderer-msvc.h"
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <io.h> /* for _setmode() */
|
#include <io.h> /* for _setmode() */
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -63,6 +64,7 @@
|
||||||
#define PKG_DEBUG (((uint64_t) 1) << 38)
|
#define PKG_DEBUG (((uint64_t) 1) << 38)
|
||||||
#define PKG_SHORT_ERRORS (((uint64_t) 1) << 39)
|
#define PKG_SHORT_ERRORS (((uint64_t) 1) << 39)
|
||||||
#define PKG_EXISTS (((uint64_t) 1) << 40)
|
#define PKG_EXISTS (((uint64_t) 1) << 40)
|
||||||
|
#define PKG_MSVC_SYNTAX (((uint64_t) 1) << 41)
|
||||||
|
|
||||||
static pkgconf_client_t pkg_client;
|
static pkgconf_client_t pkg_client;
|
||||||
static const pkgconf_fragment_render_ops_t *want_render_ops = NULL;
|
static const pkgconf_fragment_render_ops_t *want_render_ops = NULL;
|
||||||
|
@ -683,6 +685,7 @@ usage(void)
|
||||||
printf(" --keep-system-libs keep -L%s entries in libs output\n", SYSTEM_LIBDIR);
|
printf(" --keep-system-libs keep -L%s entries in libs output\n", SYSTEM_LIBDIR);
|
||||||
printf(" --path show the exact filenames for any matching .pc files\n");
|
printf(" --path show the exact filenames for any matching .pc files\n");
|
||||||
printf(" --modversion print the specified module's version to stdout\n");
|
printf(" --modversion print the specified module's version to stdout\n");
|
||||||
|
printf(" --msvc-syntax print translatable fragments in MSVC syntax\n");
|
||||||
|
|
||||||
printf("\nreport bugs to <%s>.\n", PACKAGE_BUGREPORT);
|
printf("\nreport bugs to <%s>.\n", PACKAGE_BUGREPORT);
|
||||||
}
|
}
|
||||||
|
@ -779,6 +782,7 @@ main(int argc, char *argv[])
|
||||||
{ "dont-define-prefix", no_argument, &want_flags, PKG_DONT_DEFINE_PREFIX },
|
{ "dont-define-prefix", no_argument, &want_flags, PKG_DONT_DEFINE_PREFIX },
|
||||||
{ "dont-relocate-paths", no_argument, &want_flags, PKG_DONT_RELOCATE_PATHS },
|
{ "dont-relocate-paths", no_argument, &want_flags, PKG_DONT_RELOCATE_PATHS },
|
||||||
{ "env", required_argument, NULL, 48 },
|
{ "env", required_argument, NULL, 48 },
|
||||||
|
{ "msvc-syntax", no_argument, &want_flags, PKG_MSVC_SYNTAX },
|
||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -839,6 +843,9 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((want_flags & PKG_MSVC_SYNTAX) == PKG_MSVC_SYNTAX)
|
||||||
|
want_render_ops = msvc_renderer_get();
|
||||||
|
|
||||||
if ((env_traverse_depth = getenv("PKG_CONFIG_MAXIMUM_TRAVERSE_DEPTH")) != NULL)
|
if ((env_traverse_depth = getenv("PKG_CONFIG_MAXIMUM_TRAVERSE_DEPTH")) != NULL)
|
||||||
maximum_traverse_depth = atoi(env_traverse_depth);
|
maximum_traverse_depth = atoi(env_traverse_depth);
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ libpkgconf = shared_library('pkgconf',
|
||||||
pkgconf_exe = executable('pkgconf',
|
pkgconf_exe = executable('pkgconf',
|
||||||
'main.c',
|
'main.c',
|
||||||
'getopt_long.c',
|
'getopt_long.c',
|
||||||
|
'renderer-msvc.c',
|
||||||
link_with : libpkgconf,
|
link_with : libpkgconf,
|
||||||
install : true)
|
install : true)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,174 @@
|
||||||
|
/*
|
||||||
|
* renderer-msvc.c
|
||||||
|
* MSVC library syntax renderer
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 pkgconf authors (see AUTHORS).
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <libpkgconf/libpkgconf.h>
|
||||||
|
#include "renderer-msvc.h"
|
||||||
|
|
||||||
|
static inline char *
|
||||||
|
fragment_escape(const char *src)
|
||||||
|
{
|
||||||
|
ssize_t outlen = strlen(src) + 10;
|
||||||
|
char *out = calloc(outlen, 1);
|
||||||
|
char *dst = out;
|
||||||
|
|
||||||
|
while (*src)
|
||||||
|
{
|
||||||
|
if (((*src < ' ') ||
|
||||||
|
(*src > ' ' && *src < '$') ||
|
||||||
|
(*src > '$' && *src < '(') ||
|
||||||
|
(*src > ')' && *src < '+') ||
|
||||||
|
(*src > ':' && *src < '=') ||
|
||||||
|
(*src > '=' && *src < '@') ||
|
||||||
|
(*src > 'Z' && *src < '^') ||
|
||||||
|
(*src == '`') ||
|
||||||
|
(*src > 'z' && *src < '~') ||
|
||||||
|
(*src > '~')) && *src != '\\')
|
||||||
|
*dst++ = '\\';
|
||||||
|
|
||||||
|
*dst++ = *src++;
|
||||||
|
|
||||||
|
if ((ptrdiff_t)(dst - out) + 2 > outlen)
|
||||||
|
{
|
||||||
|
outlen *= 2;
|
||||||
|
out = realloc(out, outlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*dst = 0;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t
|
||||||
|
fragment_len(const pkgconf_fragment_t *frag, bool escape)
|
||||||
|
{
|
||||||
|
size_t len = 1;
|
||||||
|
|
||||||
|
if (!escape)
|
||||||
|
len += strlen(frag->data);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *tmp = fragment_escape(frag->data);
|
||||||
|
len += strlen(tmp);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
allowed_fragment(const pkgconf_fragment_t *frag)
|
||||||
|
{
|
||||||
|
return !(!frag->type || frag->data == NULL || strchr("Ll", frag->type) == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
msvc_renderer_render_len(const pkgconf_list_t *list, bool escape)
|
||||||
|
{
|
||||||
|
size_t out = 1; /* trailing nul */
|
||||||
|
pkgconf_node_t *node;
|
||||||
|
|
||||||
|
PKGCONF_FOREACH_LIST_ENTRY(list->head, node)
|
||||||
|
{
|
||||||
|
const pkgconf_fragment_t *frag = node->data;
|
||||||
|
|
||||||
|
if (!allowed_fragment(frag))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (frag->type)
|
||||||
|
{
|
||||||
|
case 'L':
|
||||||
|
out += 9; /* "/libpath:" */
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
out += 4; /* ".lib" */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out += fragment_len(frag, escape);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
msvc_renderer_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, bool escape)
|
||||||
|
{
|
||||||
|
pkgconf_node_t *node;
|
||||||
|
char *bptr = buf;
|
||||||
|
|
||||||
|
memset(buf, 0, buflen);
|
||||||
|
|
||||||
|
PKGCONF_FOREACH_LIST_ENTRY(list->head, node)
|
||||||
|
{
|
||||||
|
const pkgconf_fragment_t *frag = node->data;
|
||||||
|
size_t buf_remaining = buflen - (bptr - buf);
|
||||||
|
|
||||||
|
if (!allowed_fragment(frag))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (fragment_len(frag, escape) > buf_remaining)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (frag->type == 'L')
|
||||||
|
{
|
||||||
|
size_t cnt = pkgconf_strlcpy(bptr, "/libpath:", buf_remaining);
|
||||||
|
bptr += cnt;
|
||||||
|
buf_remaining -= cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!escape)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
buf_remaining -= cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frag->type == 'l')
|
||||||
|
{
|
||||||
|
size_t cnt = pkgconf_strlcpy(bptr, ".lib", buf_remaining);
|
||||||
|
bptr += cnt;
|
||||||
|
buf_remaining -= cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
*bptr++ = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
*bptr = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static const pkgconf_fragment_render_ops_t msvc_renderer_ops = {
|
||||||
|
.render_len = msvc_renderer_render_len,
|
||||||
|
.render_buf = msvc_renderer_render_buf
|
||||||
|
};
|
||||||
|
|
||||||
|
const pkgconf_fragment_render_ops_t *
|
||||||
|
msvc_renderer_get(void)
|
||||||
|
{
|
||||||
|
return &msvc_renderer_ops;
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* renderer-msvc.h
|
||||||
|
* MSVC library syntax renderer header
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 pkgconf authors (see AUTHORS).
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* This software is provided 'as is' and without any warranty, express or
|
||||||
|
* implied. In no event shall the authors be liable for any damages arising
|
||||||
|
* from the use of this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RENDERER_MSVC_H
|
||||||
|
#define RENDERER_MSVC_H
|
||||||
|
|
||||||
|
#include <libpkgconf/libpkgconf.h>
|
||||||
|
|
||||||
|
const pkgconf_fragment_render_ops_t *msvc_renderer_get(void);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue