lib/util: add spdk_strsepq()

Parsing function for delimited strings with embedded quotes.

Originally based on code imported from istgt.

Change-Id: I448feb53ea232048ed8c68738e12bc3660eb4235
Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Daniel Verkamp 2016-04-28 16:39:47 -07:00
parent c5611b26b3
commit e56aab98ac
2 changed files with 79 additions and 0 deletions

View File

@ -54,6 +54,19 @@ char *spdk_sprintf_alloc(const char *format, ...) __attribute__((format(printf,
*/
char *spdk_strlwr(char *s);
/**
* Parse a delimited string with quote handling.
*
* \param stringp Pointer to starting location in string. *stringp will be updated to point to the
* start of the next field, or NULL if the end of the string has been reached.
* \param delim Null-terminated string containing the list of accepted delimiters.
*
* \return Pointer to beginning of the current field.
*
* Note that the string will be modified in place to add the string terminator to each field.
*/
char *spdk_strsepq(char **stringp, const char *delim);
#ifdef __cplusplus
}
#endif

View File

@ -35,6 +35,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "spdk/string.h"
@ -100,3 +101,68 @@ spdk_strlwr(char *s)
return s;
}
char *
spdk_strsepq(char **stringp, const char *delim)
{
char *p, *q, *r;
int quoted = 0, bslash = 0;
p = *stringp;
if (p == NULL) {
return NULL;
}
r = q = p;
while (*q != '\0' && *q != '\n') {
/* eat quoted characters */
if (bslash) {
bslash = 0;
*r++ = *q++;
continue;
} else if (quoted) {
if (quoted == '"' && *q == '\\') {
bslash = 1;
q++;
continue;
} else if (*q == quoted) {
quoted = 0;
q++;
continue;
}
*r++ = *q++;
continue;
} else if (*q == '\\') {
bslash = 1;
q++;
continue;
} else if (*q == '"' || *q == '\'') {
quoted = *q;
q++;
continue;
}
/* separator? */
if (strchr(delim, *q) == NULL) {
*r++ = *q++;
continue;
}
/* new string */
q++;
break;
}
*r = '\0';
/* skip tailer */
while (*q != '\0' && strchr(delim, *q) != NULL) {
q++;
}
if (*q != '\0') {
*stringp = q;
} else {
*stringp = NULL;
}
return p;
}