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
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; +}