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