xref: /freebsd/contrib/openbsm/compat/vis.h (revision fbbd9655)
1aa772005SRobert Watson /*-
2aa772005SRobert Watson  * Copyright (c) 1989, 1993
3aa772005SRobert Watson  *	The Regents of the University of California.  All rights reserved.
4aa772005SRobert Watson  *
5aa772005SRobert Watson  * Redistribution and use in source and binary forms, with or without
6aa772005SRobert Watson  * modification, are permitted provided that the following conditions
7aa772005SRobert Watson  * are met:
8aa772005SRobert Watson  * 1. Redistributions of source code must retain the above copyright
9aa772005SRobert Watson  *    notice, this list of conditions and the following disclaimer.
10aa772005SRobert Watson  * 2. Redistributions in binary form must reproduce the above copyright
11aa772005SRobert Watson  *    notice, this list of conditions and the following disclaimer in the
12aa772005SRobert Watson  *    documentation and/or other materials provided with the distribution.
13fbbd9655SWarner Losh  * 3. Neither the name of the University nor the names of its contributors
14aa772005SRobert Watson  *    may be used to endorse or promote products derived from this software
15aa772005SRobert Watson  *    without specific prior written permission.
16aa772005SRobert Watson  *
17aa772005SRobert Watson  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18aa772005SRobert Watson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19aa772005SRobert Watson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20aa772005SRobert Watson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21aa772005SRobert Watson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22aa772005SRobert Watson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23aa772005SRobert Watson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24aa772005SRobert Watson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25aa772005SRobert Watson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26aa772005SRobert Watson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27aa772005SRobert Watson  * SUCH DAMAGE.
28aa772005SRobert Watson  *
29aa772005SRobert Watson  * Defived from FreeBSD head/lib/libc/gen/vis.c 165903, head/include/vis.h
30aa772005SRobert Watson  * 203964.
31aa772005SRobert Watson  */
32aa772005SRobert Watson 
33aa772005SRobert Watson #include <sys/types.h>
34aa772005SRobert Watson #include <limits.h>
35aa772005SRobert Watson #include <ctype.h>
36aa772005SRobert Watson #include <stdio.h>
37aa772005SRobert Watson 
38aa772005SRobert Watson /*
39aa772005SRobert Watson  * to select alternate encoding format
40aa772005SRobert Watson  */
41aa772005SRobert Watson #define	VIS_OCTAL	0x01	/* use octal \ddd format */
42aa772005SRobert Watson #define	VIS_CSTYLE	0x02	/* use \[nrft0..] where appropriate */
43aa772005SRobert Watson 
44aa772005SRobert Watson /*
45aa772005SRobert Watson  * to alter set of characters encoded (default is to encode all
46aa772005SRobert Watson  * non-graphic except space, tab, and newline).
47aa772005SRobert Watson  */
48aa772005SRobert Watson #define	VIS_SP		0x04	/* also encode space */
49aa772005SRobert Watson #define	VIS_TAB		0x08	/* also encode tab */
50aa772005SRobert Watson #define	VIS_NL		0x10	/* also encode newline */
51aa772005SRobert Watson #define	VIS_WHITE	(VIS_SP | VIS_TAB | VIS_NL)
52aa772005SRobert Watson #define	VIS_SAFE	0x20	/* only encode "unsafe" characters */
53aa772005SRobert Watson 
54aa772005SRobert Watson /*
55aa772005SRobert Watson  * other
56aa772005SRobert Watson  */
57aa772005SRobert Watson #define	VIS_NOSLASH	0x40	/* inhibit printing '\' */
58aa772005SRobert Watson #define	VIS_HTTPSTYLE	0x80	/* http-style escape % HEX HEX */
59aa772005SRobert Watson #define	VIS_GLOB	0x100	/* encode glob(3) magics */
60aa772005SRobert Watson 
61aa772005SRobert Watson /*
62aa772005SRobert Watson  * unvis return codes
63aa772005SRobert Watson  */
64aa772005SRobert Watson #define	UNVIS_VALID	 1	/* character valid */
65aa772005SRobert Watson #define	UNVIS_VALIDPUSH	 2	/* character valid, push back passed char */
66aa772005SRobert Watson #define	UNVIS_NOCHAR	 3	/* valid sequence, no character produced */
67aa772005SRobert Watson #define	UNVIS_SYNBAD	-1	/* unrecognized escape sequence */
68aa772005SRobert Watson #define	UNVIS_ERROR	-2	/* decoder in unknown state (unrecoverable) */
69aa772005SRobert Watson 
70aa772005SRobert Watson /*
71aa772005SRobert Watson  * unvis flags
72aa772005SRobert Watson  */
73aa772005SRobert Watson #define	UNVIS_END	1	/* no more characters */
74aa772005SRobert Watson 
75aa772005SRobert Watson #define	isoctal(c)	(((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
76aa772005SRobert Watson 
77aa772005SRobert Watson /*
78aa772005SRobert Watson  * vis - visually encode characters
79aa772005SRobert Watson  */
80aa772005SRobert Watson char *
vis(dst,c,flag,nextc)81aa772005SRobert Watson vis(dst, c, flag, nextc)
82aa772005SRobert Watson 	char *dst;
83aa772005SRobert Watson 	int c, nextc;
84aa772005SRobert Watson 	int flag;
85aa772005SRobert Watson {
86aa772005SRobert Watson 	c = (unsigned char)c;
87aa772005SRobert Watson 
88aa772005SRobert Watson 	if (flag & VIS_HTTPSTYLE) {
89aa772005SRobert Watson 		/* Described in RFC 1808 */
90aa772005SRobert Watson 		if (!(isalnum(c) /* alpha-numeric */
91aa772005SRobert Watson 		    /* safe */
92aa772005SRobert Watson 		    || c == '$' || c == '-' || c == '_' || c == '.' || c == '+'
93aa772005SRobert Watson 		    /* extra */
94aa772005SRobert Watson 		    || c == '!' || c == '*' || c == '\'' || c == '('
95aa772005SRobert Watson 		    || c == ')' || c == ',')) {
96aa772005SRobert Watson 			*dst++ = '%';
97aa772005SRobert Watson 			snprintf(dst, 4, (c < 16 ? "0%X" : "%X"), c);
98aa772005SRobert Watson 			dst += 2;
99aa772005SRobert Watson 			goto done;
100aa772005SRobert Watson 		}
101aa772005SRobert Watson 	}
102aa772005SRobert Watson 
103aa772005SRobert Watson 	if ((flag & VIS_GLOB) &&
104aa772005SRobert Watson 	    (c == '*' || c == '?' || c == '[' || c == '#'))
105aa772005SRobert Watson 		;
106aa772005SRobert Watson 	else if (isgraph(c) ||
107aa772005SRobert Watson 	   ((flag & VIS_SP) == 0 && c == ' ') ||
108aa772005SRobert Watson 	   ((flag & VIS_TAB) == 0 && c == '\t') ||
109aa772005SRobert Watson 	   ((flag & VIS_NL) == 0 && c == '\n') ||
110aa772005SRobert Watson 	   ((flag & VIS_SAFE) && (c == '\b' || c == '\007' || c == '\r'))) {
111aa772005SRobert Watson 		*dst++ = c;
112aa772005SRobert Watson 		if (c == '\\' && (flag & VIS_NOSLASH) == 0)
113aa772005SRobert Watson 			*dst++ = '\\';
114aa772005SRobert Watson 		*dst = '\0';
115aa772005SRobert Watson 		return (dst);
116aa772005SRobert Watson 	}
117aa772005SRobert Watson 
118aa772005SRobert Watson 	if (flag & VIS_CSTYLE) {
119aa772005SRobert Watson 		switch(c) {
120aa772005SRobert Watson 		case '\n':
121aa772005SRobert Watson 			*dst++ = '\\';
122aa772005SRobert Watson 			*dst++ = 'n';
123aa772005SRobert Watson 			goto done;
124aa772005SRobert Watson 		case '\r':
125aa772005SRobert Watson 			*dst++ = '\\';
126aa772005SRobert Watson 			*dst++ = 'r';
127aa772005SRobert Watson 			goto done;
128aa772005SRobert Watson 		case '\b':
129aa772005SRobert Watson 			*dst++ = '\\';
130aa772005SRobert Watson 			*dst++ = 'b';
131aa772005SRobert Watson 			goto done;
132aa772005SRobert Watson 		case '\a':
133aa772005SRobert Watson 			*dst++ = '\\';
134aa772005SRobert Watson 			*dst++ = 'a';
135aa772005SRobert Watson 			goto done;
136aa772005SRobert Watson 		case '\v':
137aa772005SRobert Watson 			*dst++ = '\\';
138aa772005SRobert Watson 			*dst++ = 'v';
139aa772005SRobert Watson 			goto done;
140aa772005SRobert Watson 		case '\t':
141aa772005SRobert Watson 			*dst++ = '\\';
142aa772005SRobert Watson 			*dst++ = 't';
143aa772005SRobert Watson 			goto done;
144aa772005SRobert Watson 		case '\f':
145aa772005SRobert Watson 			*dst++ = '\\';
146aa772005SRobert Watson 			*dst++ = 'f';
147aa772005SRobert Watson 			goto done;
148aa772005SRobert Watson 		case ' ':
149aa772005SRobert Watson 			*dst++ = '\\';
150aa772005SRobert Watson 			*dst++ = 's';
151aa772005SRobert Watson 			goto done;
152aa772005SRobert Watson 		case '\0':
153aa772005SRobert Watson 			*dst++ = '\\';
154aa772005SRobert Watson 			*dst++ = '0';
155aa772005SRobert Watson 			if (isoctal(nextc)) {
156aa772005SRobert Watson 				*dst++ = '0';
157aa772005SRobert Watson 				*dst++ = '0';
158aa772005SRobert Watson 			}
159aa772005SRobert Watson 			goto done;
160aa772005SRobert Watson 		}
161aa772005SRobert Watson 	}
162aa772005SRobert Watson 	if (((c & 0177) == ' ') || isgraph(c) || (flag & VIS_OCTAL)) {
163aa772005SRobert Watson 		*dst++ = '\\';
164aa772005SRobert Watson 		*dst++ = ((u_char)c >> 6 & 07) + '0';
165aa772005SRobert Watson 		*dst++ = ((u_char)c >> 3 & 07) + '0';
166aa772005SRobert Watson 		*dst++ = ((u_char)c & 07) + '0';
167aa772005SRobert Watson 		goto done;
168aa772005SRobert Watson 	}
169aa772005SRobert Watson 	if ((flag & VIS_NOSLASH) == 0)
170aa772005SRobert Watson 		*dst++ = '\\';
171aa772005SRobert Watson 	if (c & 0200) {
172aa772005SRobert Watson 		c &= 0177;
173aa772005SRobert Watson 		*dst++ = 'M';
174aa772005SRobert Watson 	}
175aa772005SRobert Watson 	if (iscntrl(c)) {
176aa772005SRobert Watson 		*dst++ = '^';
177aa772005SRobert Watson 		if (c == 0177)
178aa772005SRobert Watson 			*dst++ = '?';
179aa772005SRobert Watson 		else
180aa772005SRobert Watson 			*dst++ = c + '@';
181aa772005SRobert Watson 	} else {
182aa772005SRobert Watson 		*dst++ = '-';
183aa772005SRobert Watson 		*dst++ = c;
184aa772005SRobert Watson 	}
185aa772005SRobert Watson done:
186aa772005SRobert Watson 	*dst = '\0';
187aa772005SRobert Watson 	return (dst);
188aa772005SRobert Watson }
189