summaryrefslogtreecommitdiffstats
path: root/freebsd/contrib/libxo/libxo/libxo.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-21 13:47:02 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:41 +0200
commitbcdce02d9bc8150e1d191ed5ca9da45b7604964a (patch)
tree3b2faf509db7672ee1fc98857736470be97e7ed8 /freebsd/contrib/libxo/libxo/libxo.c
parentUpdate to FreeBSD head 2018-04-01 (diff)
downloadrtems-libbsd-bcdce02d9bc8150e1d191ed5ca9da45b7604964a.tar.bz2
Update to FreeBSD head 2018-06-01
Git mirror commit fb63610a69b0eb7f69a201ba05c4c1a7a2739cf9. Update #3472.
Diffstat (limited to 'freebsd/contrib/libxo/libxo/libxo.c')
-rw-r--r--freebsd/contrib/libxo/libxo/libxo.c59
1 files changed, 56 insertions, 3 deletions
diff --git a/freebsd/contrib/libxo/libxo/libxo.c b/freebsd/contrib/libxo/libxo/libxo.c
index 4577adb2..2a78aea1 100644
--- a/freebsd/contrib/libxo/libxo/libxo.c
+++ b/freebsd/contrib/libxo/libxo/libxo.c
@@ -4182,6 +4182,59 @@ xo_format_title (xo_handle_t *xop, xo_field_info_t *xfip,
}
}
+/*
+ * strspn() with a string length
+ */
+static ssize_t
+xo_strnspn (const char *str, size_t len, const char *accept)
+{
+ ssize_t i;
+ const char *cp, *ep;
+
+ for (i = 0, cp = str, ep = str + len; cp < ep && *cp != '\0'; i++, cp++) {
+ if (strchr(accept, *cp) == NULL)
+ break;
+ }
+
+ return i;
+}
+
+/*
+ * Decide if a format string should be considered "numeric",
+ * in the sense that the number does not need to be quoted.
+ * This means that it consists only of a single numeric field
+ * with nothing exotic or "interesting". This means that
+ * static values are never considered numeric.
+ */
+static int
+xo_format_is_numeric (const char *fmt, ssize_t flen)
+{
+ if (flen <= 0 || *fmt++ != '%') /* Must start with '%' */
+ return FALSE;
+ flen -= 1;
+
+ /* Handle leading flags; don't want "#" since JSON can't handle hex */
+ ssize_t spn = xo_strnspn(fmt, flen, "0123456789.*+ -");
+ if (spn >= flen)
+ return FALSE;
+
+ fmt += spn; /* Move along the input string */
+ flen -= spn;
+
+ /* Handle the length modifiers */
+ spn = xo_strnspn(fmt, flen, "hljtqz");
+ if (spn >= flen)
+ return FALSE;
+
+ fmt += spn; /* Move along the input string */
+ flen -= spn;
+
+ if (flen != 1) /* Should only be one character left */
+ return FALSE;
+
+ return (strchr("diouDOUeEfFgG", *fmt) == NULL) ? FALSE : TRUE;
+}
+
static void
xo_format_prep (xo_handle_t *xop, xo_xff_flags_t flags)
{
@@ -4410,10 +4463,10 @@ xo_format_value (xo_handle_t *xop, const char *name, ssize_t nlen,
quote = 0;
fmt = "true"; /* JSON encodes empty tags as a boolean true */
flen = 4;
- } else if (strchr("diouDOUeEfFgG", fmt[flen - 1]) == NULL)
- quote = 1;
- else
+ } else if (xo_format_is_numeric(fmt, flen))
quote = 0;
+ else
+ quote = 1;
if (nlen == 0) {
static char missing[] = "missing-field-name";