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