Skip to content

Commit

Permalink
Added new StringJoin() utility function
Browse files Browse the repository at this point in the history
The function joins a sequence of strings with an optional separator in
between the elements.

Ticket: None
Changelog: None
Signed-off-by: Lars Erik Wik <lars.erik.wik@northern.tech>
  • Loading branch information
larsewi committed Dec 8, 2023
1 parent 0aefa4a commit f6ac7fd
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
20 changes: 20 additions & 0 deletions libutils/string_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1781,3 +1781,23 @@ bool StringMatchesOption(
}
return StringEqualN_IgnoreCase(supplied, longopt, length);
}

char *StringJoin(const Seq *const seq, const char *sep)
{
assert(seq != NULL);

Writer *const writer = StringWriter();
const size_t len = SeqLength(seq);
for (size_t i = 0; i < len; i++)
{
if (i != 0 && sep != NULL)
{
WriterWrite(writer, sep);
}
const char *const str = SeqAt(seq, i);
WriterWrite(writer, str);
}

char *const data = StringWriterClose(writer);
return data;
}
10 changes: 10 additions & 0 deletions libutils/string_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,4 +322,14 @@ void CanonifyNameInPlace(char *str);
bool StringMatchesOption(
const char *supplied, const char *longopt, const char *shortopt);

/**
* @brief Join elements in sequence into a string
* @param[in] seq Sequence of strings to join
* @param[in] sep Separator between elements (can be NULL)
* @return The concatenation of the elements in sequence
* @note Sequence must contain only NUL-terminated strings, otherwise behavior
* is undefined
*/
char *StringJoin(const Seq *seq, const char *sep);

#endif
32 changes: 32 additions & 0 deletions tests/unit/string_lib_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1470,6 +1470,37 @@ static void test_StringMatchesOption(void)
assert_true(StringMatchesOption("--host", "--hosts", "-H"));
}

static void test_StringJoin(void)
{
const char *argv[] = { "one", "two", "three" };
const int argc = sizeof(argv) / sizeof(argv[0]);

Seq *seq = SeqFromArgv(argc, argv);

char *actual = StringJoin(seq, NULL);
assert_string_equal(actual, "onetwothree");

actual = StringJoin(seq, "");
assert_string_equal(actual, "onetwothree");

actual = StringJoin(seq, ", ");
assert_string_equal(actual, "one, two, three");

SeqDestroy(seq);
seq = SeqNew(0, NULL);

actual = StringJoin(seq, NULL);
assert_string_equal(actual, "");

actual = StringJoin(seq, "");
assert_string_equal(actual, "");

actual = StringJoin(seq, ", ");
assert_string_equal(actual, "");

SeqDestroy(seq);
}

int main()
{
PRINT_TEST_BANNER();
Expand Down Expand Up @@ -1564,6 +1595,7 @@ int main()
unit_test(test_StrCatDelim),

unit_test(test_StringMatchesOption),
unit_test(test_StringJoin),
};

return run_tests(tests);
Expand Down

0 comments on commit f6ac7fd

Please sign in to comment.