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 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 30 /* 31 * Translate a string into C literal string constant notation. 32 */ 33 34 #include <stdio.h> 35 #include <ctype.h> 36 #include <_conv.h> 37 #include <c_literal_msg.h> 38 39 40 /* 41 * Convert characters to the form used by the C language to represent 42 * literal strings: 43 * - Printable characters are shown as themselves 44 * - Convert special characters to their 2-character escaped forms: 45 * alert (bell) \a 46 * backspace \b 47 * formfeed \f 48 * newline \n 49 * return \r 50 * horizontal tab \t 51 * vertical tab \v 52 * backspace \\ 53 * single quote \' 54 * double quote \" 55 * - Display other non-printable characters as 4-character escaped 56 * octal constants. 57 * 58 * entry: 59 * buf - Buffer of characters to be processed 60 * n # of characters in buf to be processed 61 * outfunc - Function to be called to move output characters. 62 * uvalue - User value. This argument is passed to outfunc without 63 * examination. The caller can use it to pass additional 64 * information required by the callback. 65 * 66 * exit: 67 * The string has been processed, with the resulting data passed 68 * to outfunc for processing. 69 */ 70 void 71 conv_str_to_c_literal(const char *buf, size_t n, 72 Conv_str_to_c_literal_func_t *outfunc, void *uvalue) 73 { 74 char bs_buf[2]; /* For two-character backslash codes */ 75 char octal_buf[10]; /* For \000 style octal constants */ 76 77 bs_buf[0] = '\\'; 78 while (n > 0) { 79 switch (*buf) { 80 case '\0': 81 bs_buf[1] = '0'; 82 break; 83 case '\a': 84 bs_buf[1] = 'a'; 85 break; 86 case '\b': 87 bs_buf[1] = 'b'; 88 break; 89 case '\f': 90 bs_buf[1] = 'f'; 91 break; 92 case '\n': 93 bs_buf[1] = 'n'; 94 break; 95 case '\r': 96 bs_buf[1] = 'r'; 97 break; 98 case '\t': 99 bs_buf[1] = 't'; 100 break; 101 case '\v': 102 bs_buf[1] = 'v'; 103 break; 104 case '\\': 105 bs_buf[1] = '\\'; 106 break; 107 case '\'': 108 bs_buf[1] = '\''; 109 break; 110 case '"': 111 bs_buf[1] = '"'; 112 break; 113 default: 114 bs_buf[1] = '\0'; 115 } 116 117 if (bs_buf[1] != '\0') { 118 (*outfunc)(bs_buf, 2, uvalue); 119 buf++; 120 n--; 121 } else if (isprint(*buf)) { 122 /* 123 * Output the entire sequence of printable 124 * characters in a single shot. 125 */ 126 const char *start = buf; 127 size_t outlen = 0; 128 129 for (start = buf; (n > 0) && isprint(*buf); buf++, n--) 130 outlen++; 131 (*outfunc)(start, outlen, uvalue); 132 } else { 133 /* Generic unprintable character: Use octal notation */ 134 (void) snprintf(octal_buf, sizeof (octal_buf), 135 MSG_ORIG(MSG_FMT_OCTCONST), *buf); 136 (*outfunc)(octal_buf, strlen(octal_buf), uvalue); 137 buf++; 138 n--; 139 } 140 } 141 } 142