[compiler-rt] r349018 - Add new interceptors for vis(3) API in NetBSD
Kamil Rytarowski via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 13 02:14:02 PST 2018
Author: kamil
Date: Thu Dec 13 02:14:01 2018
New Revision: 349018
URL: http://llvm.org/viewvc/llvm-project?rev=349018&view=rev
Log:
Add new interceptors for vis(3) API in NetBSD
Summary:
Add interceptors for the NetBSD style of vis(3) present inside libc:
- vis
- nvis
- strvis
- stravis
- strnvis
- strvisx
- strnvisx
- strenvisx
- svis
- snvis
- strsvis
- strsnvis
- strsvisx
- strsnvisx
- strsenvisx
- unvis
- strunvis
- strnunvis
- strunvisx
- strnunvisx
Add a dedicated test verifying the installed interceptors.
Based on original work by Yang Zheng.
Reviewers: vitalybuka, joerg
Reviewed By: vitalybuka
Subscribers: tomsun.0.7, kubamracek, llvm-commits, mgorny, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D54594
Added:
compiler-rt/trunk/test/sanitizer_common/TestCases/NetBSD/vis.cc
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=349018&r1=349017&r2=349018&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Thu Dec 13 02:14:01 2018
@@ -117,6 +117,7 @@
#define stat __stat50
#define time __time50
#define times __times13
+#define unvis __unvis50
#define wait3 __wait350
#define wait4 __wait450
extern const unsigned short *_ctype_tab_;
@@ -8460,6 +8461,270 @@ SHA2_INTERCEPTORS(512, u64);
#define INIT_SHA2
#endif
+#if SANITIZER_INTERCEPT_VIS
+INTERCEPTOR(char *, vis, char *dst, int c, int flag, int nextc) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, vis, dst, c, flag, nextc);
+ char *end = REAL(vis)(dst, c, flag, nextc);
+ // dst is NULL terminated and end points to the NULL char
+ if (dst && end)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
+ return end;
+}
+INTERCEPTOR(char *, nvis, char *dst, SIZE_T dlen, int c, int flag, int nextc) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, nvis, dst, dlen, c, flag, nextc);
+ char *end = REAL(nvis)(dst, dlen, c, flag, nextc);
+ // nvis cannot make sure the dst is NULL terminated
+ if (dst && end)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
+ return end;
+}
+INTERCEPTOR(int, strvis, char *dst, const char *src, int flag) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strvis, dst, src, flag);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ int len = REAL(strvis)(dst, src, flag);
+ if (dst)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
+ return len;
+}
+INTERCEPTOR(int, stravis, char **dst, const char *src, int flag) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, stravis, dst, src, flag);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ int len = REAL(stravis)(dst, src, flag);
+ if (dst) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(char *));
+ if (*dst)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *dst, len + 1);
+ }
+ return len;
+}
+INTERCEPTOR(int, strnvis, char *dst, SIZE_T dlen, const char *src, int flag) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strnvis, dst, dlen, src, flag);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ int len = REAL(strnvis)(dst, dlen, src, flag);
+ // The interface will be valid even if there is no space for NULL char
+ if (dst && len > 0)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
+ return len;
+}
+INTERCEPTOR(int, strvisx, char *dst, const char *src, SIZE_T len, int flag) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strvisx, dst, src, len, flag);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
+ int ret = REAL(strvisx)(dst, src, len, flag);
+ if (dst)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ return ret;
+}
+INTERCEPTOR(int, strnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
+ int flag) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strnvisx, dst, dlen, src, len, flag);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
+ int ret = REAL(strnvisx)(dst, dlen, src, len, flag);
+ if (dst && ret >= 0)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ return ret;
+}
+INTERCEPTOR(int, strenvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
+ int flag, int *cerr_ptr) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strenvisx, dst, dlen, src, len, flag, cerr_ptr);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
+ // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold
+ // according to the implementation
+ if (cerr_ptr)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));
+ int ret = REAL(strenvisx)(dst, dlen, src, len, flag, cerr_ptr);
+ if (dst && ret >= 0)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ if (cerr_ptr)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));
+ return ret;
+}
+INTERCEPTOR(char *, svis, char *dst, int c, int flag, int nextc,
+ const char *extra) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, svis, dst, c, flag, nextc, extra);
+ if (extra)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
+ char *end = REAL(svis)(dst, c, flag, nextc, extra);
+ if (dst && end)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
+ return end;
+}
+INTERCEPTOR(char *, snvis, char *dst, SIZE_T dlen, int c, int flag, int nextc,
+ const char *extra) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, snvis, dst, dlen, c, flag, nextc, extra);
+ if (extra)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
+ char *end = REAL(snvis)(dst, dlen, c, flag, nextc, extra);
+ if (dst && end)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst,
+ Min((SIZE_T)(end - dst + 1), dlen));
+ return end;
+}
+INTERCEPTOR(int, strsvis, char *dst, const char *src, int flag,
+ const char *extra) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strsvis, dst, src, flag, extra);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ if (extra)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
+ int len = REAL(strsvis)(dst, src, flag, extra);
+ if (dst)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
+ return len;
+}
+INTERCEPTOR(int, strsnvis, char *dst, SIZE_T dlen, const char *src, int flag,
+ const char *extra) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strsnvis, dst, dlen, src, flag, extra);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ if (extra)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
+ int len = REAL(strsnvis)(dst, dlen, src, flag, extra);
+ // The interface will be valid even if there is no space for NULL char
+ if (dst && len >= 0)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
+ return len;
+}
+INTERCEPTOR(int, strsvisx, char *dst, const char *src, SIZE_T len, int flag,
+ const char *extra) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strsvisx, dst, src, len, flag, extra);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
+ if (extra)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
+ int ret = REAL(strsvisx)(dst, src, len, flag, extra);
+ if (dst)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ return ret;
+}
+INTERCEPTOR(int, strsnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
+ int flag, const char *extra) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strsnvisx, dst, dlen, src, len, flag, extra);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
+ if (extra)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
+ int ret = REAL(strsnvisx)(dst, dlen, src, len, flag, extra);
+ if (dst && ret >= 0)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ return ret;
+}
+INTERCEPTOR(int, strsenvisx, char *dst, SIZE_T dlen, const char *src,
+ SIZE_T len, int flag, const char *extra, int *cerr_ptr) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strsenvisx, dst, dlen, src, len, flag, extra,
+ cerr_ptr);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
+ if (extra)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
+ // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold
+ // according to the implementation
+ if (cerr_ptr)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));
+ int ret = REAL(strsenvisx)(dst, dlen, src, len, flag, extra, cerr_ptr);
+ if (dst && ret >= 0)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ if (cerr_ptr)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));
+ return ret;
+}
+INTERCEPTOR(int, unvis, char *cp, int c, int *astate, int flag) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, unvis, cp, c, astate, flag);
+ if (astate)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, astate, sizeof(*astate));
+ int ret = REAL(unvis)(cp, c, astate, flag);
+ if (ret == unvis_valid || ret == unvis_validpush) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cp, sizeof(*cp));
+ }
+ return ret;
+}
+INTERCEPTOR(int, strunvis, char *dst, const char *src) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strunvis, dst, src);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ int ret = REAL(strunvis)(dst, src);
+ if (ret != -1)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ return ret;
+}
+INTERCEPTOR(int, strnunvis, char *dst, SIZE_T dlen, const char *src) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strnunvis, dst, dlen, src);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ int ret = REAL(strnunvis)(dst, dlen, src);
+ if (ret != -1)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ return ret;
+}
+INTERCEPTOR(int, strunvisx, char *dst, const char *src, int flag) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strunvisx, dst, src, flag);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ int ret = REAL(strunvisx)(dst, src, flag);
+ if (ret != -1)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ return ret;
+}
+INTERCEPTOR(int, strnunvisx, char *dst, SIZE_T dlen, const char *src,
+ int flag) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strnunvisx, dst, dlen, src, flag);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ int ret = REAL(strnunvisx)(dst, dlen, src, flag);
+ if (ret != -1)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ return ret;
+}
+#define INIT_VIS \
+ COMMON_INTERCEPT_FUNCTION(vis); \
+ COMMON_INTERCEPT_FUNCTION(nvis); \
+ COMMON_INTERCEPT_FUNCTION(strvis); \
+ COMMON_INTERCEPT_FUNCTION(stravis); \
+ COMMON_INTERCEPT_FUNCTION(strnvis); \
+ COMMON_INTERCEPT_FUNCTION(strvisx); \
+ COMMON_INTERCEPT_FUNCTION(strnvisx); \
+ COMMON_INTERCEPT_FUNCTION(strenvisx); \
+ COMMON_INTERCEPT_FUNCTION(svis); \
+ COMMON_INTERCEPT_FUNCTION(snvis); \
+ COMMON_INTERCEPT_FUNCTION(strsvis); \
+ COMMON_INTERCEPT_FUNCTION(strsnvis); \
+ COMMON_INTERCEPT_FUNCTION(strsvisx); \
+ COMMON_INTERCEPT_FUNCTION(strsnvisx); \
+ COMMON_INTERCEPT_FUNCTION(strsenvisx); \
+ COMMON_INTERCEPT_FUNCTION(unvis); \
+ COMMON_INTERCEPT_FUNCTION(strunvis); \
+ COMMON_INTERCEPT_FUNCTION(strnunvis); \
+ COMMON_INTERCEPT_FUNCTION(strunvisx); \
+ COMMON_INTERCEPT_FUNCTION(strnunvisx)
+#else
+#define INIT_VIS
+#endif
+
static void InitializeCommonInterceptors() {
static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
interceptor_metadata_map =
@@ -8737,6 +9002,7 @@ static void InitializeCommonInterceptors
INIT_FSEEK;
INIT_MD2;
INIT_SHA2;
+ INIT_VIS;
INIT___PRINTF_CHK;
}
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h?rev=349018&r1=349017&r2=349018&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h Thu Dec 13 02:14:01 2018
@@ -542,5 +542,6 @@
#define SANITIZER_INTERCEPT_FSEEK (SI_NETBSD || SI_FREEBSD)
#define SANITIZER_INTERCEPT_MD2 SI_NETBSD
#define SANITIZER_INTERCEPT_SHA2 SI_NETBSD
+#define SANITIZER_INTERCEPT_VIS SI_NETBSD
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc?rev=349018&r1=349017&r2=349018&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc Thu Dec 13 02:14:01 2018
@@ -2131,6 +2131,9 @@ SHA2_CONST(384);
SHA2_CONST(512);
#undef SHA2_CONST
+
+const int unvis_valid = UNVIS_VALID;
+const int unvis_validpush = UNVIS_VALIDPUSH;
} // namespace __sanitizer
using namespace __sanitizer;
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h?rev=349018&r1=349017&r2=349018&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h Thu Dec 13 02:14:01 2018
@@ -2253,6 +2253,9 @@ SHA2_EXTERN(384);
SHA2_EXTERN(512);
#undef SHA2_EXTERN
+
+extern const int unvis_valid;
+extern const int unvis_validpush;
} // namespace __sanitizer
#define CHECK_TYPE_SIZE(TYPE) \
Added: compiler-rt/trunk/test/sanitizer_common/TestCases/NetBSD/vis.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/NetBSD/vis.cc?rev=349018&view=auto
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/NetBSD/vis.cc (added)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/NetBSD/vis.cc Thu Dec 13 02:14:01 2018
@@ -0,0 +1,245 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
+
+#include <ctype.h>
+#include <err.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <vis.h>
+
+void test_vis() {
+ char visout[5];
+ int ch = toascii(0x1);
+ vis(visout, ch, VIS_SAFE | VIS_NOSLASH, 0);
+ printf("vis: %s\n", visout);
+}
+
+void test_nvis() {
+ char visout[5];
+ int ch = toascii(0x2);
+ nvis(visout, sizeof visout, ch, VIS_SAFE | VIS_NOSLASH, 0);
+ printf("nvis: %s\n", visout);
+}
+
+void test_strvis() {
+ char visout[5];
+ strvis(visout, "\3", VIS_SAFE | VIS_NOSLASH);
+ printf("strvis: %s\n", visout);
+}
+
+void test_stravis() {
+ char *visout;
+ stravis(&visout, "\4", VIS_SAFE | VIS_NOSLASH);
+ printf("stravis: %s\n", visout);
+ free(visout);
+}
+
+void test_strnvis() {
+ char visout[5];
+ strnvis(visout, sizeof visout, "\5", VIS_SAFE | VIS_NOSLASH);
+ printf("strnvis: %s\n", visout);
+}
+
+void test_strvisx() {
+ char visout[5];
+ char src[] = "\6";
+ strvisx(visout, src, sizeof src - 1 /* skip final \0 */,
+ VIS_SAFE | VIS_NOSLASH);
+ printf("strvisx: %s\n", visout);
+}
+
+void test_strnvisx() {
+ char visout[5];
+ char src[] = "\1";
+ strnvisx(visout, sizeof visout, src, sizeof src - 1 /* skip final \0 */,
+ VIS_SAFE | VIS_NOSLASH);
+ printf("strnvisx: %s\n", visout);
+}
+
+void test_strenvisx() {
+ char visout[5];
+ char src[] = "\2";
+ strenvisx(visout, sizeof visout, src, sizeof src - 1 /* skip final \0 */,
+ VIS_SAFE | VIS_NOSLASH, NULL);
+ printf("strenvisx: %s\n", visout);
+}
+
+void test_svis() {
+ char visout[5];
+ int ch = toascii(0x3);
+ svis(visout, ch, VIS_SAFE | VIS_NOSLASH, 0, "x");
+ printf("svis: %s\n", visout);
+}
+
+void test_snvis() {
+ char visout[5];
+ int ch = toascii(0x2);
+ snvis(visout, sizeof visout, ch, VIS_SAFE | VIS_NOSLASH, 0, "x");
+ printf("snvis: %s\n", visout);
+}
+
+void test_strsvis() {
+ char visout[5];
+ strsvis(visout, "\4", VIS_SAFE | VIS_NOSLASH, "x");
+ printf("strsvis: %s\n", visout);
+}
+
+void test_strsnvis() {
+ char visout[5];
+ strsnvis(visout, sizeof visout, "\5", VIS_SAFE | VIS_NOSLASH, "x");
+ printf("strsnvis: %s\n", visout);
+}
+
+void test_strsvisx() {
+ char visout[5];
+ char src[] = "\5";
+ strsvisx(visout, src, sizeof src - 1 /* skip final \0 */,
+ VIS_SAFE | VIS_NOSLASH, "x");
+ printf("strsvisx: %s\n", visout);
+}
+
+void test_strsnvisx() {
+ char visout[5];
+ char src[] = "\6";
+ strsnvisx(visout, sizeof visout, src, sizeof src - 1 /* skip final \0 */,
+ VIS_SAFE | VIS_NOSLASH, "x");
+ printf("strsnvisx: %s\n", visout);
+}
+
+void test_strsenvisx() {
+ char visout[5];
+ char src[] = "\1";
+ strsenvisx(visout, sizeof visout, src, sizeof src - 1 /* skip final \0 */,
+ VIS_SAFE | VIS_NOSLASH, "x", NULL);
+ printf("strsenvisx: %s\n", visout);
+}
+
+void test_unvis() {
+ char visout[5];
+ int ch = toascii(0x1);
+ vis(visout, ch, VIS_SAFE, 0);
+
+ int state = 0;
+ char out;
+ char *p = visout;
+ while ((ch = *(p++)) != '\0') {
+ again:
+ switch (unvis(&out, ch, &state, 0)) {
+ case 0:
+ case UNVIS_NOCHAR:
+ break;
+ case UNVIS_VALID:
+ printf("unvis: %" PRIx8 "\n", (unsigned char)out);
+ break;
+ case UNVIS_VALIDPUSH:
+ printf("unvis: %" PRIx8 "\n", (unsigned char)out);
+ goto again;
+ case UNVIS_SYNBAD:
+ errx(1, "Bad character sequence!");
+ }
+ }
+ if (unvis(&out, '\0', &state, UNVIS_END) == UNVIS_VALID)
+ printf("unvis: %" PRIx8 "\n", (unsigned char)out);
+}
+
+void test_strunvis() {
+ char visout[5];
+ int ch = toascii(0x2);
+ vis(visout, ch, VIS_SAFE, 0);
+
+ char p[5];
+ strunvis(p, visout);
+
+ char *pp = p;
+ while ((ch = *(pp++)) != '\0')
+ printf("strunvis: %" PRIx8 "\n", (unsigned char)ch);
+}
+
+void test_strnunvis() {
+ char visout[5];
+ int ch = toascii(0x3);
+ vis(visout, ch, VIS_SAFE, 0);
+
+ char p[5];
+ strnunvis(p, sizeof p, visout);
+
+ char *pp = p;
+ while ((ch = *(pp++)) != '\0')
+ printf("strnunvis: %" PRIx8 "\n", (unsigned char)ch);
+}
+
+void test_strunvisx() {
+ char visout[5];
+ int ch = toascii(0x4);
+ vis(visout, ch, VIS_SAFE, 0);
+
+ char p[5];
+ strunvisx(p, visout, VIS_SAFE);
+
+ char *pp = p;
+ while ((ch = *(pp++)) != '\0')
+ printf("strunvisx: %" PRIx8 "\n", (unsigned char)ch);
+}
+
+void test_strnunvisx() {
+ char visout[5];
+ int ch = toascii(0x5);
+ vis(visout, ch, VIS_SAFE, 0);
+
+ char p[5];
+ strnunvisx(p, sizeof p, visout, VIS_SAFE);
+
+ char *pp = p;
+ while ((ch = *(pp++)) != '\0')
+ printf("strnunvisx: %" PRIx8 "\n", (unsigned char)ch);
+}
+
+int main(void) {
+ printf("vis\n");
+
+ test_vis();
+ test_nvis();
+ test_strvis();
+ test_stravis();
+ test_strnvis();
+ test_strvisx();
+ test_strnvisx();
+ test_strenvisx();
+ test_svis();
+ test_snvis();
+ test_strsvis();
+ test_strsnvis();
+ test_strsvisx();
+ test_strsnvisx();
+ test_strsenvisx();
+ test_unvis();
+ test_strunvis();
+ test_strnunvis();
+ test_strunvisx();
+ test_strnunvisx();
+
+ // CHECK: vis
+ // CHECK: vis: ^A
+ // CHECK: nvis: ^B
+ // CHECK: strvis: ^C
+ // CHECK: stravis: ^D
+ // CHECK: strnvis: ^E
+ // CHECK: strvisx: ^F
+ // CHECK: strnvisx: ^A
+ // CHECK: strenvisx: ^B
+ // CHECK: svis: ^C
+ // CHECK: snvis: ^B
+ // CHECK: strsvis: ^D
+ // CHECK: strsnvis: ^E
+ // CHECK: strsvisx: ^E
+ // CHECK: strsnvisx: ^F
+ // CHECK: strsenvisx: ^A
+ // CHECK: unvis: 1
+ // CHECK: strunvis: 2
+ // CHECK: strnunvis: 3
+ // CHECK: strunvisx: 4
+ // CHECK: strnunvisx: 5
+
+ return 0;
+}
More information about the llvm-commits
mailing list