144302Smarc /*-
2*63894Sbostic * Copyright (c) 1989, 1993
3*63894Sbostic * The Regents of the University of California. All rights reserved.
439284Smarc *
544302Smarc * %sccs.include.redist.c%
639284Smarc */
739284Smarc
839284Smarc #if defined(LIBC_SCCS) && !defined(lint)
9*63894Sbostic static char sccsid[] = "@(#)vis.c 8.1 (Berkeley) 07/19/93";
1039284Smarc #endif /* LIBC_SCCS and not lint */
1139284Smarc
1239284Smarc #include <sys/types.h>
1352363Sbostic #include <limits.h>
1439284Smarc #include <ctype.h>
1544302Smarc #include <vis.h>
1639284Smarc
1739284Smarc #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
1839284Smarc
1939284Smarc /*
2041757Smarc * vis - visually encode characters
2139284Smarc */
2239284Smarc char *
vis(dst,c,flag,nextc)2341757Smarc vis(dst, c, flag, nextc)
2452363Sbostic register char *dst;
2552363Sbostic int c, nextc;
2641757Smarc register int flag;
2739284Smarc {
2852363Sbostic if ((u_int)c <= UCHAR_MAX && isgraph(c) ||
2944302Smarc ((flag & VIS_SP) == 0 && c == ' ') ||
3044302Smarc ((flag & VIS_TAB) == 0 && c == '\t') ||
3144302Smarc ((flag & VIS_NL) == 0 && c == '\n') ||
3241757Smarc ((flag & VIS_SAFE) && (c == '\b' || c == '\007' || c == '\r'))) {
3341757Smarc *dst++ = c;
3441757Smarc if (c == '\\' && (flag & VIS_NOSLASH) == 0)
3541757Smarc *dst++ = '\\';
3641757Smarc *dst = '\0';
3741757Smarc return (dst);
3841757Smarc }
3939284Smarc
4041757Smarc if (flag & VIS_CSTYLE) {
4139284Smarc switch(c) {
4239284Smarc case '\n':
4344302Smarc *dst++ = '\\';
4441757Smarc *dst++ = 'n';
4539284Smarc goto done;
4639284Smarc case '\r':
4744302Smarc *dst++ = '\\';
4841757Smarc *dst++ = 'r';
4939284Smarc goto done;
5039284Smarc case '\b':
5144302Smarc *dst++ = '\\';
5241757Smarc *dst++ = 'b';
5339284Smarc goto done;
5446597Sdonn #if __STDC__
5546597Sdonn case '\a':
5646597Sdonn #else
5746597Sdonn case '\007':
5846597Sdonn #endif
5944302Smarc *dst++ = '\\';
6041757Smarc *dst++ = 'a';
6139284Smarc goto done;
6239284Smarc case '\v':
6344302Smarc *dst++ = '\\';
6441757Smarc *dst++ = 'v';
6539284Smarc goto done;
6639284Smarc case '\t':
6744302Smarc *dst++ = '\\';
6841757Smarc *dst++ = 't';
6939284Smarc goto done;
7039284Smarc case '\f':
7144302Smarc *dst++ = '\\';
7241757Smarc *dst++ = 'f';
7339284Smarc goto done;
7439284Smarc case ' ':
7544302Smarc *dst++ = '\\';
7641757Smarc *dst++ = 's';
7739284Smarc goto done;
7839284Smarc case '\0':
7944302Smarc *dst++ = '\\';
8041757Smarc *dst++ = '0';
8144302Smarc if (isoctal(nextc)) {
8241757Smarc *dst++ = '0';
8341757Smarc *dst++ = '0';
8439284Smarc }
8539284Smarc goto done;
8639284Smarc }
8739284Smarc }
8841757Smarc if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
8944302Smarc *dst++ = '\\';
9041757Smarc *dst++ = ((u_char)c >> 6 & 07) + '0';
9141757Smarc *dst++ = ((u_char)c >> 3 & 07) + '0';
9241757Smarc *dst++ = ((u_char)c & 07) + '0';
9339284Smarc goto done;
9439284Smarc }
9544302Smarc if ((flag & VIS_NOSLASH) == 0)
9644302Smarc *dst++ = '\\';
9741757Smarc if (c & 0200) {
9841757Smarc c &= 0177;
9941757Smarc *dst++ = 'M';
10041757Smarc }
10141757Smarc if (iscntrl(c)) {
10241757Smarc *dst++ = '^';
10341757Smarc if (c == 0177)
10441757Smarc *dst++ = '?';
10539284Smarc else
10641757Smarc *dst++ = c + '@';
10741757Smarc } else {
10841757Smarc *dst++ = '-';
10941757Smarc *dst++ = c;
11039284Smarc }
11139284Smarc done:
11241757Smarc *dst = '\0';
11341757Smarc return (dst);
11439284Smarc }
11539284Smarc
11639284Smarc /*
11744302Smarc * strvis, strvisx - visually encode characters from src into dst
11844302Smarc *
11944302Smarc * Dst must be 4 times the size of src to account for possible
12044302Smarc * expansion. The length of dst, not including the trailing NULL,
12144302Smarc * is returned.
12239284Smarc *
12344302Smarc * Strvisx encodes exactly len bytes from src into dst.
12444302Smarc * This is useful for encoding a block of data.
12539284Smarc */
12646597Sdonn int
strvis(dst,src,flag)12744302Smarc strvis(dst, src, flag)
12846597Sdonn register char *dst;
12946597Sdonn register const char *src;
13046597Sdonn int flag;
13139284Smarc {
13244302Smarc register char c;
13352338Sbostic char *start;
13439284Smarc
13552338Sbostic for (start = dst; c = *src;)
13652338Sbostic dst = vis(dst, c, flag, *++src);
13752338Sbostic *dst = '\0';
13844302Smarc return (dst - start);
13939284Smarc }
14041757Smarc
14146597Sdonn int
strvisx(dst,src,len,flag)14244302Smarc strvisx(dst, src, len, flag)
14346597Sdonn register char *dst;
14446597Sdonn register const char *src;
14546597Sdonn register size_t len;
14646597Sdonn int flag;
14741757Smarc {
14863893Sbostic int c;
14963893Sbostic char *start;
15041757Smarc
15163893Sbostic for (start = dst; len > 1; len--) {
15263893Sbostic c = *src;
15363893Sbostic dst = vis(dst, c, flag, *++src);
15441757Smarc }
15544302Smarc if (len)
15644302Smarc dst = vis(dst, *src, flag, '\0');
15763893Sbostic *dst = '\0';
15841757Smarc
15941757Smarc return (dst - start);
16041757Smarc }
161