diff --git a/libpromises/fncall.c b/libpromises/fncall.c index 44f66e9d12..c599f459bd 100644 --- a/libpromises/fncall.c +++ b/libpromises/fncall.c @@ -228,7 +228,7 @@ void FnCallWrite(Writer *writer, const FnCall *call) switch (rp->val.type) { case RVAL_TYPE_SCALAR: - ScalarWrite(writer, RlistScalarValue(rp), true); + ScalarWrite(writer, RlistScalarValue(rp), true, false); break; case RVAL_TYPE_FNCALL: diff --git a/libpromises/policy.c b/libpromises/policy.c index c40003d8b8..844542f4cf 100644 --- a/libpromises/policy.c +++ b/libpromises/policy.c @@ -2105,7 +2105,7 @@ void BundleToString(Writer *writer, Bundle *bundle) } IndentPrint(writer, 2); - ScalarWrite(writer, pp->promiser, true); + ScalarWrite(writer, pp->promiser, true, false); /* FIX: add support * diff --git a/libpromises/rlist.c b/libpromises/rlist.c index 732e9d324c..909ef7633f 100644 --- a/libpromises/rlist.c +++ b/libpromises/rlist.c @@ -1339,7 +1339,7 @@ void RlistWrite(Writer *writer, const Rlist *list) WriterWriteChar(writer, '}'); } -void ScalarWrite(Writer *writer, const char *s, bool quote) +void ScalarWrite(Writer *writer, const char *s, bool quote, bool raw) { if (quote) { @@ -1347,7 +1347,7 @@ void ScalarWrite(Writer *writer, const char *s, bool quote) } for (; *s; s++) { - if (*s == '"') + if (*s == '"' && !raw) { WriterWriteChar(writer, '\\'); } @@ -1359,7 +1359,7 @@ void ScalarWrite(Writer *writer, const char *s, bool quote) } } -static void RvalWriteParts(Writer *writer, const void* item, RvalType type, bool quote) +static void RvalWriteParts(Writer *writer, const void* item, RvalType type, bool quote, bool raw) { if (item == NULL) { @@ -1369,7 +1369,7 @@ static void RvalWriteParts(Writer *writer, const void* item, RvalType type, bool switch (type) { case RVAL_TYPE_SCALAR: - ScalarWrite(writer, item, quote); + ScalarWrite(writer, item, quote, raw); break; case RVAL_TYPE_LIST: @@ -1392,12 +1392,17 @@ static void RvalWriteParts(Writer *writer, const void* item, RvalType type, bool void RvalWrite(Writer *writer, Rval rval) { - RvalWriteParts(writer, rval.item, rval.type, false); + RvalWriteParts(writer, rval.item, rval.type, false, false); } void RvalWriteQuoted(Writer *writer, Rval rval) { - RvalWriteParts(writer, rval.item, rval.type, true); + RvalWriteParts(writer, rval.item, rval.type, true, false); +} + +void RvalWriteRaw(Writer *writer, Rval rval) +{ + RvalWriteParts(writer, rval.item, rval.type, false, true); } char *RvalToString(Rval rval) diff --git a/libpromises/rlist.h b/libpromises/rlist.h index 32445c5eeb..da9f0653ff 100644 --- a/libpromises/rlist.h +++ b/libpromises/rlist.h @@ -65,6 +65,7 @@ char *RvalToString(Rval rval); char *RlistToString(const Rlist *rlist); void RvalWrite(Writer *writer, Rval rval); void RvalWriteQuoted(Writer *writer, Rval rval); +void RvalWriteRaw(Writer *writer, Rval rval); unsigned RvalHash(Rval rval, unsigned seed); Rlist *RlistCopy(const Rlist *list); @@ -109,7 +110,7 @@ void RlistWrite(Writer *writer, const Rlist *list); Rlist *RlistLast(Rlist *start); void RlistFilter(Rlist **list, bool (*KeepPredicate)(void *item, void *predicate_data), void *predicate_user_data, void (*DestroyItem)(void *item)); void RlistReverse(Rlist **list); -void ScalarWrite(Writer *w, const char *s, bool quote); +void ScalarWrite(Writer *w, const char *s, bool quote, bool raw); void RlistFlatten(EvalContext *ctx, Rlist **list); bool RlistEqual (const Rlist *list1, const Rlist *list2); bool RlistEqual_untyped(const void *list1, const void *list2); diff --git a/tests/unit/rlist_test.c b/tests/unit/rlist_test.c index 32fb4e4a99..e713368ad9 100644 --- a/tests/unit/rlist_test.c +++ b/tests/unit/rlist_test.c @@ -713,6 +713,36 @@ static void test_regex_split_overlapping_delimiters() RlistDestroy(list); } +static void test_rval_write() +{ + Rval rval = { "\"Hello World!\"", RVAL_TYPE_SCALAR }; + Writer *writer = StringWriter(); + RvalWrite(writer, rval); + const char *actual = StringWriterData(writer); + assert_string_equal(actual, "\\\"Hello World!\\\""); + WriterClose(writer); +} + +static void test_rval_write_quoted() +{ + Rval rval = { "\"Hello World!\"", RVAL_TYPE_SCALAR }; + Writer *writer = StringWriter(); + RvalWriteQuoted(writer, rval); + const char *actual = StringWriterData(writer); + assert_string_equal(actual, "\"\\\"Hello World!\\\"\""); + WriterClose(writer); +} + +static void test_rval_write_raw() +{ + Rval rval = { "\"Hello World!\"", RVAL_TYPE_SCALAR }; + Writer *writer = StringWriter(); + RvalWriteRaw(writer, rval); + const char *actual = StringWriterData(writer); + assert_string_equal(actual, "\"Hello World!\""); + WriterClose(writer); +} + int main() { PRINT_TEST_BANNER(); @@ -744,7 +774,10 @@ int main() unit_test(test_regex_split_no_match), unit_test(test_regex_split_adjacent_separators), unit_test(test_regex_split_real_regex), - unit_test(test_regex_split_overlapping_delimiters) + unit_test(test_regex_split_overlapping_delimiters), + unit_test(test_rval_write), + unit_test(test_rval_write_quoted), + unit_test(test_rval_write_raw), }; return run_tests(tests);