xref: /csrg-svn/lib/libc/gen/vis.c (revision 46597)
144302Smarc /*-
239284Smarc  * Copyright (c) 1989 The Regents of the University of California.
339284Smarc  * All rights reserved.
439284Smarc  *
544302Smarc  * %sccs.include.redist.c%
639284Smarc  */
739284Smarc 
839284Smarc #if defined(LIBC_SCCS) && !defined(lint)
9*46597Sdonn static char sccsid[] = "@(#)vis.c	5.4 (Berkeley) 02/23/91";
1039284Smarc #endif /* LIBC_SCCS and not lint */
1139284Smarc 
1239284Smarc #include <sys/types.h>
1339284Smarc #include <ctype.h>
1444302Smarc #include <vis.h>
1539284Smarc 
1639284Smarc #define	isoctal(c)	(((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
1739284Smarc 
1839284Smarc /*
1941757Smarc  * vis - visually encode characters
2039284Smarc  */
2139284Smarc char *
22*46597Sdonn #if __STDC__
23*46597Sdonn vis(register char *dst, register char c, register int flag, char nextc)
24*46597Sdonn #else
2541757Smarc vis(dst, c, flag, nextc)
2641757Smarc 	register char *dst, c;
2741757Smarc 	char nextc;
2841757Smarc 	register int flag;
29*46597Sdonn #endif
3039284Smarc {
3141757Smarc 	if (isascii(c) && isgraph(c) ||
3244302Smarc 	   ((flag & VIS_SP) == 0 && c == ' ') ||
3344302Smarc 	   ((flag & VIS_TAB) == 0 && c == '\t') ||
3444302Smarc 	   ((flag & VIS_NL) == 0 && c == '\n') ||
3541757Smarc 	   ((flag & VIS_SAFE) && (c == '\b' || c == '\007' || c == '\r'))) {
3641757Smarc 		*dst++ = c;
3741757Smarc 		if (c == '\\' && (flag & VIS_NOSLASH) == 0)
3841757Smarc 			*dst++ = '\\';
3941757Smarc 		*dst = '\0';
4041757Smarc 		return (dst);
4141757Smarc 	}
4239284Smarc 
4341757Smarc 	if (flag & VIS_CSTYLE) {
4439284Smarc 		switch(c) {
4539284Smarc 		case '\n':
4644302Smarc 			*dst++ = '\\';
4741757Smarc 			*dst++ = 'n';
4839284Smarc 			goto done;
4939284Smarc 		case '\r':
5044302Smarc 			*dst++ = '\\';
5141757Smarc 			*dst++ = 'r';
5239284Smarc 			goto done;
5339284Smarc 		case '\b':
5444302Smarc 			*dst++ = '\\';
5541757Smarc 			*dst++ = 'b';
5639284Smarc 			goto done;
57*46597Sdonn #if __STDC__
58*46597Sdonn 		case '\a':
59*46597Sdonn #else
60*46597Sdonn 		case '\007':
61*46597Sdonn #endif
6244302Smarc 			*dst++ = '\\';
6341757Smarc 			*dst++ = 'a';
6439284Smarc 			goto done;
6539284Smarc 		case '\v':
6644302Smarc 			*dst++ = '\\';
6741757Smarc 			*dst++ = 'v';
6839284Smarc 			goto done;
6939284Smarc 		case '\t':
7044302Smarc 			*dst++ = '\\';
7141757Smarc 			*dst++ = 't';
7239284Smarc 			goto done;
7339284Smarc 		case '\f':
7444302Smarc 			*dst++ = '\\';
7541757Smarc 			*dst++ = 'f';
7639284Smarc 			goto done;
7739284Smarc 		case ' ':
7844302Smarc 			*dst++ = '\\';
7941757Smarc 			*dst++ = 's';
8039284Smarc 			goto done;
8139284Smarc 		case '\0':
8244302Smarc 			*dst++ = '\\';
8341757Smarc 			*dst++ = '0';
8444302Smarc 			if (isoctal(nextc)) {
8541757Smarc 				*dst++ = '0';
8641757Smarc 				*dst++ = '0';
8739284Smarc 			}
8839284Smarc 			goto done;
8939284Smarc 		}
9039284Smarc 	}
9141757Smarc 	if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
9244302Smarc 		*dst++ = '\\';
9341757Smarc 		*dst++ = ((u_char)c >> 6 & 07) + '0';
9441757Smarc 		*dst++ = ((u_char)c >> 3 & 07) + '0';
9541757Smarc 		*dst++ = ((u_char)c & 07) + '0';
9639284Smarc 		goto done;
9739284Smarc 	}
9844302Smarc 	if ((flag & VIS_NOSLASH) == 0)
9944302Smarc 		*dst++ = '\\';
10041757Smarc 	if (c & 0200) {
10141757Smarc 		c &= 0177;
10241757Smarc 		*dst++ = 'M';
10341757Smarc 	}
10441757Smarc 	if (iscntrl(c)) {
10541757Smarc 		*dst++ = '^';
10641757Smarc 		if (c == 0177)
10741757Smarc 			*dst++ = '?';
10839284Smarc 		else
10941757Smarc 			*dst++ = c + '@';
11041757Smarc 	} else {
11141757Smarc 		*dst++ = '-';
11241757Smarc 		*dst++ = c;
11339284Smarc 	}
11439284Smarc done:
11541757Smarc 	*dst = '\0';
11641757Smarc 	return (dst);
11739284Smarc }
11839284Smarc 
11939284Smarc /*
12044302Smarc  * strvis, strvisx - visually encode characters from src into dst
12144302Smarc  *
12244302Smarc  *	Dst must be 4 times the size of src to account for possible
12344302Smarc  *	expansion.  The length of dst, not including the trailing NULL,
12444302Smarc  *	is returned.
12539284Smarc  *
12644302Smarc  *	Strvisx encodes exactly len bytes from src into dst.
12744302Smarc  *	This is useful for encoding a block of data.
12839284Smarc  */
129*46597Sdonn int
13044302Smarc strvis(dst, src, flag)
131*46597Sdonn 	register char *dst;
132*46597Sdonn 	register const char *src;
133*46597Sdonn 	int flag;
13439284Smarc {
13544302Smarc 	register char c;
13644302Smarc 	char *start = dst;
13739284Smarc 
13844302Smarc 	for (;c = *src; src++)
13944302Smarc 		dst = vis(dst, c, flag, *(src+1));
14039284Smarc 
14144302Smarc 	return (dst - start);
14239284Smarc }
14341757Smarc 
144*46597Sdonn int
14544302Smarc strvisx(dst, src, len, flag)
146*46597Sdonn 	register char *dst;
147*46597Sdonn 	register const char *src;
148*46597Sdonn 	register size_t len;
149*46597Sdonn 	int flag;
15041757Smarc {
15141757Smarc 	char *start = dst;
15241757Smarc 
15344302Smarc 	while (len > 1) {
15444302Smarc 		dst = vis(dst, *src, flag, *(src+1));
15544302Smarc 		len--;
15641757Smarc 	}
15744302Smarc 	if (len)
15844302Smarc 		dst = vis(dst, *src, flag, '\0');
15941757Smarc 
16041757Smarc 	return (dst - start);
16141757Smarc }
162