From a019bc48fd683667ee32e33d872b5d7037a16acf Mon Sep 17 00:00:00 2001 From: Gerhard Sittig Date: Wed, 7 Nov 2018 20:22:54 +0100 Subject: [PATCH] scpi: introduce string un-quote helper routine The SCPI protocol may communicate strings in quoted form, enclosed by a matching pair of single or double quote characters, and occurances of this very quote character within the string get doubled (escaped). Add a common routine to undo the quotes. --- src/scpi.h | 2 ++ src/scpi/scpi.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/scpi.h b/src/scpi.h index e55d36f1..13b2d301 100644 --- a/src/scpi.h +++ b/src/scpi.h @@ -149,6 +149,8 @@ SR_PRIV int sr_scpi_get_hw_id(struct sr_scpi_dev_inst *scpi, struct sr_scpi_hw_info **scpi_response); SR_PRIV void sr_scpi_hw_info_free(struct sr_scpi_hw_info *hw_info); +SR_PRIV const char *sr_scpi_unquote_string(char *s); + SR_PRIV const char *sr_vendor_alias(const char *raw_vendor); SR_PRIV const char *sr_scpi_cmd_get(const struct scpi_command *cmdtable, int command); diff --git a/src/scpi/scpi.c b/src/scpi/scpi.c index 37004786..a01e13e0 100644 --- a/src/scpi/scpi.c +++ b/src/scpi/scpi.c @@ -1139,6 +1139,48 @@ SR_PRIV void sr_scpi_hw_info_free(struct sr_scpi_hw_info *hw_info) g_free(hw_info); } +/** + * Remove potentially enclosing pairs of quotes, un-escape content. + * This implementation modifies the caller's buffer when quotes are found + * and doubled quote characters need to get removed from the content. + * + * @param[in, out] s The SCPI string to check and un-quote. + * + * @return The start of the un-quoted string. + */ +SR_PRIV const char *sr_scpi_unquote_string(char *s) +{ + size_t s_len; + char quotes[3]; + char *rdptr; + + /* Immediately bail out on invalid or short input. */ + if (!s || !*s) + return s; + s_len = strlen(s); + if (s_len < 2) + return s; + + /* Check for matching quote characters front and back. */ + if (s[0] != '\'' && s[0] != '"') + return s; + if (s[0] != s[s_len - 1]) + return s; + + /* Need to strip quotes, and un-double quote chars inside. */ + quotes[0] = quotes[1] = *s; + quotes[2] = '\0'; + s[s_len - 1] = '\0'; + s++; + rdptr = s; + while ((rdptr = strstr(rdptr, quotes)) != NULL) { + memmove(rdptr, rdptr + 1, strlen(rdptr)); + rdptr++; + } + + return s; +} + SR_PRIV const char *sr_vendor_alias(const char *raw_vendor) { unsigned int i;