xref: /onnv-gate/usr/src/cmd/sgs/libconv/common/c_literal.c (revision 6635:8de60a34b2e5)
1*6635Sab196087 /*
2*6635Sab196087  * CDDL HEADER START
3*6635Sab196087  *
4*6635Sab196087  * The contents of this file are subject to the terms of the
5*6635Sab196087  * Common Development and Distribution License (the "License").
6*6635Sab196087  * You may not use this file except in compliance with the License.
7*6635Sab196087  *
8*6635Sab196087  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*6635Sab196087  * or http://www.opensolaris.org/os/licensing.
10*6635Sab196087  * See the License for the specific language governing permissions
11*6635Sab196087  * and limitations under the License.
12*6635Sab196087  *
13*6635Sab196087  * When distributing Covered Code, include this CDDL HEADER in each
14*6635Sab196087  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*6635Sab196087  * If applicable, add the following below this CDDL HEADER, with the
16*6635Sab196087  * fields enclosed by brackets "[]" replaced with your own identifying
17*6635Sab196087  * information: Portions Copyright [yyyy] [name of copyright owner]
18*6635Sab196087  *
19*6635Sab196087  * CDDL HEADER END
20*6635Sab196087  */
21*6635Sab196087 
22*6635Sab196087 /*
23*6635Sab196087  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24*6635Sab196087  * Use is subject to license terms.
25*6635Sab196087  */
26*6635Sab196087 
27*6635Sab196087 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*6635Sab196087 
29*6635Sab196087 
30*6635Sab196087 /*
31*6635Sab196087  * Translate a string into C literal string constant notation.
32*6635Sab196087  */
33*6635Sab196087 
34*6635Sab196087 #include	<stdio.h>
35*6635Sab196087 #include	<ctype.h>
36*6635Sab196087 #include	<_conv.h>
37*6635Sab196087 #include	<c_literal_msg.h>
38*6635Sab196087 
39*6635Sab196087 
40*6635Sab196087 /*
41*6635Sab196087  * Convert characters to the form used by the C language to represent
42*6635Sab196087  * literal strings:
43*6635Sab196087  *	- Printable characters are shown as themselves
44*6635Sab196087  *	- Convert special characters to their 2-character escaped forms:
45*6635Sab196087  *		alert (bell)	\a
46*6635Sab196087  *		backspace	\b
47*6635Sab196087  *		formfeed	\f
48*6635Sab196087  *		newline		\n
49*6635Sab196087  *		return		\r
50*6635Sab196087  *		horizontal tab	\t
51*6635Sab196087  *		vertical tab	\v
52*6635Sab196087  *		backspace	\\
53*6635Sab196087  *		single quote	\'
54*6635Sab196087  *		double quote	\"
55*6635Sab196087  *	- Display other non-printable characters as 4-character escaped
56*6635Sab196087  *		octal constants.
57*6635Sab196087  *
58*6635Sab196087  * entry:
59*6635Sab196087  *	buf - Buffer of characters to be processed
60*6635Sab196087  *	n # of characters in buf to be processed
61*6635Sab196087  *	outfunc - Function to be called to move output characters.
62*6635Sab196087  *	uvalue - User value. This argument is passed to outfunc without
63*6635Sab196087  *		examination. The caller can use it to pass additional
64*6635Sab196087  *		information required by the callback.
65*6635Sab196087  *
66*6635Sab196087  * exit:
67*6635Sab196087  *	The string has been processed, with the resulting data passed
68*6635Sab196087  *	to outfunc for processing.
69*6635Sab196087  */
70*6635Sab196087 void
71*6635Sab196087 conv_str_to_c_literal(const char *buf, size_t n,
72*6635Sab196087     Conv_str_to_c_literal_func_t *outfunc, void *uvalue)
73*6635Sab196087 {
74*6635Sab196087 	char	bs_buf[2];	/* For two-character backslash codes */
75*6635Sab196087 	char	octal_buf[10];	/* For \000 style octal constants */
76*6635Sab196087 
77*6635Sab196087 	bs_buf[0] = '\\';
78*6635Sab196087 	while (n > 0) {
79*6635Sab196087 		switch (*buf) {
80*6635Sab196087 		case '\0':
81*6635Sab196087 			bs_buf[1] = '0';
82*6635Sab196087 			break;
83*6635Sab196087 		case '\a':
84*6635Sab196087 			bs_buf[1] = 'a';
85*6635Sab196087 			break;
86*6635Sab196087 		case '\b':
87*6635Sab196087 			bs_buf[1] = 'b';
88*6635Sab196087 			break;
89*6635Sab196087 		case '\f':
90*6635Sab196087 			bs_buf[1] = 'f';
91*6635Sab196087 			break;
92*6635Sab196087 		case '\n':
93*6635Sab196087 			bs_buf[1] = 'n';
94*6635Sab196087 			break;
95*6635Sab196087 		case '\r':
96*6635Sab196087 			bs_buf[1] = 'r';
97*6635Sab196087 			break;
98*6635Sab196087 		case '\t':
99*6635Sab196087 			bs_buf[1] = 't';
100*6635Sab196087 			break;
101*6635Sab196087 		case '\v':
102*6635Sab196087 			bs_buf[1] = 'v';
103*6635Sab196087 			break;
104*6635Sab196087 		case '\\':
105*6635Sab196087 			bs_buf[1] = '\\';
106*6635Sab196087 			break;
107*6635Sab196087 		case '\'':
108*6635Sab196087 			bs_buf[1] = '\'';
109*6635Sab196087 			break;
110*6635Sab196087 		case '"':
111*6635Sab196087 			bs_buf[1] = '"';
112*6635Sab196087 			break;
113*6635Sab196087 		default:
114*6635Sab196087 			bs_buf[1] = '\0';
115*6635Sab196087 		}
116*6635Sab196087 
117*6635Sab196087 		if (bs_buf[1] != '\0') {
118*6635Sab196087 			(*outfunc)(bs_buf, 2, uvalue);
119*6635Sab196087 			buf++;
120*6635Sab196087 			n--;
121*6635Sab196087 		} else if (isprint(*buf)) {
122*6635Sab196087 			/*
123*6635Sab196087 			 * Output the entire sequence of printable
124*6635Sab196087 			 * characters in a single shot.
125*6635Sab196087 			 */
126*6635Sab196087 			const char	*start = buf;
127*6635Sab196087 			size_t		outlen = 0;
128*6635Sab196087 
129*6635Sab196087 			for (start = buf; (n > 0) && isprint(*buf); buf++, n--)
130*6635Sab196087 				outlen++;
131*6635Sab196087 			(*outfunc)(start, outlen, uvalue);
132*6635Sab196087 		} else {
133*6635Sab196087 			/* Generic unprintable character: Use octal notation */
134*6635Sab196087 			(void) snprintf(octal_buf, sizeof (octal_buf),
135*6635Sab196087 			    MSG_ORIG(MSG_FMT_OCTCONST), *buf);
136*6635Sab196087 			(*outfunc)(octal_buf, strlen(octal_buf), uvalue);
137*6635Sab196087 			buf++;
138*6635Sab196087 			n--;
139*6635Sab196087 		}
140*6635Sab196087 	}
141*6635Sab196087 }
142