From 2fab31704068ddf4d5ed2fc40e1b1d9c5736c044 Mon Sep 17 00:00:00 2001 From: qu1ck Date: Wed, 13 May 2020 16:54:44 -0700 Subject: [PATCH] Add TR_TORRENT_LABELS to env variables available to scripts (#868) * Add TR_TORRENT_LABELS to env variables available to scripts * Add unit test for tr_strjoin Co-authored-by: Charles Kerr --- libtransmission/torrent.c | 4 ++++ libtransmission/utils-test.c | 33 +++++++++++++++++++++++++++++++++ libtransmission/utils.c | 31 +++++++++++++++++++++++++++++++ libtransmission/utils.h | 3 +++ 4 files changed, 71 insertions(+) diff --git a/libtransmission/torrent.c b/libtransmission/torrent.c index 24f9fde67..7ecaf3f51 100644 --- a/libtransmission/torrent.c +++ b/libtransmission/torrent.c @@ -2253,6 +2253,8 @@ static void torrentCallScript(tr_torrent const* tor, char const* script) NULL }; + char* labels = tr_strjoin((char const* const*)tr_ptrArrayBase(&tor->labels), tr_ptrArraySize(&tor->labels), ","); + char* const env[] = { tr_strdup_printf("TR_APP_VERSION=%s", SHORT_VERSION_STRING), @@ -2261,6 +2263,7 @@ static void torrentCallScript(tr_torrent const* tor, char const* script) tr_strdup_printf("TR_TORRENT_HASH=%s", tor->info.hashString), tr_strdup_printf("TR_TORRENT_ID=%d", tr_torrentId(tor)), tr_strdup_printf("TR_TORRENT_NAME=%s", tr_torrentName(tor)), + tr_strdup_printf("TR_TORRENT_LABELS=%s", labels), NULL }; @@ -2276,6 +2279,7 @@ static void torrentCallScript(tr_torrent const* tor, char const* script) tr_free_ptrv((void* const*)env); tr_free_ptrv((void* const*)cmd); + tr_free(labels); tr_free(torrent_dir); } diff --git a/libtransmission/utils-test.c b/libtransmission/utils-test.c index 8eabf2e40..b93307a9f 100644 --- a/libtransmission/utils-test.c +++ b/libtransmission/utils-test.c @@ -80,6 +80,38 @@ static int test_strstrip(void) return 0; } +static int test_strjoin(void) +{ + char* out; + + char const* in1[] = { "one", "two" }; + out = tr_strjoin(in1, 2, ", "); + check_str(out, ==, "one, two"); + tr_free(out); + + char const* in2[] = { "hello" }; + out = tr_strjoin(in2, 1, "###"); + check_str(out, ==, "hello"); + tr_free(out); + + char const* in3[] = { "a", "b", "ccc", "d", "eeeee" }; + out = tr_strjoin(in3, 5, " "); + check_str(out, ==, "a b ccc d eeeee"); + tr_free(out); + + char const* in4[] = { "7", "ate", "9" }; + out = tr_strjoin(in4, 3, ""); + check_str(out, ==, "7ate9"); + tr_free(out); + + char const** in5; + out = tr_strjoin(in5, 0, "a"); + check_str(out, ==, ""); + tr_free(out); + + return 0; +} + static int test_buildpath(void) { char* out; @@ -545,6 +577,7 @@ int main(void) test_strip_positional_args, test_strdup_printf, test_strstrip, + test_strjoin, test_truncd, test_url, test_utf8, diff --git a/libtransmission/utils.c b/libtransmission/utils.c index 04b4372f7..182bc6483 100644 --- a/libtransmission/utils.c +++ b/libtransmission/utils.c @@ -587,6 +587,37 @@ char* tr_strsep(char** str, char const* delims) #endif } +char* tr_strjoin(char const* const* arr, size_t len, char const* delim) +{ + size_t total_len = 1; + size_t delim_len = strlen(delim); + for (size_t i = 0; i < len; ++i) + { + total_len += strlen(arr[i]); + } + + total_len += len > 0 ? (len - 1) * delim_len : 0; + + char* const ret = tr_new(char, total_len); + char* p = ret; + + for (size_t i = 0; i < len; ++i) + { + if (i > 0) + { + memcpy(p, delim, delim_len); + p += delim_len; + } + + size_t const part_len = strlen(arr[i]); + memcpy(p, arr[i], part_len); + p += part_len; + } + + *p = '\0'; + return ret; +} + char* tr_strstrip(char* str) { if (str != NULL) diff --git a/libtransmission/utils.h b/libtransmission/utils.h index 98f88545c..ac1f5c3f3 100644 --- a/libtransmission/utils.h +++ b/libtransmission/utils.h @@ -254,6 +254,9 @@ char const* tr_strcasestr(char const* haystack, char const* needle); /** @brief Portability wrapper for strsep() that uses the system implementation if available */ char* tr_strsep(char** str, char const* delim); +/** @brief Concatenates array of strings with delimiter in between elements */ +char* tr_strjoin(char const* const* arr, size_t len, char const* delim); + /*** **** ***/