commit - ddbcd3c13f2159113bb7e9921a1bec13755c5d43
commit + d13b044d59619a52277c229eb37d38265690fb64
blob - f820f71c219debfb93731a6abbb6ea5fb284f4fc
blob + 65ec3ef2b2dce2eda370c789d62e7c02b6eadb74
--- compat/Makefile
+++ compat/Makefile
strlcpy.c \
strtonum.c \
tree.h \
- vasprintf.c
+ vasprintf.c \
+ vis.c
all:
false
dist: ${DISTFILES}
mkdir -p ${DESTDIR}/
${INSTALL} -m 0644 ${DISTFILES} ${DESTDIR}/
+ mkdir -p ${DESTDIR}/vis
+ ${INSTALL} -m 0644 vis/vis.h ${DESTDIR}/vis
.PHONY: all dist
include ../config.mk
blob - /dev/null
blob + 59b7d6b81777229668dfbb0bb1aaaca8e126eb8c (mode 644)
--- /dev/null
+++ compat/vis/vis.h
+/* $OpenBSD: vis.h,v 1.15 2015/07/20 01:52:27 millert Exp $ */
+/* $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)vis.h 5.9 (Berkeley) 4/3/91
+ */
+
+#ifndef _VIS_H_
+#define _VIS_H_
+
+/*
+ * to select alternate encoding format
+ */
+#define VIS_OCTAL 0x01 /* use octal \ddd format */
+#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropriate */
+
+/*
+ * to alter set of characters encoded (default is to encode all
+ * non-graphic except space, tab, and newline).
+ */
+#define VIS_SP 0x04 /* also encode space */
+#define VIS_TAB 0x08 /* also encode tab */
+#define VIS_NL 0x10 /* also encode newline */
+#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
+#define VIS_SAFE 0x20 /* only encode "unsafe" characters */
+#define VIS_DQ 0x200 /* backslash-escape double quotes */
+#define VIS_ALL 0x400 /* encode all characters */
+
+/*
+ * other
+ */
+#define VIS_NOSLASH 0x40 /* inhibit printing '\' */
+#define VIS_GLOB 0x100 /* encode glob(3) magics and '#' */
+
+/*
+ * unvis return codes
+ */
+#define UNVIS_VALID 1 /* character valid */
+#define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */
+#define UNVIS_NOCHAR 3 /* valid sequence, no character produced */
+#define UNVIS_SYNBAD -1 /* unrecognized escape sequence */
+#define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */
+
+/*
+ * unvis flags
+ */
+#define UNVIS_END 1 /* no more characters */
+
+#include <sys/cdefs.h>
+
+char *vis(char *, int, int, int);
+int strvis(char *, const char *, int);
+int stravis(char **, const char *, int);
+int strnvis(char *, const char *, size_t, int)
+ __attribute__ ((__bounded__(__string__,1,3)));
+int strvisx(char *, const char *, size_t, int)
+ __attribute__ ((__bounded__(__string__,1,3)));
+int strunvis(char *, const char *);
+int unvis(char *, char, int *, int);
+ssize_t strnunvis(char *, const char *, size_t)
+ __attribute__ ((__bounded__(__string__,1,3)));
+
+#endif /* !_VIS_H_ */
blob - /dev/null
blob + 9ebdc7207f5acf508340c7b3737f3cf990c49b84 (mode 644)
--- /dev/null
+++ compat/vis.c
+/* $OpenBSD: vis.c,v 1.26 2022/05/04 18:57:50 deraadt Exp $ */
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <ctype.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+#include <vis.h>
+
+static int
+isoctal(int c)
+{
+ u_char uc = c;
+
+ return uc >= '0' && uc <= '7';
+}
+
+static int
+isvisible(int c, int flag)
+{
+ int vis_sp = flag & VIS_SP;
+ int vis_tab = flag & VIS_TAB;
+ int vis_nl = flag & VIS_NL;
+ int vis_safe = flag & VIS_SAFE;
+ int vis_glob = flag & VIS_GLOB;
+ int vis_all = flag & VIS_ALL;
+ u_char uc = c;
+
+ if (c == '\\' || !vis_all) {
+ if ((u_int)c <= UCHAR_MAX && isascii(uc) &&
+ ((c != '*' && c != '?' && c != '[' && c != '#') || !vis_glob) &&
+ isgraph(uc))
+ return 1;
+ if (!vis_sp && c == ' ')
+ return 1;
+ if (!vis_tab && c == '\t')
+ return 1;
+ if (!vis_nl && c == '\n')
+ return 1;
+ if (vis_safe && (c == '\b' || c == '\007' || c == '\r' || isgraph(uc)))
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * vis - visually encode characters
+ */
+char *
+vis(char *dst, int c, int flag, int nextc)
+{
+ int vis_dq = flag & VIS_DQ;
+ int vis_noslash = flag & VIS_NOSLASH;
+ int vis_cstyle = flag & VIS_CSTYLE;
+ int vis_octal = flag & VIS_OCTAL;
+ int vis_glob = flag & VIS_GLOB;
+
+ if (isvisible(c, flag)) {
+ if ((c == '"' && vis_dq) ||
+ (c == '\\' && !vis_noslash))
+ *dst++ = '\\';
+ *dst++ = c;
+ *dst = '\0';
+ return (dst);
+ }
+
+ if (vis_cstyle) {
+ switch (c) {
+ case '\n':
+ *dst++ = '\\';
+ *dst++ = 'n';
+ goto done;
+ case '\r':
+ *dst++ = '\\';
+ *dst++ = 'r';
+ goto done;
+ case '\b':
+ *dst++ = '\\';
+ *dst++ = 'b';
+ goto done;
+ case '\a':
+ *dst++ = '\\';
+ *dst++ = 'a';
+ goto done;
+ case '\v':
+ *dst++ = '\\';
+ *dst++ = 'v';
+ goto done;
+ case '\t':
+ *dst++ = '\\';
+ *dst++ = 't';
+ goto done;
+ case '\f':
+ *dst++ = '\\';
+ *dst++ = 'f';
+ goto done;
+ case ' ':
+ *dst++ = '\\';
+ *dst++ = 's';
+ goto done;
+ case '\0':
+ *dst++ = '\\';
+ *dst++ = '0';
+ if (isoctal(nextc)) {
+ *dst++ = '0';
+ *dst++ = '0';
+ }
+ goto done;
+ }
+ }
+ if (((c & 0177) == ' ') || vis_octal ||
+ (vis_glob && (c == '*' || c == '?' || c == '[' || c == '#'))) {
+ *dst++ = '\\';
+ *dst++ = ((u_char)c >> 6 & 07) + '0';
+ *dst++ = ((u_char)c >> 3 & 07) + '0';
+ *dst++ = ((u_char)c & 07) + '0';
+ goto done;
+ }
+ if (!vis_noslash)
+ *dst++ = '\\';
+ if (c & 0200) {
+ c &= 0177;
+ *dst++ = 'M';
+ }
+ if (iscntrl((u_char)c)) {
+ *dst++ = '^';
+ if (c == 0177)
+ *dst++ = '?';
+ else
+ *dst++ = c + '@';
+ } else {
+ *dst++ = '-';
+ *dst++ = c;
+ }
+done:
+ *dst = '\0';
+ return (dst);
+}
+
+/*
+ * strvis, strnvis, strvisx - visually encode characters from src into dst
+ *
+ * Dst must be 4 times the size of src to account for possible
+ * expansion. The length of dst, not including the trailing NULL,
+ * is returned.
+ *
+ * Strnvis will write no more than siz-1 bytes (and will NULL terminate).
+ * The number of bytes needed to fully encode the string is returned.
+ *
+ * Strvisx encodes exactly len bytes from src into dst.
+ * This is useful for encoding a block of data.
+ */
+int
+strvis(char *dst, const char *src, int flag)
+{
+ char c;
+ char *start;
+
+ for (start = dst; (c = *src);)
+ dst = vis(dst, c, flag, *++src);
+ *dst = '\0';
+ return (dst - start);
+}
+
+int
+strnvis(char *dst, const char *src, size_t siz, int flag)
+{
+ int vis_dq = flag & VIS_DQ;
+ int vis_noslash = flag & VIS_NOSLASH;
+ char *start, *end;
+ char tbuf[5];
+ int c, i;
+
+ i = 0;
+ for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) {
+ if (isvisible(c, flag)) {
+ if ((c == '"' && vis_dq) ||
+ (c == '\\' && !vis_noslash)) {
+ /* need space for the extra '\\' */
+ if (dst + 1 >= end) {
+ i = 2;
+ break;
+ }
+ *dst++ = '\\';
+ }
+ i = 1;
+ *dst++ = c;
+ src++;
+ } else {
+ i = vis(tbuf, c, flag, *++src) - tbuf;
+ if (dst + i <= end) {
+ memcpy(dst, tbuf, i);
+ dst += i;
+ } else {
+ src--;
+ break;
+ }
+ }
+ }
+ if (siz > 0)
+ *dst = '\0';
+ if (dst + i > end) {
+ /* adjust return value for truncation */
+ while ((c = *src))
+ dst += vis(tbuf, c, flag, *++src) - tbuf;
+ }
+ return (dst - start);
+}
+
+int
+stravis(char **outp, const char *src, int flag)
+{
+ char *buf;
+ int len, serrno;
+
+ buf = reallocarray(NULL, 4, strlen(src) + 1);
+ if (buf == NULL)
+ return -1;
+ len = strvis(buf, src, flag);
+ serrno = errno;
+ *outp = realloc(buf, len + 1);
+ if (*outp == NULL) {
+ *outp = buf;
+ errno = serrno;
+ }
+ return (len);
+}
+
+int
+strvisx(char *dst, const char *src, size_t len, int flag)
+{
+ char c;
+ char *start;
+
+ for (start = dst; len > 1; len--) {
+ c = *src;
+ dst = vis(dst, c, flag, *++src);
+ }
+ if (len)
+ dst = vis(dst, *src, flag, '\0');
+ *dst = '\0';
+ return (dst - start);
+}
blob - 83332f998b3adf98066ee340ece5f5cb0088feb5
blob + 7ae1d5a7a1b485c7e396bb215c903e7b84c33c87
--- configure
+++ configure
NEED_GNU_SOURCE=0
NEED_OPENBSD_SOURCE=0
+NEED_LIBBSD_OPENBSD_VIS=0
COMPATS=
COMP="${CC} ${CFLAGS} -Wno-unused -Werror"
fi
if [ "$4" = -D_OPENBSD_SOURCE ]; then
NEED_OPENBSD_SOURCE=1
+ return 0
+ fi
+ if [ "$4" = -DLIBBSD_OPENBSD_VIS ]; then
+ NEED_LIBBSD_OPENBSD_VIS=1
return 0
fi
if [ -n "$3" ]; then
runtest strtonum STRTONUM -D_OPENBSD_SOURCE || true
runtest tree_h TREE_H || true
runtest vasprintf VASPRINTF -D_GNU_SOURCE || true
+runtest vis VIS -DLIBBSD_OPENBSD_VIS || true
deptest libevent2 LIBEVENT2 || true
CFLAGS="${CFLAGS} -I ${PWD}/compat"
fi
+if [ ${HAVE_VIS} -eq 0 ]; then
+ CFLAGS="${CFLAGS} -I ${PWD}/compat/vis"
+fi
+
if [ $HAVE_LIBEVENT2 -eq 1 ]; then
CFLAGS="$CFLAGS -DHAVE_LIBEVENT2=1"
fi
if [ $NEED_OPENBSD_SOURCE = 1 ]; then
CFLAGS="$CFLAGS -D_OPENBSD_SOURCE"
fi
+if [ $NEED_LIBBSD_OPENBSD_VIS = 1 ]; then
+ CFLAGS="$CFLAGS -DLIBBSD_OPENBSD_VIS"
+fi
CFLAGS="${CFLAGS} ${CDIAGFLAGS}"
blob - ee214d5a44e1ad365a8d4c155fe1188d567e452a
blob + 9fd19e83b7c9097930bede923b3dfbdacafd9e04
--- have/Makefile
+++ have/Makefile
strlcpy.c \
strtonum.c \
tree_h.c \
- vasprintf.c
+ vasprintf.c \
+ vis.c
all:
false
blob - /dev/null
blob + 85a4307d23c00e101a1331ba094cfa8aaa167748 (mode 644)
--- /dev/null
+++ have/vis.c
+/*
+ * Copyright (c) 2023 Omar Polo <op@omarpolo.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <vis.h>
+
+int
+main(void)
+{
+ char buf[128];
+
+ return strnvis(buf, "Hello, world!\n", sizeof(buf), 0);
+}