Patchwork [1/6] Introduce helpers.c and unquote_string().

login
register
about
Submitter Stefan Tauner
Date 2013-09-23 23:14:01
Message ID <1379978046-32403-2-git-send-email-stefan.tauner@student.tuwien.ac.at>
Download mbox | patch
Permalink /patch/4069/
State New
Headers show

Comments

Stefan Tauner - 2013-09-23 23:14:01
The unquoting function is the first to be moved to the new file which will
host various utility functions to be shared by multiple files but which do not
fit elsewhere.

unquote_string() extracts a possibly quoted phrase from a string by
using a set of separator characters, which is useful to allow user input
to be optionally quoted to support spaces within names such a region or
file names.

Signed-off-by: Stefan Tauner <stefan.tauner@student.tuwien.ac.at>
---
 Makefile  |  2 +-
 flash.h   |  3 +++
 helpers.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 92 insertions(+), 1 deletion(-)
 create mode 100644 helpers.c

Patch

diff --git a/Makefile b/Makefile
index 346d46a..69e0b9c 100644
--- a/Makefile
+++ b/Makefile
@@ -338,7 +338,7 @@  CHIP_OBJS = jedec.o stm50.o w39.o w29ee011.o \
 ###############################################################################
 # Library code.
 
-LIB_OBJS = layout.o flashrom.o udelay.o programmer.o
+LIB_OBJS = layout.o flashrom.o udelay.o programmer.o helpers.o
 
 ###############################################################################
 # Frontend related stuff.
diff --git a/flash.h b/flash.h
index e320ced..a942b9b 100644
--- a/flash.h
+++ b/flash.h
@@ -264,6 +264,9 @@  int doit(struct flashctx *flash, int force, const char *filename, int read_it, i
 int read_buf_from_file(unsigned char *buf, unsigned long size, const char *filename);
 int write_buf_to_file(unsigned char *buf, unsigned long size, const char *filename);
 
+/* helpers.c */
+int unquote_string(char **startp, char **endp, const char *delimiters);
+
 enum test_state {
 	OK = 0,
 	NT = 1,	/* Not tested */
diff --git a/helpers.c b/helpers.c
new file mode 100644
index 0000000..ba82a0f
--- /dev/null
+++ b/helpers.c
@@ -0,0 +1,88 @@ 
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2013 Carl-Daniel Hailfinger
+ * Copyright (C) 2013 Stefan Tauner
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <string.h>
+#include "flash.h"
+
+/** Parse a \em possibly quoted string.
+ *
+ * \a startp points to the string which should be parsed. If the string does not start with a quote, it is
+ * terminated at the first character contained in \a delimiters by replacing it with '\0'. If the string starts
+ * with a quote, it is terminated at the second quote by replacing it with '\0'. In the latter case a character
+ * contained in \a delimiters has to follow the terminating quote.
+ *
+ * If \a delimiters is NULL an empty set is assumed.
+ *
+ * After returning \a startp will point to a string that is either the first quoted part of the
+ * original string with the quotation marks removed, or the first word of that string before any delimiter.
+ *
+ * If \a endp is not NULL it will be set to point to the first character after the parsed string
+ * (i.e. a delimiter), or to the '\0' at the end of the string if there are no more subsequent characters.
+ *
+ * @param start		Points to the input string.
+ * @param end		Is set to the first char following the input string (possibly NULL).
+ * @param delimiters	Set of characters which terminate a string (possibly NULL).
+ * @return		-1 if a quotation mark is not matched,
+ *			0 on success,
+ *			1 if the parsed string is empty.
+ */
+int unquote_string(char **startp, char **endp, const char *delimiters)
+{
+	msg_gspew("unquoting \'%s\'\n", *startp);
+
+	if (delimiters == NULL)
+		delimiters = "";
+
+	char *end;
+	if (**startp == '"') {
+		(*startp)++;
+		size_t len = strcspn(*startp, "\"");
+		end = *startp + len + 1;
+		/* Catch unclosed quotes and string not followed immediately by delimiter or end-of-string. */
+		if ((*startp)[len] == '\0' && strcspn(end, delimiters) != 0)
+			return -1;
+		
+		/* Eliminate closing quote. */
+		(*startp)[len] = '\0';
+	} else {
+		size_t len = strcspn(*startp, delimiters);
+		/* Check for (forbidden) quotes in the middle. */
+		if (strcspn(*startp, "\"") < len)
+			return -1;
+		end = *startp + len;
+	}
+
+	/* end points to the first character after the (possibly quoted) string, i.e. the delimiter or \0. */
+	if (*end != '\0') {
+		*end = '\0';
+		end++;
+	}
+	if (endp != NULL)
+		*endp = end;
+
+	if (strlen(*startp) == 0) {
+		*startp = '\0';
+		return 1;
+	}
+
+	msg_gspew("%s: start=\'%s\', end=\'%s\'\n", __func__, *startp, end);
+	return 0;
+}