Commit e56aab98 authored by Daniel Verkamp's avatar Daniel Verkamp
Browse files

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: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent c5611b26
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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
+66 −0
Original line number Diff line number Diff line
@@ -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;
}