]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tools: add new functions to quote-encode strings
authorWilly Tarreau <w@1wt.eu>
Mon, 16 Jun 2014 13:16:40 +0000 (15:16 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 16 Jun 2014 16:20:14 +0000 (18:20 +0200)
qstr() and cstr() will be used to quote-encode strings. The first one
does it unconditionally. The second one is aimed at CSV files where the
quote-encoding is only needed when the field contains a quote or a comma.

include/common/standard.h
src/standard.c

index ecac1e02e4981e77d33bc831b0e1b3c4da9da049..8811c6f91a62821f254c1f1e27d15b0d7d6ae221 100644 (file)
 /* number of itoa_str entries */
 #define NB_ITOA_STR    10
 
+/* maximum quoted string length (truncated above) */
+#define QSTR_SIZE 200
+#define NB_QSTR 10
+
 /****** string-specific macros and functions ******/
 /* if a > max, then bound <a> to <max>. The macro returns the new <a> */
 #define UBOUND(a, max) ({ typeof(a) b = (max); if ((a) > b) (a) = b; (a); })
@@ -195,6 +199,29 @@ static inline const char *LIM2A(unsigned long n, const char *alt)
        return ret;
 }
 
+/* returns a locally allocated string containing the quoted encoding of the
+ * input string. The output may be truncated to QSTR_SIZE chars, but it is
+ * guaranteed that the string will always be properly terminated. Quotes are
+ * encoded by doubling them as is commonly done in CSV files. QSTR_SIZE must
+ * always be at least 4 chars.
+ */
+const char *qstr(const char *str);
+
+/* returns <str> or its quote-encoded equivalent if it contains at least one
+ * quote or a comma. This is aimed at build CSV-compatible strings.
+ */
+static inline const char *cstr(const char *str)
+{
+       const char *p = str;
+
+       while (*p) {
+               if (*p == ',' || *p == '"')
+                       return qstr(str);
+               p++;
+       }
+       return str;
+}
+
 /*
  * Returns non-zero if character <s> is a hex digit (0-9, a-f, A-F), else zero.
  */
index b0c5fe6eb23488cf7a576b02a117cf3359cc678a..f57724c4a14e11d001925c188492848c754a37d7 100644 (file)
 char itoa_str[NB_ITOA_STR][171];
 int itoa_idx = 0; /* index of next itoa_str to use */
 
+/* sometimes we'll need to quote strings (eg: in stats), and we don't expect
+ * to quote strings larger than a max configuration line.
+ */
+char quoted_str[NB_QSTR][QSTR_SIZE + 1];
+int quoted_idx = 0;
+
 /*
  * unsigned long long ASCII representation
  *
@@ -444,6 +450,39 @@ const char *limit_r(unsigned long n, char *buffer, int size, const char *alt)
        return (n) ? ultoa_r(n, buffer, size) : (alt ? alt : "");
 }
 
+/* returns a locally allocated string containing the quoted encoding of the
+ * input string. The output may be truncated to QSTR_SIZE chars, but it is
+ * guaranteed that the string will always be properly terminated. Quotes are
+ * encoded by doubling them as is commonly done in CSV files. QSTR_SIZE must
+ * always be at least 4 chars.
+ */
+const char *qstr(const char *str)
+{
+       char *ret = quoted_str[quoted_idx];
+       char *p, *end;
+
+       if (++quoted_idx >= NB_QSTR)
+               quoted_idx = 0;
+
+       p = ret;
+       end = ret + QSTR_SIZE;
+
+       *p++ = '"';
+
+       /* always keep 3 chars to support passing "" and the ending " */
+       while (*str && p < end - 3) {
+               if (*str == '"') {
+                       *p++ = '"';
+                       *p++ = '"';
+               }
+               else
+                       *p++ = *str;
+               str++;
+       }
+       *p++ = '"';
+       return ret;
+}
+
 /*
  * Returns non-zero if character <s> is a hex digit (0-9, a-f, A-F), else zero.
  *