summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2016-02-18 15:37:32 +0100
committerWerner Koch <wk@gnupg.org>2016-02-19 14:35:25 +0100
commit4e134b6e77f558730ec1eceb6b816b0bcfd845e9 (patch)
tree3c263565162e3495bfd5354afecbd62ad7bdc7e3
parentfd13372fa9069d3a72947ea59c57e33637c936bf (diff)
downloadlibgcrypt-4e134b6e77f558730ec1eceb6b816b0bcfd845e9.tar.gz
Add helper function _gcry_strtokenize.
* src/misc.c (_gcry_strtokenize): New. -- The code has been taken from GnuPG and re-licensed to LPGLv2+ by me as its original author. Minor changes for use in Libgcrypt. Signed-off-by: Werner Koch <wk@gnupg.org>
-rw-r--r--src/g10lib.h3
-rw-r--r--src/misc.c73
2 files changed, 76 insertions, 0 deletions
diff --git a/src/g10lib.h b/src/g10lib.h
index a579e945..9d2ece9c 100644
--- a/src/g10lib.h
+++ b/src/g10lib.h
@@ -189,6 +189,9 @@ int _gcry_log_verbosity( int level );
/* Compatibility macro. */
#define log_mpidump _gcry_log_printmpi
+/* Tokeninze STRING and return a malloced array. */
+char **_gcry_strtokenize (const char *string, const char *delim);
+
/*-- src/hwfeatures.c --*/
/* (Do not change these values unless synced with the asm code.) */
diff --git a/src/misc.c b/src/misc.c
index b3c56e29..ac64d703 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -436,6 +436,79 @@ _gcry_log_printsxp (const char *text, gcry_sexp_t sexp)
}
+/*
+ * Tokenize STRING using the set of delimiters in DELIM. Leading
+ * white spaces are removed from all tokens. The caller must xfree
+ * the result.
+ *
+ * Returns: A malloced and NULL delimited array with the tokens. On
+ * memory error NULL is returned and ERRNO is set.
+ */
+char **
+_gcry_strtokenize (const char *string, const char *delim)
+{
+ const char *s;
+ size_t fields;
+ size_t bytes, n;
+ char *buffer;
+ char *p, *px, *pend;
+ char **result;
+ char const ws[] = " \t\v\f\r\n";
+
+ if (!delim)
+ delim = ws;
+
+ /* 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 = xtrymalloc (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;
+ while (strchr (ws, *(byte*)p))
+ p++;
+ for (px = pend - 1; px >= p && strchr (ws, *(byte*)px); px--)
+ *px = 0;
+ result[n++] = p;
+ }
+ while (*p && strchr (ws, *(byte*)p))
+ p++;
+ for (px = p + strlen (p) - 1; px >= p && strchr (ws, *(byte*)px); px--)
+ *px = 0;
+ /* Traling spaces may result in an empty field. We do not want to
+ store that. */
+ result[n++] = *p? p : NULL;
+ result[n] = NULL;
+
+ gcry_assert ((char*)(result + n + 1) == buffer);
+
+ return result;
+}
+
+
void
__gcry_burn_stack (unsigned int bytes)
{