xref: /csrg-svn/lib/libc/gen/vis.c (revision 63894)
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