xref: /illumos-gate/usr/src/cmd/sgs/libconv/common/globals.c (revision c13de8f6a88563211bd4432ca11ca38ed3bf0fc0)
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