From 077939939140091f62283ab9eeb02d019d443ab7 Mon Sep 17 00:00:00 2001 From: Martin Bremmer Date: Thu, 11 Apr 2019 14:10:08 +0200 Subject: [PATCH] Moved expand_envvars. Signed-off-by: Martin Bremmer --- src/core/ddsi/src/q_config.c | 1 + src/ddsrt/include/dds/ddsrt/environ.h | 44 +++++++++++ src/ddsrt/tests/environ.c | 105 +++++++++++++++++++++++++- src/mpt/mpt/cmake/MPT.cmake | 9 --- src/mpt/mpt/src/main.c.in | 3 +- 5 files changed, 150 insertions(+), 12 deletions(-) diff --git a/src/core/ddsi/src/q_config.c b/src/core/ddsi/src/q_config.c index 5a412e8..bf1781d 100644 --- a/src/core/ddsi/src/q_config.c +++ b/src/core/ddsi/src/q_config.c @@ -22,6 +22,7 @@ #include "dds/ddsrt/string.h" #include "dds/ddsrt/strtod.h" #include "dds/ddsrt/misc.h" +#include "dds/ddsrt/environ.h" #include "dds/ddsi/q_config.h" #include "dds/ddsi/q_log.h" #include "dds/ddsrt/avl.h" diff --git a/src/ddsrt/include/dds/ddsrt/environ.h b/src/ddsrt/include/dds/ddsrt/environ.h index 48953c2..67a8c29 100644 --- a/src/ddsrt/include/dds/ddsrt/environ.h +++ b/src/ddsrt/include/dds/ddsrt/environ.h @@ -96,6 +96,50 @@ ddsrt_unsetenv( const char *name) ddsrt_nonnull_all; +/** + * @brief Expand environment 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. + * + * @returns Allocated char*. + * + * @retval NULL + * Expansion failed. + * @retval Pointer + * Copy of the string argument with the environment + * variables expanded. + */ +DDS_EXPORT char* +ddsrt_expand_envvars( + const char *string); + +/** + * @brief Expand environment 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. + * + * @returns Allocated char*. + * + * @retval NULL + * Expansion failed. + * @retval Pointer + * Copy of the string argument with the environment + * variables expanded. + */ +DDS_EXPORT char* +ddsrt_expand_envvars_sh( + const char *string); + + #if defined(__cplusplus) } #endif diff --git a/src/ddsrt/tests/environ.c b/src/ddsrt/tests/environ.c index 56f7468..b69acf4 100644 --- a/src/ddsrt/tests/environ.c +++ b/src/ddsrt/tests/environ.c @@ -14,6 +14,7 @@ #include "CUnit/Theory.h" #include "dds/ddsrt/environ.h" #include "dds/ddsrt/misc.h" +#include "dds/ddsrt/heap.h" CU_TheoryDataPoints(ddsrt_environ, bad_name) = { CU_DataPoints(const char *, "", "foo=") @@ -91,8 +92,110 @@ CU_Test(ddsrt_environ, getenv) CU_ASSERT_STRING_EQUAL(ptr, "bar"); } - /* Ensure environement is as it was. */ + /* Ensure environment is as it was. */ rc = ddsrt_unsetenv(name); CU_ASSERT_EQUAL(rc, DDS_RETCODE_OK); } +CU_TheoryDataPoints(ddsrt_environ, expand) = { + CU_DataPoints(const char *, + "${X}", "$X", "X", "${Y}", "${Q}", "${X", + "${X:-ALT}", "${Q:-ALT}", "${X:-${Y}}", "${Q:-${Y}}", "${X:-$Y}", "${Q:-$Y}", "${X:-}", "${Q:-}", + "${X:+SET}", "${Q:+SET}", "${X:+${Y}}", "${Q:+${Y}}", "${X:+$Y}", "${Q:+$Y}", "${X:+}", "${Q:+}", + "${X:?SET}", "${Q:?SET}", "${X:?${Y}}", "${Q:?${Y}}", "${X:?$Y}", "${Q:?$Y}", "${X:?}", "${Q:?}"), + CU_DataPoints(const char *, + "TEST", "$X", "X", "FOO", "", NULL, + "TEST", "ALT", "TEST", "FOO", "TEST", "$Y", "TEST", "", + "SET", "", "FOO", "", "$Y", "", "", "", + "TEST", NULL, "TEST", NULL, "TEST", NULL, "TEST", NULL) +}; +CU_Theory((const char *var, const char *expect), ddsrt_environ, expand) +{ + dds_retcode_t rc; + static const char x_name[] = "X"; + static const char x_value[] = "TEST"; + static const char y_name[] = "Y"; + static const char y_value[] = "FOO"; + char *ptr; + + /* Ensure that the vars are not used yet. */ + rc = ddsrt_unsetenv(x_name); + CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK); + rc = ddsrt_unsetenv(y_name); + CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK); + + /* Set the env vars to check expansion. */ + rc = ddsrt_setenv(x_name, x_value); + CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK); + rc = ddsrt_setenv(y_name, y_value); + CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK); + + /* Expand a string with available environment variables. */ + ptr = ddsrt_expand_envvars(var); + if (ptr) { + /* printf("==== %10s: expand(%s), expect(%s))\n", var, ptr, expect); */ + CU_ASSERT_STRING_EQUAL(ptr, expect); + ddsrt_free(ptr); + } else { + /* printf("==== %10s: expand(), expect())\n", var ? var : ""); */ + CU_ASSERT_PTR_NULL(expect); + } + + /* Ensure to reset the environment is as it was. */ + rc = ddsrt_unsetenv(y_name); + CU_ASSERT_EQUAL(rc, DDS_RETCODE_OK); + rc = ddsrt_unsetenv(x_name); + CU_ASSERT_EQUAL(rc, DDS_RETCODE_OK); +} + + +CU_TheoryDataPoints(ddsrt_environ, expand_sh) = { + CU_DataPoints(const char *, + "${X}", "$X", "X", "${Y}", "${Q}", "${X", + "${X:-ALT}", "${Q:-ALT}", "${X:-${Y}}", "${Q:-${Y}}", "${X:-$Y}", "${Q:-$Y}", "${X:-}", "${Q:-}", + "${X:+SET}", "${Q:+SET}", "${X:+${Y}}", "${Q:+${Y}}", "${X:+$Y}", "${Q:+$Y}", "${X:+}", "${Q:+}", + "${X:?SET}", "${Q:?SET}", "${X:?${Y}}", "${Q:?${Y}}", "${X:?$Y}", "${Q:?$Y}", "${X:?}", "${Q:?}"), + CU_DataPoints(const char *, + "TEST", "TEST", "X", "FOO", "", NULL, + "TEST", "ALT", "TEST", "FOO", "TEST", "FOO", "TEST", "", + "SET", "", "FOO", "", "FOO", "", "", "", + "TEST", NULL, "TEST", NULL, "TEST", NULL, "TEST", NULL) +}; +CU_Theory((const char *var, const char *expect), ddsrt_environ, expand_sh) +{ + dds_retcode_t rc; + static const char x_name[] = "X"; + static const char x_value[] = "TEST"; + static const char y_name[] = "Y"; + static const char y_value[] = "FOO"; + char *ptr; + + /* Ensure that the vars are not used yet. */ + rc = ddsrt_unsetenv(x_name); + CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK); + rc = ddsrt_unsetenv(y_name); + CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK); + + /* Set the env vars to check expansion. */ + rc = ddsrt_setenv(x_name, x_value); + CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK); + rc = ddsrt_setenv(y_name, y_value); + CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK); + + /* Expand a string with available environment variables. */ + ptr = ddsrt_expand_envvars_sh(var); + if (ptr) { + /* printf("==== %10s: expand(%s), expect(%s))\n", var, ptr, expect); */ + CU_ASSERT_STRING_EQUAL(ptr, expect); + ddsrt_free(ptr); + } else { + /* printf("==== %10s: expand(), expect())\n", var ? var : ""); */ + CU_ASSERT_PTR_NULL(expect); + } + + /* Ensure to reset the environment is as it was. */ + rc = ddsrt_unsetenv(y_name); + CU_ASSERT_EQUAL(rc, DDS_RETCODE_OK); + rc = ddsrt_unsetenv(x_name); + CU_ASSERT_EQUAL(rc, DDS_RETCODE_OK); +} diff --git a/src/mpt/mpt/cmake/MPT.cmake b/src/mpt/mpt/cmake/MPT.cmake index fd50b5b..a9fad3d 100644 --- a/src/mpt/mpt/cmake/MPT.cmake +++ b/src/mpt/mpt/cmake/MPT.cmake @@ -171,14 +171,5 @@ function(add_mpt_executable TARGET) target_include_directories(${TARGET} PRIVATE "${MPT_DIR}/include" "${MPT_BINARY_ROOT_DIR}/mpt/include") target_link_libraries(${TARGET} PRIVATE ddsc) - - # We need the 'expand environment variables' feature that is present in the - # 'util' module. However, it is currently not possible to properly link to - # that module on Windows. In the near future, the utils will be migrated to - # ddsrt, after which we automatically have access to expand_envvars. - # But until then, use this very ugly (but quick) hack to solve our immediate - # build issues. - target_include_directories(${TARGET} PRIVATE "${CMAKE_SOURCE_DIR}/util/include") - target_sources(${TARGET} PRIVATE "${CMAKE_SOURCE_DIR}/util/src/ut_expand_envvars.c") endfunction() diff --git a/src/mpt/mpt/src/main.c.in b/src/mpt/mpt/src/main.c.in index 31f0689..fb5aaba 100644 --- a/src/mpt/mpt/src/main.c.in +++ b/src/mpt/mpt/src/main.c.in @@ -6,7 +6,6 @@ #include "dds/ddsrt/heap.h" #include "dds/ddsrt/process.h" #include "dds/ddsrt/environ.h" -#include "dds/util/ut_expand_envvars.h" #ifndef _WIN32 #include @@ -63,7 +62,7 @@ mpt_export_env(const mpt_env_t *env) { if (env) { while ((env->name != NULL) && (env->value != NULL)) { - char *expanded = ut_expand_envvars(env->value); + char *expanded = ddsrt_expand_envvars(env->value); ddsrt_setenv(env->name, expanded); ddsrt_free(expanded); env++;