Refactored expand_vars so that a custom lookup function can be used, which makes it usable for replacing tags by values other than environment variables

Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com>
This commit is contained in:
Dennis Potman 2020-02-24 14:03:25 +01:00 committed by eboasson
parent 24e42fd658
commit b3c5a8d4fc
14 changed files with 180 additions and 49 deletions

View file

@ -96,7 +96,7 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_
dds_participant * pp;
ddsi_plist_t plist;
dds_qos_t *new_qos = NULL;
char *config = "";
const char *config = "";
/* Make sure DDS instance is initialized. */
if ((ret = dds_init ()) < 0)

View file

@ -29,7 +29,7 @@
static void config__check_env (const char *env_variable, const char *expected_value)
{
char *env_uri = NULL;
const char *env_uri = NULL;
ddsrt_getenv (env_variable, &env_uri);
#ifdef FORCE_ENV
{

View file

@ -111,7 +111,7 @@ CU_Test(ddsc_participant, create_with_conf_no_env) {
ddsrt_setenv(DDS_PROJECT_NAME_NOSPACE_CAPS"_URI", CONFIG_ENV_SIMPLE_UDP);
ddsrt_setenv("MAX_PARTICIPANTS", CONFIG_ENV_MAX_PARTICIPANTS);
char * env_uri = NULL;
const char * env_uri = NULL;
ddsrt_getenv(DDS_PROJECT_NAME_NOSPACE_CAPS"_URI", &env_uri);
CU_ASSERT_PTR_NOT_EQUAL_FATAL(env_uri, NULL);

View file

@ -131,7 +131,8 @@ list(APPEND sources
"${source_path}/strtol.c"
"${source_path}/mh3.c"
"${source_path}/avl.c"
"${source_path}/expand_envvars.c"
"${source_path}/environ.c"
"${source_path}/expand_vars.c"
"${source_path}/fibheap.c"
"${source_path}/hopscotch.c"
"${source_path}/thread_pool.c"

View file

@ -14,6 +14,7 @@
#include "dds/export.h"
#include "dds/ddsrt/attributes.h"
#include "dds/ddsrt/expand_vars.h"
#include "dds/ddsrt/retcode.h"
#if defined(__cplusplus)
@ -42,7 +43,7 @@ extern "C" {
DDS_EXPORT dds_return_t
ddsrt_getenv(
const char *name,
char **value)
const char **value)
ddsrt_nonnull_all;
/**

View file

@ -0,0 +1,78 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#ifndef DDSRT_EXPAND_VARS_H
#define DDSRT_EXPAND_VARS_H
#include "dds/export.h"
#include "dds/ddsrt/attributes.h"
#include "dds/ddsrt/retcode.h"
#if defined(__cplusplus)
extern "C" {
#endif
typedef const char * (*expand_lookup_fn)(const char *name, void *data);
/**
* @brief Expand variables within string.
*
* Expands ${X}, ${X:-Y}, ${X:+Y}, ${X:?Y} forms, but not $X.
*
* The result string should be freed with ddsrt_free().
*
* @param[in] string String to expand.
* @param[in] lookup Lookup function to retrieve replacement value
* @param[in] data Data passed to lookup function
*
* @returns Allocated char*.
*
* @retval NULL
* Expansion failed.
* @retval Pointer
* Copy of the string argument with the variables expanded.
*/
DDS_EXPORT char*
ddsrt_expand_vars(
const char *string,
expand_lookup_fn lookup,
void * data);
/**
* @brief Expand variables within string.
*
* Expands $X, ${X}, ${X:-Y}, ${X:+Y}, ${X:?Y} forms, $ and \
* can be escaped with \.
*
* The result string should be freed with ddsrt_free().
*
* @param[in] string String to expand.
* @param[in] lookup Lookup function to retrieve replacement value
* @param[in] data Data passed to lookup function
*
* @returns Allocated char*.
*
* @retval NULL
* Expansion failed.
* @retval Pointer
* Copy of the string argument with the variables expanded.
*/
DDS_EXPORT char*
ddsrt_expand_vars_sh(
const char *string,
expand_lookup_fn lookup,
void * data);
#if defined(__cplusplus)
}
#endif
#endif /* DDSRT_EXPAND_VARS_H */

59
src/ddsrt/src/environ.c Normal file
View file

@ -0,0 +1,59 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "dds/ddsrt/expand_vars.h"
#include "dds/ddsrt/environ.h"
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/log.h"
#include "dds/ddsrt/string.h"
#include "dds/ddsrt/process.h"
struct expand_env_data
{
uint32_t domid;
char idstr[20];
};
static const char * expand_lookup_env(const char *name, void * data)
{
const char *env = NULL;
struct expand_env_data * env_data = data;
if (ddsrt_getenv (name, &env) == DDS_RETCODE_OK) {
/* ok */
} else if (strcmp (name, "$") == 0 || strcmp (name, "CYCLONEDDS_PID") == 0) {
(void) snprintf (env_data->idstr, sizeof (env_data->idstr), "%"PRIdPID, ddsrt_getpid ());
env = env_data->idstr;
} else if (strcmp (name, "CYCLONEDDS_DOMAIN_ID") == 0 && env_data->domid != UINT32_MAX) {
(void) snprintf (env_data->idstr, sizeof (env_data->idstr), "%"PRIu32, env_data->domid);
env = env_data->idstr;
}
return env;
}
char *ddsrt_expand_envvars_sh (const char *src0, uint32_t domid)
{
struct expand_env_data env = { .domid = domid, .idstr = "" };
return ddsrt_expand_vars_sh(src0, &expand_lookup_env, &env);
}
char *ddsrt_expand_envvars (const char *src0, uint32_t domid)
{
struct expand_env_data env = { .domid = domid, .idstr = "" };
return ddsrt_expand_vars(src0, &expand_lookup_env, &env);
}

View file

@ -24,7 +24,7 @@ isenvvar(const char *name)
}
dds_return_t
ddsrt_getenv(const char *name, char **value)
ddsrt_getenv(const char *name, const char **value)
{
char *env;

View file

@ -27,7 +27,7 @@ isenvvar(const char *name)
}
dds_return_t
ddsrt_getenv(const char *name, char **value)
ddsrt_getenv(const char *name, const char **value)
{
char *env;

View file

@ -26,7 +26,7 @@ isenvvar(const char *name)
DDSRT_WARNING_MSVC_OFF(4996)
dds_return_t
ddsrt_getenv(const char *name, char **value)
ddsrt_getenv(const char *name, const char **value)
{
char *env;

View file

@ -15,13 +15,13 @@
#include <assert.h>
#include <string.h>
#include "dds/ddsrt/environ.h"
#include "dds/ddsrt/expand_vars.h"
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/log.h"
#include "dds/ddsrt/string.h"
#include "dds/ddsrt/process.h"
typedef char * (*expand_fn)(const char *src0, uint32_t domid);
typedef char * (*expand_fn)(const char *src0, expand_lookup_fn lookup, void * data);
static void expand_append (char **dst, size_t *sz, size_t *pos, char c)
{
@ -33,46 +33,33 @@ static void expand_append (char **dst, size_t *sz, size_t *pos, char c)
(*pos)++;
}
static char *expand_env (const char *name, char op, const char *alt, expand_fn expand, uint32_t domid)
static char *expand_var (const char *name, char op, const char *alt, expand_fn expand, expand_lookup_fn lookup, void * data)
{
char idstr[20];
char *env = NULL;
dds_return_t ret;
if ((ret = ddsrt_getenv (name, &env)) == DDS_RETCODE_OK) {
/* ok */
} else if (strcmp (name, "$") == 0 || strcmp (name, "CYCLONEDDS_PID") == 0) {
(void) snprintf (idstr, sizeof (idstr), "%"PRIdPID, ddsrt_getpid ());
env = idstr;
} else if (strcmp (name, "CYCLONEDDS_DOMAIN_ID") == 0 && domid != UINT32_MAX) {
(void) snprintf (idstr, sizeof (idstr), "%"PRIu32, domid);
env = idstr;
}
const char *val = lookup (name, data);
switch (op)
{
case 0:
return ddsrt_strdup (env ? env : "");
return ddsrt_strdup (val ? val : "");
case '-':
return env && *env ? ddsrt_strdup (env) : expand (alt, domid);
return val && *val ? ddsrt_strdup (val) : expand (alt, lookup, data);
case '?':
if (env && *env) {
return ddsrt_strdup (env);
if (val && *val) {
return ddsrt_strdup (val);
} else {
char *altx = expand (alt, domid);
DDS_ILOG (DDS_LC_ERROR, domid, "%s: %s\n", name, altx);
char *altx = expand (alt, lookup, data);
DDS_LOG (DDS_LC_ERROR, "%s: %s\n", name, altx);
ddsrt_free (altx);
return NULL;
}
case '+':
return env && *env ? expand (alt, domid) : ddsrt_strdup ("");
return val && *val ? expand (alt, lookup, data) : ddsrt_strdup ("");
default:
abort ();
return NULL;
}
}
static char *expand_envbrace (const char **src, expand_fn expand, uint32_t domid)
static char *expand_varbrace (const char **src, expand_fn expand, expand_lookup_fn lookup, void * data)
{
const char *start = *src + 1;
char *name, *x;
@ -89,7 +76,7 @@ static char *expand_envbrace (const char **src, expand_fn expand, uint32_t domid
name[*src - start] = 0;
if (**src == '}') {
(*src)++;
x = expand_env (name, 0, NULL, expand, domid);
x = expand_var (name, 0, NULL, expand, lookup, data);
ddsrt_free (name);
return x;
} else {
@ -133,7 +120,7 @@ static char *expand_envbrace (const char **src, expand_fn expand, uint32_t domid
memcpy (alt, altstart, (size_t) (*src - altstart));
alt[*src - altstart] = 0;
(*src)++;
x = expand_env (name, op, alt, expand, domid);
x = expand_var (name, op, alt, expand, lookup, data);
ddsrt_free (alt);
ddsrt_free (name);
return x;
@ -143,7 +130,7 @@ err:
return NULL;
}
static char *expand_envsimple (const char **src, expand_fn expand, uint32_t domid)
static char *expand_varsimple (const char **src, expand_fn expand, expand_lookup_fn lookup, void * data)
{
const char *start = *src;
char *name, *x;
@ -154,22 +141,22 @@ static char *expand_envsimple (const char **src, expand_fn expand, uint32_t domi
name = ddsrt_malloc ((size_t) (*src - start) + 1);
memcpy (name, start, (size_t) (*src - start));
name[*src - start] = 0;
x = expand_env (name, 0, NULL, expand, domid);
x = expand_var (name, 0, NULL, expand, lookup, data);
ddsrt_free (name);
return x;
}
static char *expand_envchar (const char **src, expand_fn expand, uint32_t domid)
static char *expand_varchar (const char **src, expand_fn expand, expand_lookup_fn lookup, void * data)
{
char name[2];
assert (**src);
name[0] = **src;
name[1] = 0;
(*src)++;
return expand_env (name, 0, NULL, expand, domid);
return expand_var (name, 0, NULL, expand, lookup, data);
}
char *ddsrt_expand_envvars_sh (const char *src0, uint32_t domid)
char *ddsrt_expand_vars_sh (const char *src0, expand_lookup_fn lookup, void * data)
{
/* Expands $X, ${X}, ${X:-Y}, ${X:+Y}, ${X:?Y} forms; $ and \ can be escaped with \ */
const char *src = src0;
@ -192,11 +179,11 @@ char *ddsrt_expand_envvars_sh (const char *src0, uint32_t domid)
ddsrt_free(dst);
return NULL;
} else if (*src == '{') {
x = expand_envbrace (&src, &ddsrt_expand_envvars_sh, domid);
x = expand_varbrace (&src, &ddsrt_expand_vars_sh, lookup, data);
} else if (isalnum ((unsigned char) *src) || *src == '_') {
x = expand_envsimple (&src, &ddsrt_expand_envvars_sh, domid);
x = expand_varsimple (&src, &ddsrt_expand_vars_sh, lookup, data);
} else {
x = expand_envchar (&src, &ddsrt_expand_envvars_sh, domid);
x = expand_varchar (&src, &ddsrt_expand_vars_sh, lookup, data);
}
if (x == NULL) {
ddsrt_free(dst);
@ -215,7 +202,7 @@ char *ddsrt_expand_envvars_sh (const char *src0, uint32_t domid)
return dst;
}
char *ddsrt_expand_envvars (const char *src0, uint32_t domid)
char *ddsrt_expand_vars (const char *src0, expand_lookup_fn lookup, void * data)
{
/* Expands ${X}, ${X:-Y}, ${X:+Y}, ${X:?Y} forms, but not $X */
const char *src = src0;
@ -225,7 +212,7 @@ char *ddsrt_expand_envvars (const char *src0, uint32_t domid)
if (*src == '$' && *(src + 1) == '{') {
char *x, *xp;
src++;
x = expand_envbrace (&src, &ddsrt_expand_envvars, domid);
x = expand_varbrace (&src, &ddsrt_expand_vars, lookup, data);
if (x == NULL) {
ddsrt_free(dst);
return NULL;
@ -242,3 +229,4 @@ char *ddsrt_expand_envvars (const char *src0, uint32_t domid)
expand_append (&dst, &sz, &pos, 0);
return dst;
}

View file

@ -27,9 +27,12 @@
#define TOK_CLOSE_TAG -5
#define TOK_SHORTHAND_CLOSE_TAG -6
#define TOK_ERROR -7
#define TOK_CDATA -8
#define NOMARKER (~(size_t)0)
static const char *cdata_magic = "<![CDATA[";
struct ddsrt_xmlp_state {
size_t cbufp; /* current position in cbuf */
size_t cbufn; /* number of bytes in cbuf (cbufp <= cbufn) */
@ -559,6 +562,8 @@ static int next_token (struct ddsrt_xmlp_state *st, char **payload)
} else if (peek_chars (st, "<?", 1)) {
processing_instruction (st, "?>");
return next_token (st, payload);
} else if (peek_chars (st, cdata_magic, 0)) {
tok = TOK_CDATA;
} else if (peek_chars (st, "<!", 1)) {
processing_instruction (st, ">");
return next_token (st, payload);
@ -652,7 +657,6 @@ static int parse_element (struct ddsrt_xmlp_state *st, uintptr_t parentinfo)
}
} else {
/* text */
static const char *cdata_magic = "<![CDATA[";
char *content;
int cmt = 0;
rewind_to_input_marker (st);

View file

@ -26,7 +26,7 @@ CU_Theory((const char *name), ddsrt_environ, bad_name)
dds_return_t rc;
static const char value[] = "bar";
static char dummy[] = "foobar";
char *ptr;
const char *ptr;
rc = ddsrt_setenv(name, value);
CU_ASSERT_EQUAL(rc, DDS_RETCODE_BAD_PARAMETER);
@ -71,7 +71,7 @@ CU_Test(ddsrt_environ, getenv)
static const char name[] = "foo";
static const char value[] = "bar";
static char dummy[] = "foobar";
char *ptr;
const char *ptr;
/* Ensure "not found" is returned. */
rc = ddsrt_unsetenv(name);

View file

@ -57,7 +57,7 @@ static int test_pid(void)
static int test_env(void)
{
int ret = TEST_EXIT_FAILURE;
char *envptr = NULL;
const char *envptr = NULL;
if (ddsrt_getenv(TEST_ENV_VAR_NAME, &envptr) == DDS_RETCODE_OK) {
printf(" Process: env %s=%s.\n", TEST_ENV_VAR_NAME, envptr);
if (strcmp(envptr, TEST_ENV_VAR_VALUE) == 0) {