xref: /illumos-gate/usr/src/cmd/sgs/libconv/common/globals.c (revision 29e362da24db33a6650152985ef5626b4e6a810f)
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 const char *
35 conv_invalid_val(char *string, size_t size, Xword value, int flags)
36 {
37 	const char	*fmt;
38 
39 	if (flags & CONV_INV_DECIMAL) {
40 		if (flags & CONV_INV_SPACE)
41 			fmt = MSG_ORIG(MSG_GBL_FMT_DECS);
42 		else
43 			fmt = MSG_ORIG(MSG_GBL_FMT_DEC);
44 	} else {
45 		if (flags & CONV_INV_SPACE)
46 			fmt = MSG_ORIG(MSG_GBL_FMT_HEXS);
47 		else
48 			fmt = MSG_ORIG(MSG_GBL_FMT_HEX);
49 	}
50 	(void) snprintf(string, size, fmt, value);
51 	return ((const char *)string);
52 }
53 
54 /*
55  * Provide a focal point for expanding values (typically bit-fields) into
56  * their corresponding strings.
57  */
58 int
59 conv_expn_field(char *string, size_t size, const Val_desc *vdp,
60     Xword oflags, Xword rflags, const char *separator, int element)
61 {
62 	const Val_desc	*vde;
63 
64 	/*
65 	 * Traverse the callers Val_desc array and determine if the value
66 	 * corresponds to any array item.
67 	 */
68 	for (vde = vdp; vde->v_msg; vde++) {
69 		if (oflags & vde->v_val) {
70 			/*
71 			 * If a separator is required, and elements have already
72 			 * been added to the users output buffer, add the
73 			 * separator to the buffer first.
74 			 */
75 			if (separator && element++) {
76 				if (strlcat(string, separator, size) >= size) {
77 					(void) conv_invalid_val(string, size,
78 					    oflags, 0);
79 					return (0);
80 				}
81 			}
82 
83 			/*
84 			 * Add the items strings to the users output buffer.
85 			 */
86 			if (strlcat(string, vde->v_msg, size) >= size) {
87 				(void) conv_invalid_val(string, size,
88 				    oflags, 0);
89 				return (0);
90 			}
91 
92 			/*
93 			 * Indicate this item has been collected.
94 			 */
95 			rflags &= ~(vde->v_val);
96 		}
97 	}
98 
99 	/*
100 	 * If any flags remain, then they are unidentified.  Add the number
101 	 * representation of these flags to the users output buffer.
102 	 */
103 	if (rflags) {
104 		size_t  off = strlen(string);
105 		size_t  rem = size - off;
106 
107 		(void) conv_invalid_val(&string[off], rem, rflags,
108 		    CONV_INV_SPACE);
109 	}
110 
111 	return (1);
112 }
113