globals.c revision 1976:f0691a145b7e
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 */
48const char *
49conv_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 */
94int
95conv_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