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 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdio.h> 29 #include <strings.h> 30 #include <sys/machelf.h> 31 #include "_conv.h" 32 #include "globals_msg.h" 33 34 35 /* 36 * Given an integer value, generate an ASCII representation of it. 37 * 38 * entry: 39 * string - Buffer into which the resulting string is generated. 40 * size - Size of string buffer (i.e. sizeof(string)) 41 * value - Value to be formatted. 42 * fmt_flags - CONV_FMT_* values, used to specify formatting details. 43 * 44 * exit: 45 * The formatted string, or as much as will fit, is placed into 46 * string. String is returned. 47 */ 48 const char * 49 conv_invalid_val(char *string, size_t size, Xword value, int fmt_flags) 50 { 51 const char *fmt; 52 53 if (fmt_flags & CONV_FMT_DECIMAL) { 54 if (fmt_flags & CONV_FMT_SPACE) 55 fmt = MSG_ORIG(MSG_GBL_FMT_DECS); 56 else 57 fmt = MSG_ORIG(MSG_GBL_FMT_DEC); 58 } else { 59 if (fmt_flags & CONV_FMT_SPACE) 60 fmt = MSG_ORIG(MSG_GBL_FMT_HEXS); 61 else 62 fmt = MSG_ORIG(MSG_GBL_FMT_HEX); 63 } 64 (void) snprintf(string, size, fmt, value); 65 return ((const char *)string); 66 } 67 68 69 70 /* 71 * Provide a focal point for expanding bit-fields values into 72 * their corresponding strings. 73 * 74 * entry: 75 * string - Buffer into which the resulting string is generated. 76 * size - Size of string buffer (i.e. sizeof(string)) 77 * vdp - Array of value descriptors, giving the possible bit 78 * values, and their corresponding strings. Note that the 79 * final element must contain only NULL values. This 80 * terminates the list. 81 * oflags - Bits for which output strings are desired. 82 * rflags - Bits for which a numeric value should be printed 83 * if vdp does not provide a corresponding string. This 84 * must be a proper subset of oflags. 85 * separator - If non-NULL, a separator string to be inserted 86 * between each string value copied into the output. 87 * element - TRUE if first element output should be preceeded 88 * by a separator, and FALSE otherwise. 89 * 90 * exit: 91 * string contains the formatted result. True (1) is returned if there 92 * was no error, and False (0) if the buffer was too small. 93 */ 94 int 95 conv_expn_field(char *string, size_t size, const Val_desc *vdp, 96 Xword oflags, Xword rflags, const char *separator, int element) 97 { 98 const Val_desc *vde; 99 100 /* 101 * Traverse the callers Val_desc array and determine if the value 102 * corresponds to any array item. 103 */ 104 for (vde = vdp; vde->v_msg; vde++) { 105 if (oflags & vde->v_val) { 106 /* 107 * If a separator is required, and elements have already 108 * been added to the users output buffer, add the 109 * separator to the buffer first. 110 */ 111 if (separator && element++) { 112 if (strlcat(string, separator, size) >= size) { 113 (void) conv_invalid_val(string, size, 114 oflags, 0); 115 return (0); 116 } 117 } 118 119 /* 120 * Add the items strings to the users output buffer. 121 */ 122 if (strlcat(string, vde->v_msg, size) >= size) { 123 (void) conv_invalid_val(string, size, 124 oflags, 0); 125 return (0); 126 } 127 128 /* 129 * Indicate this item has been collected. 130 */ 131 rflags &= ~(vde->v_val); 132 } 133 } 134 135 /* 136 * If any flags remain, then they are unidentified. Add the number 137 * representation of these flags to the users output buffer. 138 */ 139 if (rflags) { 140 size_t off = strlen(string); 141 size_t rem = size - off; 142 143 (void) conv_invalid_val(&string[off], rem, rflags, 144 CONV_FMT_SPACE); 145 } 146 147 return (1); 148 } 149