aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2024-10-29 09:37:15 +0000
committerWerner Koch <[email protected]>2024-10-29 11:00:11 +0000
commitc835676f7dfe39830d5b0500ad2cb809832428d1 (patch)
treeddb8f1016ff8bb67f7cef0bc5fedfdfd4b3c1eb3
parentqt: Fix typo (diff)
downloadgpgme-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--AUTHORS2
-rw-r--r--src/conversion.c75
-rw-r--r--src/util.h5
3 files changed, 81 insertions, 1 deletions
diff --git a/AUTHORS b/AUTHORS
index fcdba612..0663b204 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -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
diff --git a/src/util.h b/src/util.h
index 03b800a0..ea92440a 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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);