YAZ_EXPORT void nmem_strsplit_blank(NMEM nmem, 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
+ \param escape_char != 0, an escape char (could be \)
+*/
+YAZ_EXPORT void nmem_strsplit_escape(NMEM nmem, const char *delim,
+ const char *dstr,
+ char ***darray, int *num, int collapse,
+ int escape_char);
+
/** \brief allocates and sets integer for NMEM
\param nmem NMEM handle
\param v integer value
void nmem_strsplitx(NMEM nmem, const char *delim, const char *dstr,
char ***darray, int *num, int collapse)
{
- const char *cp = dstr;
- *num = 0;
+ nmem_strsplit_escape(nmem, delim, dstr, darray, num, collapse, 0);
+}
+void nmem_strsplit_escape(NMEM nmem, const char *delim, const char *dstr,
+ char ***darray, int *num, int collapse,
+ int escape_char)
+{
+ *darray = 0;
+ /* two passes over the input string.. */
while (1)
{
- 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;
- else
- {
size_t i = 0;
- *darray = (char **) nmem_malloc(nmem, *num * sizeof(**darray));
- cp = dstr;
+ const char *cp = dstr;
while (1)
{
const char *cp0;
{
if (!*cp)
break;
- while (*cp && strchr(delim, *cp))
+ while (*cp && strchr(delim, *cp) && *cp != escape_char)
cp++;
if (!*cp)
break;
cp0 = cp;
while (*cp && !strchr(delim, *cp))
+ {
+ if (*cp == escape_char)
+ cp++;
cp++;
- (*darray)[i++] = nmem_strdupn(nmem, cp0, cp - cp0);
+ }
+ if (*darray)
+ (*darray)[i] = nmem_strdupn(nmem, cp0, cp - cp0);
+ i++;
}
else
{
cp0 = cp;
while (*cp && !strchr(delim, *cp))
+ {
+ if (*cp == escape_char)
+ cp++;
cp++;
- (*darray)[i++] = nmem_strdupn(nmem, cp0, cp - cp0);
+ }
+ if (*darray)
+ (*darray)[i] = nmem_strdupn(nmem, cp0, cp - cp0);
+ i++;
if (!*cp)
break;
cp++;
}
}
+ *num = i;
+ if (!*num)
+ break; /* no items, so stop, *darray=0 already */
+ else if (*darray)
+ break; /* second pass, stop */
+ *darray = (char **) nmem_malloc(nmem, *num * sizeof(**darray));
}
}
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_strsplit_escape(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 > 3 && !strcmp(array[3], ""));
YAZ_CHECK(num > 4 && !strcmp(array[4], "cd"));
+ nmem_strsplit_escape(nmem, ",", ",a,b\\,,cd", &array, &num, 0, '\\');
+ YAZ_CHECK(num == 4);
+ 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], "cd"));
+
+ nmem_strsplit_escape(nmem, ",", "\\,a,b\\,,cd", &array, &num, 0, '\\');
+ 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_strsplit_escape(nmem, ",", "\\,a,b\\,\\,cd", &array, &num, 0, '\\');
+ YAZ_CHECK(num == 2);
+ YAZ_CHECK(num > 0 && !strcmp(array[0], "\\,a"));
+ YAZ_CHECK(num > 1 && !strcmp(array[1], "b\\,\\,cd"));
+
nmem_destroy(nmem);
}