diff options
author | Werner Koch <[email protected]> | 2024-10-29 09:37:15 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2024-10-29 11:00:11 +0000 |
commit | c835676f7dfe39830d5b0500ad2cb809832428d1 (patch) | |
tree | ddb8f1016ff8bb67f7cef0bc5fedfdfd4b3c1eb3 | |
parent | qt: Fix typo (diff) | |
download | gpgme-c835676f7dfe39830d5b0500ad2cb809832428d1.tar.gz gpgme-c835676f7dfe39830d5b0500ad2cb809832428d1.zip |
core: Add new helper _gpgme_strtokenize.
* src/conversion.c (spacep): New.
(_gpgme_strtokenize): New.
--
Function taken from GnuPG and license changed to LGPL 2.1. The
version in GnuPG was entirely written by the author.
-rw-r--r-- | AUTHORS | 2 | ||||
-rw-r--r-- | src/conversion.c | 75 | ||||
-rw-r--r-- | src/util.h | 5 |
3 files changed, 81 insertions, 1 deletions
@@ -10,7 +10,7 @@ License (manual+tools): GPL-3.0-or-later GPGME is free software. See the files COPYING.LESSER and COPYING for -copying conditions, , and LICENSES for notices about contributions +copying conditions, and LICENSES for notices about contributions that require these additional notices to be distributed. License copyright years may be listed using range notation, e.g., 2000-2013, indicating that every year in the range, inclusive, is a copyrightable diff --git a/src/conversion.c b/src/conversion.c index 44636dd6..68b2e399 100644 --- a/src/conversion.c +++ b/src/conversion.c @@ -32,6 +32,7 @@ #include <time.h> #include <errno.h> #include <stdarg.h> +#include <assert.h> #include "gpgme.h" #include "util.h" @@ -40,6 +41,7 @@ #define atoi_1(p) (*(p) - '0' ) #define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1)) #define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2)) +#define spacep(p) (*(p) == ' ' || *(p) == '\t') @@ -414,6 +416,79 @@ _gpgme_split_fields (char *string, char **array, int arraysize) return n; } + +/* Tokenize STRING using the set of delimiters in DELIM into a NULL + * delimited array. Leading spaces and tabs are removed from all + * tokens if TRIM is set. The caller must free the result. + * + * Returns: A malloced and NULL delimited array with the tokens. On + * memory error NULL is returned and ERRNO is set. + */ +char ** +_gpgme_strtokenize (const char *string, const char *delim, int trim) +{ + const char *s; + size_t fields; + size_t bytes, n; + char *buffer; + char *p, *px, *pend; + char **result; + + /* Count the number of fields. */ + for (fields = 1, s = strpbrk (string, delim); s; s = strpbrk (s + 1, delim)) + fields++; + fields++; /* Add one for the terminating NULL. */ + + /* Allocate an array for all fields, a terminating NULL, and space + for a copy of the string. */ + bytes = fields * sizeof *result; + if (bytes / sizeof *result != fields) + { + gpg_err_set_errno (ENOMEM); + return NULL; + } + n = strlen (string) + 1; + bytes += n; + if (bytes < n) + { + gpg_err_set_errno (ENOMEM); + return NULL; + } + result = malloc (bytes); + if (!result) + return NULL; + buffer = (char*)(result + fields); + + /* Copy and parse the string. */ + strcpy (buffer, string); + for (n = 0, p = buffer; (pend = strpbrk (p, delim)); p = pend + 1) + { + *pend = 0; + if (trim) + { + while (spacep (p)) + p++; + for (px = pend - 1; px >= p && spacep (px); px--) + *px = 0; + } + result[n++] = p; + } + if (trim) + { + while (spacep (p)) + p++; + for (px = p + strlen (p) - 1; px >= p && spacep (px); px--) + *px = 0; + } + result[n++] = p; + result[n] = NULL; + + assert ((char*)(result + n + 1) == buffer); + + return result; +} + + /* Convert the field STRING into an unsigned long value. Check for * trailing garbage. */ gpgme_error_t @@ -140,6 +140,11 @@ gpgme_error_t _gpgme_encode_percent_string (const char *src, char **destp, * modifies STRING. The number of parsed fields is returned. */ int _gpgme_split_fields (char *string, char **array, int arraysize); +/* Tokenize STRING using the set of delimiters in DELIM into a NULL + * delimited array. Leading spaces and tabs are removed from all + * tokens if TRIM is set. The caller must free the result. */ +char **_gpgme_strtokenize (const char *string, const char *delim, int trim); + /* Convert the field STRING into an unsigned long value. Check for * trailing garbage. */ gpgme_error_t _gpgme_strtoul_field (const char *string, unsigned long *result); |