From 7d7e192def2fef342d235ea894eddb1e89edd714 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 13 May 2011 15:18:40 +0200 Subject: [PATCH] Add new function nmem_strsplitx. This is like nmem_strsplitx but allows us to specify whether to collapse delimitors or not. The existing nmem_strsplit do collapse (collapse parameter = 1). --- include/yaz/nmem.h | 13 ++++++++++ src/nmemsdup.c | 68 +++++++++++++++++++++++++++++++++++++++++----------- test/test_nmem.c | 44 ++++++++++++++++++++++++++++++++-- 3 files changed, 109 insertions(+), 16 deletions(-) diff --git a/include/yaz/nmem.h b/include/yaz/nmem.h index 70dad4e..c12ddc0 100644 --- a/include/yaz/nmem.h +++ b/include/yaz/nmem.h @@ -112,6 +112,19 @@ YAZ_EXPORT void nmem_strsplit(NMEM nmem, const char *delim, const char *dstr, char ***darray, int *num); +/** \brief allocates sub strings out of string using certain delimitors + \param nmem NMEM handle + \param delim delimitor chars (splits on each char in there) + \param dstr string to be split + \param darray result string array for each sub string + \param num number of result strings + \param collapse 1=collapse multiple delims to one; 0=no collapse +*/ +YAZ_EXPORT void nmem_strsplitx(NMEM nmem, const char *delim, + const char *dstr, + char ***darray, int *num, + int collapse); + /** \brief splits string into sub strings delimited by blanks \param nmem NMEM handle \param dstr string to be split diff --git a/src/nmemsdup.c b/src/nmemsdup.c index 3c1c4e1..f697e73 100644 --- a/src/nmemsdup.c +++ b/src/nmemsdup.c @@ -57,18 +57,42 @@ void nmem_strsplit_blank(NMEM nmem, const char *dstr, char ***darray, int *num) nmem_strsplit(nmem, " ", dstr, darray, num); } + void nmem_strsplit(NMEM nmem, const char *delim, const char *dstr, char ***darray, int *num) { + nmem_strsplitx(nmem, delim, dstr, darray, num, 1); +} + +void nmem_strsplitx(NMEM nmem, const char *delim, const char *dstr, + char ***darray, int *num, int collapse) +{ const char *cp = dstr; - for (*num = 0; *cp; (*num)++) + *num = 0; + + while (1) { - while (*cp && strchr(delim, *cp)) - cp++; - if (!*cp) - break; - while (*cp && !strchr(delim, *cp)) + if (collapse) + { + if (!*cp) + break; + while (*cp && strchr(delim, *cp)) + cp++; + if (!*cp) + break; + while (*cp && !strchr(delim, *cp)) + cp++; + (*num)++; + } + else + { + (*num)++; + while (*cp && !strchr(delim, *cp)) + cp++; + if (!*cp) + break; cp++; + } } if (!*num) *darray = 0; @@ -76,17 +100,33 @@ void nmem_strsplit(NMEM nmem, const char *delim, const char *dstr, { size_t i = 0; *darray = (char **) nmem_malloc(nmem, *num * sizeof(**darray)); - for (cp = dstr; *cp; ) + cp = dstr; + while (1) { const char *cp0; - while (*cp && strchr(delim, *cp)) - cp++; - if (!*cp) - break; - cp0 = cp; - while (*cp && !strchr(delim, *cp)) + if (collapse) + { + if (!*cp) + break; + while (*cp && strchr(delim, *cp)) + cp++; + if (!*cp) + break; + cp0 = cp; + while (*cp && !strchr(delim, *cp)) + cp++; + (*darray)[i++] = nmem_strdupn(nmem, cp0, cp - cp0); + } + else + { + cp0 = cp; + while (*cp && !strchr(delim, *cp)) + cp++; + (*darray)[i++] = nmem_strdupn(nmem, cp0, cp - cp0); + if (!*cp) + break; cp++; - (*darray)[i++] = nmem_strdupn(nmem, cp0, cp - cp0); + } } } } diff --git a/test/test_nmem.c b/test/test_nmem.c index 61c0739..027b823 100644 --- a/test/test_nmem.c +++ b/test/test_nmem.c @@ -14,7 +14,7 @@ #include #include -void tst(void) +void tst_nmem_malloc(void) { NMEM n; int j; @@ -45,10 +45,50 @@ void tst(void) nmem_destroy(n); } +void tst_nmem_strsplit(void) +{ + NMEM nmem = nmem_create(); + int num = 0; + char **array = 0; + + nmem_strsplit(nmem, ",", "", &array, &num); + YAZ_CHECK(num == 0); + + nmem_strsplitx(nmem, ",", "", &array, &num, 0); + YAZ_CHECK(num == 1); + YAZ_CHECK(num > 0 && !strcmp(array[0], "")); + + nmem_strsplit(nmem, ",", ",,", &array, &num); + YAZ_CHECK(num == 0); + + nmem_strsplitx(nmem, ",", ",,", &array, &num, 0); + YAZ_CHECK(num == 3); + YAZ_CHECK(num > 0 && !strcmp(array[0], "")); + YAZ_CHECK(num > 1 && !strcmp(array[1], "")); + YAZ_CHECK(num > 2 && !strcmp(array[2], "")); + + nmem_strsplit(nmem, ",", ",a,b,,cd", &array, &num); + YAZ_CHECK(num == 3); + YAZ_CHECK(num > 0 && !strcmp(array[0], "a")); + YAZ_CHECK(num > 1 && !strcmp(array[1], "b")); + YAZ_CHECK(num > 2 && !strcmp(array[2], "cd")); + nmem_strsplitx(nmem, ",", ",a,b,,cd", &array, &num, 0); + + YAZ_CHECK(num == 5); + YAZ_CHECK(num > 0 && !strcmp(array[0], "")); + YAZ_CHECK(num > 1 && !strcmp(array[1], "a")); + YAZ_CHECK(num > 2 && !strcmp(array[2], "b")); + YAZ_CHECK(num > 3 && !strcmp(array[3], "")); + YAZ_CHECK(num > 4 && !strcmp(array[4], "cd")); + + nmem_destroy(nmem); +} + int main (int argc, char **argv) { YAZ_CHECK_INIT(argc, argv); - tst(); + tst_nmem_malloc(); + tst_nmem_strsplit(); YAZ_CHECK_TERM; } /* -- 1.7.10.4