xref: /onnv-gate/usr/src/cmd/sgs/libconv/common/globals_machelf.c (revision 9273:9a0603d78ad3)
1*9273SAli.Bahrami@Sun.COM /*
2*9273SAli.Bahrami@Sun.COM  * CDDL HEADER START
3*9273SAli.Bahrami@Sun.COM  *
4*9273SAli.Bahrami@Sun.COM  * The contents of this file are subject to the terms of the
5*9273SAli.Bahrami@Sun.COM  * Common Development and Distribution License (the "License").
6*9273SAli.Bahrami@Sun.COM  * You may not use this file except in compliance with the License.
7*9273SAli.Bahrami@Sun.COM  *
8*9273SAli.Bahrami@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*9273SAli.Bahrami@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*9273SAli.Bahrami@Sun.COM  * See the License for the specific language governing permissions
11*9273SAli.Bahrami@Sun.COM  * and limitations under the License.
12*9273SAli.Bahrami@Sun.COM  *
13*9273SAli.Bahrami@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*9273SAli.Bahrami@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*9273SAli.Bahrami@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*9273SAli.Bahrami@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*9273SAli.Bahrami@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*9273SAli.Bahrami@Sun.COM  *
19*9273SAli.Bahrami@Sun.COM  * CDDL HEADER END
20*9273SAli.Bahrami@Sun.COM  */
21*9273SAli.Bahrami@Sun.COM 
22*9273SAli.Bahrami@Sun.COM /*
23*9273SAli.Bahrami@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*9273SAli.Bahrami@Sun.COM  * Use is subject to license terms.
25*9273SAli.Bahrami@Sun.COM  */
26*9273SAli.Bahrami@Sun.COM 
27*9273SAli.Bahrami@Sun.COM #include	<stdio.h>
28*9273SAli.Bahrami@Sun.COM #include	<strings.h>
29*9273SAli.Bahrami@Sun.COM #include	<ctype.h>
30*9273SAli.Bahrami@Sun.COM #include	<_machelf.h>
31*9273SAli.Bahrami@Sun.COM #include	"_conv.h"
32*9273SAli.Bahrami@Sun.COM #include	"globals_msg.h"
33*9273SAli.Bahrami@Sun.COM 
34*9273SAli.Bahrami@Sun.COM 
35*9273SAli.Bahrami@Sun.COM /*
36*9273SAli.Bahrami@Sun.COM  * Given an integer value, generate an ASCII representation of it.
37*9273SAli.Bahrami@Sun.COM  *
38*9273SAli.Bahrami@Sun.COM  * entry:
39*9273SAli.Bahrami@Sun.COM  *	inv_buf - Buffer into which the resulting string is generated.
40*9273SAli.Bahrami@Sun.COM  *	value - Value to be formatted.
41*9273SAli.Bahrami@Sun.COM  *	fmt_flags - CONV_FMT_* values, used to specify formatting details.
42*9273SAli.Bahrami@Sun.COM  *
43*9273SAli.Bahrami@Sun.COM  * exit:
44*9273SAli.Bahrami@Sun.COM  *	The formatted string is placed into inv_buf. The pointer
45*9273SAli.Bahrami@Sun.COM  *	to the string is returned.
46*9273SAli.Bahrami@Sun.COM  */
47*9273SAli.Bahrami@Sun.COM const char *
48*9273SAli.Bahrami@Sun.COM conv_invalid_val(Conv_inv_buf_t *inv_buf, Xword value,
49*9273SAli.Bahrami@Sun.COM     Conv_fmt_flags_t fmt_flags)
50*9273SAli.Bahrami@Sun.COM {
51*9273SAli.Bahrami@Sun.COM 	const char	*fmt;
52*9273SAli.Bahrami@Sun.COM 
53*9273SAli.Bahrami@Sun.COM 	if (fmt_flags & CONV_FMT_DECIMAL) {
54*9273SAli.Bahrami@Sun.COM 		if (fmt_flags & CONV_FMT_SPACE)
55*9273SAli.Bahrami@Sun.COM 			fmt = MSG_ORIG(MSG_GBL_FMT_DECS);
56*9273SAli.Bahrami@Sun.COM 		else
57*9273SAli.Bahrami@Sun.COM 			fmt = MSG_ORIG(MSG_GBL_FMT_DEC);
58*9273SAli.Bahrami@Sun.COM 	} else {
59*9273SAli.Bahrami@Sun.COM 		if (fmt_flags & CONV_FMT_SPACE)
60*9273SAli.Bahrami@Sun.COM 			fmt = MSG_ORIG(MSG_GBL_FMT_HEXS);
61*9273SAli.Bahrami@Sun.COM 		else
62*9273SAli.Bahrami@Sun.COM 			fmt = MSG_ORIG(MSG_GBL_FMT_HEX);
63*9273SAli.Bahrami@Sun.COM 	}
64*9273SAli.Bahrami@Sun.COM 	(void) snprintf(inv_buf->buf, sizeof (inv_buf->buf), fmt, value);
65*9273SAli.Bahrami@Sun.COM 	return ((const char *)inv_buf->buf);
66*9273SAli.Bahrami@Sun.COM }
67*9273SAli.Bahrami@Sun.COM 
68*9273SAli.Bahrami@Sun.COM 
69*9273SAli.Bahrami@Sun.COM 
70*9273SAli.Bahrami@Sun.COM /*
71*9273SAli.Bahrami@Sun.COM  * cef_cp() is used by conv_expn_field() to fill in the output buffer.
72*9273SAli.Bahrami@Sun.COM  * A CONV_EXPN_FIELD_STATE variable is used to maintain the buffer state
73*9273SAli.Bahrami@Sun.COM  * as the operation progresses.
74*9273SAli.Bahrami@Sun.COM  *
75*9273SAli.Bahrami@Sun.COM  * entry:
76*9273SAli.Bahrami@Sun.COM  *	arg - As passed to conv_expn_field().
77*9273SAli.Bahrami@Sun.COM  *	state - Variable used to maintain buffer state between calls.
78*9273SAli.Bahrami@Sun.COM  *	list_item - TRUE(1) if this is a list item, and FALSE(0)
79*9273SAli.Bahrami@Sun.COM  *		if it is something else.
80*9273SAli.Bahrami@Sun.COM  *	str - String to be added to the buffer.
81*9273SAli.Bahrami@Sun.COM  *
82*9273SAli.Bahrami@Sun.COM  * exit:
83*9273SAli.Bahrami@Sun.COM  *	On Success:
84*9273SAli.Bahrami@Sun.COM  *		buffer contains the output string, including a list
85*9273SAli.Bahrami@Sun.COM  *		separator if appropriate. state has been updated.
86*9273SAli.Bahrami@Sun.COM  *		TRUE(1) is returned.
87*9273SAli.Bahrami@Sun.COM  *	On Failure:
88*9273SAli.Bahrami@Sun.COM  *		Buffer contains the numeric representation for the flags,
89*9273SAli.Bahrami@Sun.COM  *		and FALSE(0) is returned.
90*9273SAli.Bahrami@Sun.COM  */
91*9273SAli.Bahrami@Sun.COM typedef struct {
92*9273SAli.Bahrami@Sun.COM 	char *cur;		/* Current output position in buf */
93*9273SAli.Bahrami@Sun.COM 	size_t room;		/* # of bytes left in buf */
94*9273SAli.Bahrami@Sun.COM 	int list_cnt;		/* # of list items output into buf  */
95*9273SAli.Bahrami@Sun.COM 	const char *sep_str;	/* String used as list separator */
96*9273SAli.Bahrami@Sun.COM 	int sep_str_len;	/* strlen(sep_str) */
97*9273SAli.Bahrami@Sun.COM } CONV_EXPN_FIELD_STATE;
98*9273SAli.Bahrami@Sun.COM 
99*9273SAli.Bahrami@Sun.COM static int
100*9273SAli.Bahrami@Sun.COM cef_cp(CONV_EXPN_FIELD_ARG *arg, CONV_EXPN_FIELD_STATE *state,
101*9273SAli.Bahrami@Sun.COM 	int list_item, const char *str)
102*9273SAli.Bahrami@Sun.COM {
103*9273SAli.Bahrami@Sun.COM 	Conv_inv_buf_t inv_buf;
104*9273SAli.Bahrami@Sun.COM 	int n;
105*9273SAli.Bahrami@Sun.COM 
106*9273SAli.Bahrami@Sun.COM 	if (list_item) {	/* This is a list item */
107*9273SAli.Bahrami@Sun.COM 		/*
108*9273SAli.Bahrami@Sun.COM 		 * If list is non-empty, and the buffer has room,
109*9273SAli.Bahrami@Sun.COM 		 * then insert the separator.
110*9273SAli.Bahrami@Sun.COM 		 */
111*9273SAli.Bahrami@Sun.COM 		if (state->list_cnt != 0) {
112*9273SAli.Bahrami@Sun.COM 			if (state->sep_str_len < state->room) {
113*9273SAli.Bahrami@Sun.COM 				(void) memcpy(state->cur, state->sep_str,
114*9273SAli.Bahrami@Sun.COM 				    state->sep_str_len);
115*9273SAli.Bahrami@Sun.COM 				state->cur += state->sep_str_len;
116*9273SAli.Bahrami@Sun.COM 				state->room -= state->sep_str_len;
117*9273SAli.Bahrami@Sun.COM 			} else {
118*9273SAli.Bahrami@Sun.COM 				/* Ensure code below will catch lack of room */
119*9273SAli.Bahrami@Sun.COM 				state->room = 0;
120*9273SAli.Bahrami@Sun.COM 			}
121*9273SAli.Bahrami@Sun.COM 		}
122*9273SAli.Bahrami@Sun.COM 		state->list_cnt++;
123*9273SAli.Bahrami@Sun.COM 	}
124*9273SAli.Bahrami@Sun.COM 
125*9273SAli.Bahrami@Sun.COM 	n = strlen(str);
126*9273SAli.Bahrami@Sun.COM 	if (n < state->room) {
127*9273SAli.Bahrami@Sun.COM 		(void) memcpy(state->cur, str, n);
128*9273SAli.Bahrami@Sun.COM 		state->cur += n;
129*9273SAli.Bahrami@Sun.COM 		state->room -= n;
130*9273SAli.Bahrami@Sun.COM 		return (TRUE);
131*9273SAli.Bahrami@Sun.COM 	}
132*9273SAli.Bahrami@Sun.COM 
133*9273SAli.Bahrami@Sun.COM 	/* Buffer too small. Fill in the numeric value and report failure */
134*9273SAli.Bahrami@Sun.COM 	(void) conv_invalid_val(&inv_buf, arg->oflags, 0);
135*9273SAli.Bahrami@Sun.COM 	(void) strlcpy(arg->buf, inv_buf.buf, arg->bufsize);
136*9273SAli.Bahrami@Sun.COM 	return (FALSE);
137*9273SAli.Bahrami@Sun.COM }
138*9273SAli.Bahrami@Sun.COM 
139*9273SAli.Bahrami@Sun.COM 
140*9273SAli.Bahrami@Sun.COM 
141*9273SAli.Bahrami@Sun.COM /*
142*9273SAli.Bahrami@Sun.COM  * Common setup code for conv_expn_field() and conv_expn_field2()
143*9273SAli.Bahrami@Sun.COM  */
144*9273SAli.Bahrami@Sun.COM static int
145*9273SAli.Bahrami@Sun.COM cef_setup(CONV_EXPN_FIELD_ARG *arg, Conv_fmt_flags_t fmt_flags,
146*9273SAli.Bahrami@Sun.COM     CONV_EXPN_FIELD_STATE *state)
147*9273SAli.Bahrami@Sun.COM {
148*9273SAli.Bahrami@Sun.COM 	const char **lead_str;
149*9273SAli.Bahrami@Sun.COM 
150*9273SAli.Bahrami@Sun.COM 	/* Initialize buffer state */
151*9273SAli.Bahrami@Sun.COM 	state->cur = arg->buf;
152*9273SAli.Bahrami@Sun.COM 	state->room = arg->bufsize;
153*9273SAli.Bahrami@Sun.COM 	state->list_cnt = 0;
154*9273SAli.Bahrami@Sun.COM 	state->sep_str = arg->sep ? arg->sep : MSG_ORIG(MSG_GBL_SEP);
155*9273SAli.Bahrami@Sun.COM 	state->sep_str_len = strlen(state->sep_str);
156*9273SAli.Bahrami@Sun.COM 
157*9273SAli.Bahrami@Sun.COM 	/* Prefix string */
158*9273SAli.Bahrami@Sun.COM 	if ((fmt_flags & CONV_FMT_NOBKT) == 0)
159*9273SAli.Bahrami@Sun.COM 		if (!cef_cp(arg, state, FALSE,
160*9273SAli.Bahrami@Sun.COM 		    (arg->prefix ? arg->prefix : MSG_ORIG(MSG_GBL_OSQBRKT))))
161*9273SAli.Bahrami@Sun.COM 			return (FALSE);
162*9273SAli.Bahrami@Sun.COM 
163*9273SAli.Bahrami@Sun.COM 	/* Any strings in the lead_str array go at the head of the list */
164*9273SAli.Bahrami@Sun.COM 	lead_str = arg->lead_str;
165*9273SAli.Bahrami@Sun.COM 	if (lead_str) {
166*9273SAli.Bahrami@Sun.COM 		while (*lead_str) {
167*9273SAli.Bahrami@Sun.COM 			if (!cef_cp(arg, state, TRUE, *lead_str++))
168*9273SAli.Bahrami@Sun.COM 				return (FALSE);
169*9273SAli.Bahrami@Sun.COM 		}
170*9273SAli.Bahrami@Sun.COM 	}
171*9273SAli.Bahrami@Sun.COM 
172*9273SAli.Bahrami@Sun.COM 	return (TRUE);
173*9273SAli.Bahrami@Sun.COM }
174*9273SAli.Bahrami@Sun.COM 
175*9273SAli.Bahrami@Sun.COM /*
176*9273SAli.Bahrami@Sun.COM  * Common finishing code for conv_expn_field() and conv_expn_field2()
177*9273SAli.Bahrami@Sun.COM  */
178*9273SAli.Bahrami@Sun.COM static int
179*9273SAli.Bahrami@Sun.COM cef_wrap(CONV_EXPN_FIELD_ARG *arg, Conv_fmt_flags_t fmt_flags,
180*9273SAli.Bahrami@Sun.COM     CONV_EXPN_FIELD_STATE *state, Xword rflags)
181*9273SAli.Bahrami@Sun.COM {
182*9273SAli.Bahrami@Sun.COM 	/*
183*9273SAli.Bahrami@Sun.COM 	 * If any flags remain, then they are unidentified.  Add the numeric
184*9273SAli.Bahrami@Sun.COM 	 * representation of these flags to the users output buffer.
185*9273SAli.Bahrami@Sun.COM 	 */
186*9273SAli.Bahrami@Sun.COM 	if (rflags) {
187*9273SAli.Bahrami@Sun.COM 		Conv_inv_buf_t inv_buf;
188*9273SAli.Bahrami@Sun.COM 
189*9273SAli.Bahrami@Sun.COM 		(void) conv_invalid_val(&inv_buf, rflags, fmt_flags);
190*9273SAli.Bahrami@Sun.COM 		if (!cef_cp(arg, state, TRUE, inv_buf.buf))
191*9273SAli.Bahrami@Sun.COM 			return (FALSE);
192*9273SAli.Bahrami@Sun.COM 	}
193*9273SAli.Bahrami@Sun.COM 
194*9273SAli.Bahrami@Sun.COM 	/* Suffix string */
195*9273SAli.Bahrami@Sun.COM 	if ((fmt_flags & CONV_FMT_NOBKT) == 0)
196*9273SAli.Bahrami@Sun.COM 		if (!cef_cp(arg, state, FALSE,
197*9273SAli.Bahrami@Sun.COM 		    (arg->suffix ? arg->suffix : MSG_ORIG(MSG_GBL_CSQBRKT))))
198*9273SAli.Bahrami@Sun.COM 			return (FALSE);
199*9273SAli.Bahrami@Sun.COM 
200*9273SAli.Bahrami@Sun.COM 	/* Terminate the buffer */
201*9273SAli.Bahrami@Sun.COM 	*state->cur = '\0';
202*9273SAli.Bahrami@Sun.COM 
203*9273SAli.Bahrami@Sun.COM 	return (TRUE);
204*9273SAli.Bahrami@Sun.COM }
205*9273SAli.Bahrami@Sun.COM 
206*9273SAli.Bahrami@Sun.COM /*
207*9273SAli.Bahrami@Sun.COM  * Provide a focal point for expanding bit-fields values into
208*9273SAli.Bahrami@Sun.COM  * their corresponding strings.
209*9273SAli.Bahrami@Sun.COM  *
210*9273SAli.Bahrami@Sun.COM  * entry:
211*9273SAli.Bahrami@Sun.COM  *	arg - Specifies the operation to be carried out. See the
212*9273SAli.Bahrami@Sun.COM  *		definition of CONV_EXPN_FIELD_ARG in conv.h for details.
213*9273SAli.Bahrami@Sun.COM  *	vdp - Array of value descriptors, giving the possible bit values,
214*9273SAli.Bahrami@Sun.COM  *		and their corresponding strings. Note that the final element
215*9273SAli.Bahrami@Sun.COM  *		must contain only NULL values. This terminates the list.
216*9273SAli.Bahrami@Sun.COM  *
217*9273SAli.Bahrami@Sun.COM  * exit:
218*9273SAli.Bahrami@Sun.COM  *	arg->buf contains the formatted result. True (1) is returned if there
219*9273SAli.Bahrami@Sun.COM  *	was no error, and False (0) if the buffer was too small. In the failure
220*9273SAli.Bahrami@Sun.COM  *	case, arg->buf contains a numeric representation of the value.
221*9273SAli.Bahrami@Sun.COM  *
222*9273SAli.Bahrami@Sun.COM  * note:
223*9273SAli.Bahrami@Sun.COM  *	The Val_desc2 variant of this routine ignores entries from vdp that
224*9273SAli.Bahrami@Sun.COM  *	have a non-zero osabi or machine value that does not match that
225*9273SAli.Bahrami@Sun.COM  *	supplied by the caller.
226*9273SAli.Bahrami@Sun.COM  */
227*9273SAli.Bahrami@Sun.COM /*ARGSUSED3*/
228*9273SAli.Bahrami@Sun.COM int
229*9273SAli.Bahrami@Sun.COM _conv_expn_field(CONV_EXPN_FIELD_ARG *arg, const Val_desc *vdp,
230*9273SAli.Bahrami@Sun.COM     Conv_fmt_flags_t fmt_flags, const char *local_sgs_msg)
231*9273SAli.Bahrami@Sun.COM {
232*9273SAli.Bahrami@Sun.COM 	CONV_EXPN_FIELD_STATE state;
233*9273SAli.Bahrami@Sun.COM 	Xword rflags = arg->rflags;
234*9273SAli.Bahrami@Sun.COM 
235*9273SAli.Bahrami@Sun.COM 	if (cef_setup(arg, fmt_flags, &state) == FALSE)
236*9273SAli.Bahrami@Sun.COM 		return (FALSE);
237*9273SAli.Bahrami@Sun.COM 
238*9273SAli.Bahrami@Sun.COM 	/*
239*9273SAli.Bahrami@Sun.COM 	 * Traverse the callers Val_desc array and determine if the value
240*9273SAli.Bahrami@Sun.COM 	 * corresponds to any array item and add those that are to the list.
241*9273SAli.Bahrami@Sun.COM 	 */
242*9273SAli.Bahrami@Sun.COM 	for (; vdp->v_msg; vdp++) {
243*9273SAli.Bahrami@Sun.COM 		if (arg->oflags & vdp->v_val) {
244*9273SAli.Bahrami@Sun.COM 			if (!cef_cp(arg, &state, TRUE,
245*9273SAli.Bahrami@Sun.COM 			    MSG_ORIG_STRTAB(vdp->v_msg, local_sgs_msg)))
246*9273SAli.Bahrami@Sun.COM 				return (FALSE);
247*9273SAli.Bahrami@Sun.COM 
248*9273SAli.Bahrami@Sun.COM 			/* Indicate this item has been collected */
249*9273SAli.Bahrami@Sun.COM 			rflags &= ~(vdp->v_val);
250*9273SAli.Bahrami@Sun.COM 		}
251*9273SAli.Bahrami@Sun.COM 	}
252*9273SAli.Bahrami@Sun.COM 
253*9273SAli.Bahrami@Sun.COM 	return (cef_wrap(arg, fmt_flags, &state, rflags));
254*9273SAli.Bahrami@Sun.COM }
255*9273SAli.Bahrami@Sun.COM 
256*9273SAli.Bahrami@Sun.COM /*ARGSUSED5*/
257*9273SAli.Bahrami@Sun.COM int
258*9273SAli.Bahrami@Sun.COM _conv_expn_field2(CONV_EXPN_FIELD_ARG *arg, uchar_t osabi, Half mach,
259*9273SAli.Bahrami@Sun.COM     const Val_desc2 *vdp, Conv_fmt_flags_t fmt_flags, const char *local_sgs_msg)
260*9273SAli.Bahrami@Sun.COM {
261*9273SAli.Bahrami@Sun.COM 	CONV_EXPN_FIELD_STATE state;
262*9273SAli.Bahrami@Sun.COM 	Xword rflags = arg->rflags;
263*9273SAli.Bahrami@Sun.COM 
264*9273SAli.Bahrami@Sun.COM 	if (cef_setup(arg, fmt_flags, &state) == FALSE)
265*9273SAli.Bahrami@Sun.COM 		return (FALSE);
266*9273SAli.Bahrami@Sun.COM 
267*9273SAli.Bahrami@Sun.COM 	/*
268*9273SAli.Bahrami@Sun.COM 	 * Traverse the callers Val_desc array and determine if the value
269*9273SAli.Bahrami@Sun.COM 	 * corresponds to any array item and add those that are to the list.
270*9273SAli.Bahrami@Sun.COM 	 */
271*9273SAli.Bahrami@Sun.COM 	for (; vdp->v_msg; vdp++) {
272*9273SAli.Bahrami@Sun.COM 		if (CONV_VD2_SKIP(osabi, mach, vdp))
273*9273SAli.Bahrami@Sun.COM 			continue;
274*9273SAli.Bahrami@Sun.COM 
275*9273SAli.Bahrami@Sun.COM 		if (arg->oflags & vdp->v_val) {
276*9273SAli.Bahrami@Sun.COM 			if (!cef_cp(arg, &state, TRUE,
277*9273SAli.Bahrami@Sun.COM 			    MSG_ORIG_STRTAB(vdp->v_msg, local_sgs_msg)))
278*9273SAli.Bahrami@Sun.COM 				return (FALSE);
279*9273SAli.Bahrami@Sun.COM 
280*9273SAli.Bahrami@Sun.COM 			/* Indicate this item has been collected */
281*9273SAli.Bahrami@Sun.COM 			rflags &= ~(vdp->v_val);
282*9273SAli.Bahrami@Sun.COM 		}
283*9273SAli.Bahrami@Sun.COM 	}
284*9273SAli.Bahrami@Sun.COM 
285*9273SAli.Bahrami@Sun.COM 	return (cef_wrap(arg, fmt_flags, &state, rflags));
286*9273SAli.Bahrami@Sun.COM }
287