This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch master in repository libx2goclient. commit c13cccb5daa1c0a5e427210c8ca3a46b73e18b40 Author: Mihai Moldovan <ionic@ionic.de> Date: Sat Jun 27 12:51:16 2020 +0200 src/x2goclient-utils.{c,h}: add new documented function x2goclient_strbrk_dup (). The general idea is to scan for a character and return either a copy of the original string up until the first occurrence of the searched-for character or bypass the copy if the original string does not contain the searched-for character. Additionally, if a copy took place successfully, the original string is g_free()'d upon request and the truncated string's size returned in an out parameter. The error case behavior is complicated, so refer to the documentation. --- src/x2goclient-utils.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/x2goclient-utils.h | 1 + 2 files changed, 80 insertions(+) diff --git a/src/x2goclient-utils.c b/src/x2goclient-utils.c index bc8c358..28eaf85 100644 --- a/src/x2goclient-utils.c +++ b/src/x2goclient-utils.c @@ -150,3 +150,82 @@ long long x2goclient_str_to_int (const gchar *restrict str, _Bool min, long long return (ret); } + +/** + * x2goclient_strbrk_dup: + * @haystack: (inout) (not nullable) (transfer none): pointer to input string + * @needle: (in): character to split/break at + * @free_orig: (in): request that the original string be g_free()'d at the end + * @new_size: (out) (nullable): will be set to the copied string's size if a + * copy was created + * + * Searches for the first occurrence of a specific character in a string and + * returns a copy of the string up to that location, potentially freeing the + * original string if necessary and requested via @free_orig. The truncated + * string's (iff truncated) size is returned via @new_size, unless an error + * occurred. + * + * The input parameter @haystack MUST NOT be %NULL at any time. + * The input parameter @needle CAN be %NULL, but that's hardly useful, since it + * effectively degrades the function to (a probably slower implementation of) + * strdup(). + * The output parameter @new_size CAN be %NULL. + * + * Errors are indicated by returning %NULL: + * - If the value of @haystack is %NULL, no work will be done. + * - If the value pointed to by @haystack is %NULL, no work will be done. + * - If memory allocation failed, the value pointed to by @haystack WILL + * NOT be changed and NOT be g_free()'d. The caller will have to clean + * up. @new_size will not be touched. + * + * Otherwise, the return value will be non-%NULL: + * - If the value pointed to by @haystack does not contain @needle, a copy + * is avoided by returning the value pointed to by @haystack and setting + * the value pointed to by @haystack to %NULL. @free_orig will be ignored + * in this case. @new_size will not be touched. + * - Otherwise, the value pointed to by @haystack is g_free()'d and set to + * %NULL iff @free_orig is set to %TRUE and a copy up until the first + * occurrence of @needle returned. @new_size will be set to the truncated + * size iff it is not %NULL. + * + * Returns: either a copy of the original string up until the first occurrence + * of @needle or the value pointed to by @haystack (i.e., the + * original string) if @needle was not found, unless an error + * occurred + */ +gchar* x2goclient_strbrk_dup (gchar *restrict *haystack, const char needle, const _Bool free_orig, gsize * const new_size) { + gchar *ret = NULL; + + g_return_val_if_fail (((NULL != haystack) && (NULL != *haystack)), ret); + + const gchar *needle_pos = strchr (*haystack, needle); + + if (!(needle_pos)) { + /* Optimization: don't copy. */ + ret = *haystack; + *haystack = NULL; + } + else { + /* Since needle was found, the difference must be at least one. */ + g_assert (needle_pos - *haystack); + + gsize truncate_size = ((needle_pos - *haystack) - 1); + + /* Don't copy the needle. */ + ret = g_strndup (*haystack, truncate_size); + + if (ret) { + if (free_orig) { + /* Get rid of the original string. */ + g_free (*haystack); + *haystack = NULL; + } + + if (new_size) { + *new_size = truncate_size; + } + } + } + + return (ret); +} diff --git a/src/x2goclient-utils.h b/src/x2goclient-utils.h index 5b94e52..89e0425 100644 --- a/src/x2goclient-utils.h +++ b/src/x2goclient-utils.h @@ -52,6 +52,7 @@ G_BEGIN_DECLS void x2goclient_clear_strings (gpointer data); long long x2goclient_str_to_int (const gchar *restrict str, _Bool min, long long limit_min, _Bool max, long long limit_max, const gchar **restrict end, _Bool *restrict conv_err, _Bool *restrict min_err, _Bool *restrict max_err); +gchar* x2goclient_strbrk_dup (gchar *restrict *haystack, const char needle, const _Bool free_orig, gsize * const new_size); G_END_DECLS -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/libx2goclient.git