globals.c revision 2850:689acf945b89
1251881Speter/* 2251881Speter * CDDL HEADER START 3251881Speter * 4251881Speter * The contents of this file are subject to the terms of the 5251881Speter * Common Development and Distribution License (the "License"). 6251881Speter * You may not use this file except in compliance with the License. 7251881Speter * 8251881Speter * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9251881Speter * or http://www.opensolaris.org/os/licensing. 10251881Speter * See the License for the specific language governing permissions 11251881Speter * and limitations under the License. 12251881Speter * 13251881Speter * When distributing Covered Code, include this CDDL HEADER in each 14251881Speter * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15251881Speter * If applicable, add the following below this CDDL HEADER, with the 16251881Speter * fields enclosed by brackets "[]" replaced with your own identifying 17251881Speter * information: Portions Copyright [yyyy] [name of copyright owner] 18251881Speter * 19251881Speter * CDDL HEADER END 20251881Speter */ 21251881Speter 22251881Speter/* 23251881Speter * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24251881Speter * Use is subject to license terms. 25251881Speter */ 26251881Speter#pragma ident "%Z%%M% %I% %E% SMI" 27251881Speter 28251881Speter#include <stdio.h> 29251881Speter#include <strings.h> 30251881Speter#include <sys/machelf.h> 31251881Speter#include "_conv.h" 32251881Speter#include "globals_msg.h" 33251881Speter 34251881Speter 35251881Speter/* 36251881Speter * Given an integer value, generate an ASCII representation of it. 37251881Speter * 38251881Speter * entry: 39251881Speter * string - Buffer into which the resulting string is generated. 40251881Speter * size - Size of string buffer (i.e. sizeof(string)) 41251881Speter * value - Value to be formatted. 42251881Speter * fmt_flags - CONV_FMT_* values, used to specify formatting details. 43251881Speter * 44251881Speter * exit: 45251881Speter * The formatted string, or as much as will fit, is placed into 46251881Speter * string. String is returned. 47251881Speter */ 48251881Speterconst char * 49251881Speterconv_invalid_val(char *string, size_t size, Xword value, int fmt_flags) 50251881Speter{ 51251881Speter const char *fmt; 52251881Speter 53251881Speter if (fmt_flags & CONV_FMT_DECIMAL) { 54251881Speter if (fmt_flags & CONV_FMT_SPACE) 55251881Speter fmt = MSG_ORIG(MSG_GBL_FMT_DECS); 56251881Speter else 57251881Speter fmt = MSG_ORIG(MSG_GBL_FMT_DEC); 58251881Speter } else { 59251881Speter if (fmt_flags & CONV_FMT_SPACE) 60251881Speter fmt = MSG_ORIG(MSG_GBL_FMT_HEXS); 61251881Speter else 62251881Speter fmt = MSG_ORIG(MSG_GBL_FMT_HEX); 63251881Speter } 64251881Speter (void) snprintf(string, size, fmt, value); 65251881Speter return ((const char *)string); 66251881Speter} 67251881Speter 68251881Speter 69251881Speter 70251881Speter/* 71251881Speter * cef_cp() is used by conv_expn_field() to fill in the output buffer. 72251881Speter * A CONV_EXPN_FIELD_STATE variable is used to maintain the buffer state 73251881Speter * as the operation progresses. 74251881Speter * 75251881Speter * entry: 76251881Speter * arg - As passed to conv_expn_field(). 77251881Speter * state - Variable used to maintain buffer state between calls. 78251881Speter * list_item - TRUE(1) if this is a list item, and FALSE(0) 79251881Speter * if it is something else. 80251881Speter * str - String to be added to the buffer. 81251881Speter * 82251881Speter * exit: 83251881Speter * On Success: 84251881Speter * buffer contains the output string, including a list 85251881Speter * separator if appropriate. state has been updated. 86251881Speter * TRUE(1) is returned. 87251881Speter * On Failure: 88251881Speter * Buffer contains the numeric representation for the flags, 89251881Speter * and FALSE(0) is returned. 90251881Speter */ 91251881Spetertypedef struct { 92251881Speter char *cur; /* Current output position in buf */ 93251881Speter size_t room; /* # of bytes left in buf */ 94251881Speter int list_cnt; /* # of list items output into buf */ 95251881Speter const char *sep_str; /* String used as list separator */ 96251881Speter int sep_str_len; /* strlen(sep_str) */ 97251881Speter} CONV_EXPN_FIELD_STATE; 98251881Speter 99251881Speterstatic int 100251881Spetercef_cp(CONV_EXPN_FIELD_ARG *arg, CONV_EXPN_FIELD_STATE *state, 101251881Speter int list_item, const char *str) 102251881Speter{ 103251881Speter int n; 104251881Speter 105251881Speter if (list_item) { /* This is a list item */ 106251881Speter /* 107251881Speter * If list is non-empty, and the buffer has room, 108251881Speter * then insert the separator. 109251881Speter */ 110251881Speter if (state->list_cnt != 0) { 111251881Speter if (state->sep_str_len < state->room) { 112251881Speter (void) memcpy(state->cur, state->sep_str, 113251881Speter state->sep_str_len); 114251881Speter state->cur += state->sep_str_len; 115251881Speter state->room -= state->sep_str_len; 116251881Speter } else { 117251881Speter /* Ensure code below will catch lack of room */ 118251881Speter state->room = 0; 119251881Speter } 120251881Speter } 121251881Speter state->list_cnt++; 122251881Speter } 123251881Speter 124251881Speter n = strlen(str); 125251881Speter if (n < state->room) { 126251881Speter (void) memcpy(state->cur, str, n); 127251881Speter state->cur += n; 128251881Speter state->room -= n; 129251881Speter return (TRUE); 130251881Speter } 131251881Speter 132251881Speter /* Buffer too small. Fill in the numeric value and report failure */ 133251881Speter (void) conv_invalid_val(arg->buf, arg->bufsize, arg->oflags, 0); 134251881Speter return (FALSE); 135251881Speter} 136251881Speter 137251881Speter 138251881Speter 139251881Speter/* 140251881Speter * Provide a focal point for expanding bit-fields values into 141251881Speter * their corresponding strings. 142251881Speter * 143251881Speter * entry: 144251881Speter * arg - Specifies the operation to be carried out. See the 145251881Speter * definition of CONV_EXPN_FIELD_ARG in conv.h for details. 146251881Speter * 147251881Speter * exit: 148251881Speter * arg->buf contains the formatted result. True (1) is returned if there 149251881Speter * was no error, and False (0) if the buffer was too small. In the failure 150251881Speter * case, arg->buf contains a numeric representation of the value. 151251881Speter */ 152251881Speterint 153251881Speterconv_expn_field(CONV_EXPN_FIELD_ARG *arg) 154251881Speter{ 155251881Speter const Val_desc *vde; 156251881Speter CONV_EXPN_FIELD_STATE state; 157251881Speter Xword rflags = arg->rflags; 158251881Speter const char **lead_str; 159251881Speter 160251881Speter 161251881Speter /* Initialize buffer state */ 162251881Speter state.cur = arg->buf; 163251881Speter state.room = arg->bufsize; 164251881Speter state.list_cnt = 0; 165251881Speter state.sep_str = arg->sep ? arg->sep : MSG_ORIG(MSG_GBL_SEP); 166251881Speter state.sep_str_len = strlen(state.sep_str); 167251881Speter 168251881Speter /* Prefix string */ 169251881Speter if (!cef_cp(arg, &state, FALSE, 170251881Speter (arg->prefix ? arg->prefix : MSG_ORIG(MSG_GBL_OSQBRKT)))) 171251881Speter return (FALSE); 172251881Speter 173251881Speter /* Any strings in the lead_str array go at the head of the list */ 174251881Speter lead_str = arg->lead_str; 175251881Speter if (lead_str) { 176251881Speter while (*lead_str) { 177251881Speter if (!cef_cp(arg, &state, TRUE, *lead_str++)) 178251881Speter return (FALSE); 179251881Speter } 180251881Speter } 181251881Speter 182251881Speter /* 183251881Speter * Traverse the callers Val_desc array and determine if the value 184251881Speter * corresponds to any array item and add those that are to the list. 185251881Speter */ 186251881Speter for (vde = arg->vdp; vde->v_msg; vde++) { 187251881Speter if (arg->oflags & vde->v_val) { 188251881Speter if (!cef_cp(arg, &state, TRUE, vde->v_msg)) 189251881Speter return (FALSE); 190251881Speter 191251881Speter /* Indicate this item has been collected */ 192251881Speter rflags &= ~(vde->v_val); 193251881Speter } 194251881Speter } 195251881Speter 196251881Speter /* 197251881Speter * If any flags remain, then they are unidentified. Add the numeric 198251881Speter * representation of these flags to the users output buffer. 199251881Speter */ 200251881Speter if (rflags) { 201251881Speter Conv_inv_buf_t ibuf; 202251881Speter 203251881Speter (void) conv_invalid_val(ibuf, sizeof (ibuf), rflags, 0); 204251881Speter if (!cef_cp(arg, &state, TRUE, ibuf)) 205251881Speter return (FALSE); 206251881Speter } 207251881Speter 208251881Speter /* Suffix string */ 209251881Speter if (!cef_cp(arg, &state, FALSE, 210251881Speter (arg->suffix ? arg->suffix : MSG_ORIG(MSG_GBL_CSQBRKT)))) 211251881Speter return (FALSE); 212251881Speter 213251881Speter /* Terminate the buffer */ 214251881Speter *state.cur = '\0'; 215251881Speter 216251881Speter return (TRUE); 217251881Speter} 218251881Speter