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.
This commit is contained in:
Werner Koch 2024-10-29 10:37:15 +01:00
parent e656e51d53
commit c835676f7d
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
3 changed files with 81 additions and 1 deletions

View File

@ -10,7 +10,7 @@ License (manual+tools): GPL-3.0-or-later
GPGME is free software. See the files COPYING.LESSER and COPYING for 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 that require these additional notices to be distributed. License
copyright years may be listed using range notation, e.g., 2000-2013, copyright years may be listed using range notation, e.g., 2000-2013,
indicating that every year in the range, inclusive, is a copyrightable indicating that every year in the range, inclusive, is a copyrightable

View File

@ -32,6 +32,7 @@
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
#include <stdarg.h> #include <stdarg.h>
#include <assert.h>
#include "gpgme.h" #include "gpgme.h"
#include "util.h" #include "util.h"
@ -40,6 +41,7 @@
#define atoi_1(p) (*(p) - '0' ) #define atoi_1(p) (*(p) - '0' )
#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1)) #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 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; 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 /* Convert the field STRING into an unsigned long value. Check for
* trailing garbage. */ * trailing garbage. */
gpgme_error_t gpgme_error_t

View File

@ -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. */ * modifies STRING. The number of parsed fields is returned. */
int _gpgme_split_fields (char *string, char **array, int arraysize); 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 /* Convert the field STRING into an unsigned long value. Check for
* trailing garbage. */ * trailing garbage. */
gpgme_error_t _gpgme_strtoul_field (const char *string, unsigned long *result); gpgme_error_t _gpgme_strtoul_field (const char *string, unsigned long *result);