1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************************** 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius* Copyright (C) 1998-2011, International Business Machines 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************************** 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* File uprntf_p.c 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Modification History: 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Date Name Description 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 11/23/98 stephen Creation. 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 03/12/99 stephen Modified for new C API. 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 08/07/2003 george Reunify printf implementations 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************************** 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ustring.h" 2583a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#include "unicode/utf16.h" 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uprintf.h" 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ufmt_cmn.h" 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h" 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "putilimp.h" 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* ANSI style formatting */ 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Use US-ASCII characters only for formatting */ 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* % */ 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_SIMPLE_PERCENT {ufmt_simple_percent, u_printf_simple_percent_handler} 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* s */ 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_STRING {ufmt_string, u_printf_string_handler} 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* c */ 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_CHAR {ufmt_char, u_printf_char_handler} 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* d, i */ 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_INT {ufmt_int, u_printf_integer_handler} 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* u */ 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_UINT {ufmt_int, u_printf_uinteger_handler} 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* o */ 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_OCTAL {ufmt_int, u_printf_octal_handler} 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* x, X */ 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_HEX {ufmt_int, u_printf_hex_handler} 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* f */ 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_DOUBLE {ufmt_double, u_printf_double_handler} 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* e, E */ 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_SCIENTIFIC {ufmt_double, u_printf_scientific_handler} 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* g, G */ 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_SCIDBL {ufmt_double, u_printf_scidbl_handler} 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* n */ 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_COUNT {ufmt_count, u_printf_count_handler} 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* non-ANSI extensions */ 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Use US-ASCII characters only for formatting */ 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* p */ 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_POINTER {ufmt_pointer, u_printf_pointer_handler} 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* V */ 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_SPELLOUT {ufmt_double, u_printf_spellout_handler} 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* P */ 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_PERCENT {ufmt_double, u_printf_percent_handler} 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* C K is old format */ 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_UCHAR {ufmt_uchar, u_printf_uchar_handler} 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* S U is old format */ 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_USTRING {ufmt_ustring, u_printf_ustring_handler} 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_EMPTY {ufmt_empty, NULL} 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * A u_printf handler function. 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * A u_printf handler is responsible for handling a single u_printf 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * format specification, for example 'd' or 's'. 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param stream The UFILE to which to write output. 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param info A pointer to a <TT>u_printf_spec_info</TT> struct containing 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * information on the format specification. 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param args A pointer to the argument data 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return The number of Unicode characters written to <TT>stream</TT>. 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef int32_t U_EXPORT2 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_handler(const u_printf_stream_handler *handler, 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ufmt_args *args); 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef struct u_printf_info { 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ufmt_type_info info; 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_printf_handler *handler; 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} u_printf_info; 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Struct encapsulating a single uprintf format specification. 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef struct u_printf_spec { 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_printf_spec_info fInfo; /* Information on this spec */ 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t fWidthPos; /* Position of width in arg list */ 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t fPrecisionPos; /* Position of precision in arg list */ 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t fArgPos; /* Position of data in arg list */ 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} u_printf_spec; 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UPRINTF_NUM_FMT_HANDLERS 108 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* We do not use handlers for 0-0x1f */ 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UPRINTF_BASE_FMT_HANDLERS 0x20 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* buffer size for formatting */ 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UPRINTF_BUFFER_SIZE 1024 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UPRINTF_SYMBOL_BUFFER_SIZE 8 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar gNullStr[] = {0x28, 0x6E, 0x75, 0x6C, 0x6C, 0x29, 0}; /* "(null)" */ 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar gSpaceStr[] = {0x20, 0}; /* " " */ 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Sets the sign of a format based on u_printf_spec_info */ 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* TODO: Is setting the prefix symbol to a positive sign a good idea in all locales? */ 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_set_sign(UNumberFormat *format, 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *prefixBuffer, 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t *prefixBufLen, 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *status) 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(info->fShowSign) { 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *prefixBufLen = unum_getTextAttribute(format, 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNUM_POSITIVE_PREFIX, 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru prefixBuffer, 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *prefixBufLen, 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status); 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fSpace) { 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Setting UNUM_PLUS_SIGN_SYMBOL affects the exponent too. */ 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* unum_setSymbol(format, UNUM_PLUS_SIGN_SYMBOL, gSpaceStr, 1, &status); */ 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setTextAttribute(format, UNUM_POSITIVE_PREFIX, gSpaceStr, 1, status); 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar plusSymbol[UPRINTF_SYMBOL_BUFFER_SIZE]; 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t symbolLen; 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru symbolLen = unum_getSymbol(format, 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNUM_PLUS_SIGN_SYMBOL, 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru plusSymbol, 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sizeof(plusSymbol)/sizeof(*plusSymbol), 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status); 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setTextAttribute(format, 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNUM_POSITIVE_PREFIX, 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru plusSymbol, 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru symbolLen, 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status); 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *prefixBufLen = 0; 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_reset_sign(UNumberFormat *format, 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *prefixBuffer, 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t *prefixBufLen, 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *status) 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(info->fShowSign) { 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setTextAttribute(format, 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNUM_POSITIVE_PREFIX, 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru prefixBuffer, 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *prefixBufLen, 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status); 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* handle a '%' */ 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_simple_percent_handler(const u_printf_stream_handler *handler, 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ufmt_args *args) 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru static const UChar PERCENT[] = { UP_PERCENT }; 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* put a single '%' onto the output */ 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return handler->write(context, PERCENT, 1); 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* handle 's' */ 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_string_handler(const u_printf_stream_handler *handler, 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ufmt_args *args) 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *s; 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar buffer[UFMT_DEFAULT_BUFFER_SIZE]; 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len, written; 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t argSize; 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *arg = (const char*)(args[0].ptrValue); 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* convert from the default codepage to Unicode */ 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (arg) { 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru argSize = (int32_t)strlen(arg) + 1; 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (argSize >= MAX_UCHAR_BUFFER_SIZE(buffer)) { 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru s = ufmt_defaultCPToUnicode(arg, argSize, 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (UChar *)uprv_malloc(MAX_UCHAR_BUFFER_NEEDED(argSize)), 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru MAX_UCHAR_BUFFER_NEEDED(argSize)); 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(s == NULL) { 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru s = ufmt_defaultCPToUnicode(arg, argSize, buffer, 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sizeof(buffer)/sizeof(UChar)); 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru s = (UChar *)gNullStr; 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru len = u_strlen(s); 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* width = minimum # of characters to write */ 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* precision = maximum # of characters to write */ 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fPrecision != -1 && info->fPrecision < len) { 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru len = info->fPrecision; 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru written = handler->pad_and_justify(context, info, s, len); 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* clean up */ 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (gNullStr != s && buffer != s) { 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(s); 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return written; 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_char_handler(const u_printf_stream_handler *handler, 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ufmt_args *args) 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 24983a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius UChar s[U16_MAX_LENGTH+1]; 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = 1, written; 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unsigned char arg = (unsigned char)(args[0].int64Value); 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* convert from default codepage to Unicode */ 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ufmt_defaultCPToUnicode((const char *)&arg, 2, s, sizeof(s)/sizeof(UChar)); 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Remember that this may be an MBCS character */ 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (arg != 0) { 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru len = u_strlen(s); 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* width = minimum # of characters to write */ 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* precision = maximum # of characters to write */ 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* precision is ignored when handling a char */ 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru written = handler->pad_and_justify(context, info, s, len); 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return written; 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_double_handler(const u_printf_stream_handler *handler, 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ufmt_args *args) 276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru double num = (double) (args[0].doubleValue); 278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNumberFormat *format; 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar result[UPRINTF_BUFFER_SIZE]; 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar prefixBuffer[UPRINTF_BUFFER_SIZE]; 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t prefixBufferLen = sizeof(prefixBuffer); 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t minDecimalDigits; 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t maxDecimalDigits; 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t resultLen; 285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru prefixBuffer[0] = 0; 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* mask off any necessary bits */ 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if(! info->fIsLongDouble) 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru num &= DBL_MAX;*/ 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* get the formatter */ 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL); 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* handle error */ 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(format == 0) 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* save the formatter's state */ 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS); 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS); 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the appropriate flags and number of decimal digits on the formatter */ 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(info->fPrecision != -1) { 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the # of decimal digits */ 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision); 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if(info->fAlt) { 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* '#' means always show decimal point */ 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy of printf behavior on Solaris - '#' shows 6 digits */ 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* # of decimal digits is 6 if precision not specified regardless of locale */ 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set whether to show the sign */ 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fShowSign) { 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_printf_set_sign(format, info, prefixBuffer, &prefixBufferLen, &status); 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* format the number */ 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru resultLen = unum_formatDouble(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru resultLen = 0; 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* restore the number format */ 332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* TODO: Is this needed? */ 333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits); 334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits); 335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fShowSign) { 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Reset back to original value regardless of what the error was */ 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode localStatus = U_ZERO_ERROR; 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_printf_reset_sign(format, info, prefixBuffer, &prefixBufferLen, &localStatus); 340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return handler->pad_and_justify(context, info, result, resultLen); 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* HSYS */ 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_integer_handler(const u_printf_stream_handler *handler, 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ufmt_args *args) 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int64_t num = args[0].int64Value; 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNumberFormat *format; 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar result[UPRINTF_BUFFER_SIZE]; 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar prefixBuffer[UPRINTF_BUFFER_SIZE]; 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t prefixBufferLen = sizeof(prefixBuffer); 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t minDigits = -1; 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t resultLen; 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru prefixBuffer[0] = 0; 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* mask off any necessary bits */ 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fIsShort) 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru num = (int16_t)num; 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if (!info->fIsLongLong) 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru num = (int32_t)num; 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* get the formatter */ 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL); 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* handle error */ 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(format == 0) 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the appropriate flags on the formatter */ 378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the minimum integer digits */ 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(info->fPrecision != -1) { 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the minimum # of digits */ 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru minDigits = unum_getAttribute(format, UNUM_MIN_INTEGER_DIGITS); 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, info->fPrecision); 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set whether to show the sign */ 387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(info->fShowSign) { 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_printf_set_sign(format, info, prefixBuffer, &prefixBufferLen, &status); 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* format the number */ 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru resultLen = unum_formatInt64(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); 393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru resultLen = 0; 396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* restore the number format */ 399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (minDigits != -1) { 400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, minDigits); 401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fShowSign) { 404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Reset back to original value regardless of what the error was */ 405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode localStatus = U_ZERO_ERROR; 406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_printf_reset_sign(format, info, prefixBuffer, &prefixBufferLen, &localStatus); 407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return handler->pad_and_justify(context, info, result, resultLen); 410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_hex_handler(const u_printf_stream_handler *handler, 414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ufmt_args *args) 418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int64_t num = args[0].int64Value; 420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar result[UPRINTF_BUFFER_SIZE]; 421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = UPRINTF_BUFFER_SIZE; 422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* mask off any necessary bits */ 425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fIsShort) 426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru num &= UINT16_MAX; 427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if (!info->fIsLongLong) 428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru num &= UINT32_MAX; 429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* format the number, preserving the minimum # of digits */ 431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ufmt_64tou(result, &len, num, 16, 432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (UBool)(info->fSpec == 0x0078), 433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (info->fPrecision == -1 && info->fZero) ? info->fWidth : info->fPrecision); 434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* convert to alt form, if desired */ 436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(num != 0 && info->fAlt && len < UPRINTF_BUFFER_SIZE - 2) { 437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* shift the formatted string right by 2 chars */ 438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru memmove(result + 2, result, len * sizeof(UChar)); 439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result[0] = 0x0030; 440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result[1] = info->fSpec; 441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru len += 2; 442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return handler->pad_and_justify(context, info, result, len); 445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_octal_handler(const u_printf_stream_handler *handler, 449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ufmt_args *args) 453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int64_t num = args[0].int64Value; 455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar result[UPRINTF_BUFFER_SIZE]; 456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = UPRINTF_BUFFER_SIZE; 457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* mask off any necessary bits */ 460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fIsShort) 461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru num &= UINT16_MAX; 462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if (!info->fIsLongLong) 463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru num &= UINT32_MAX; 464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* format the number, preserving the minimum # of digits */ 466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ufmt_64tou(result, &len, num, 8, 467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FALSE, /* doesn't matter for octal */ 468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fPrecision == -1 && info->fZero ? info->fWidth : info->fPrecision); 469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* convert to alt form, if desired */ 471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(info->fAlt && result[0] != 0x0030 && len < UPRINTF_BUFFER_SIZE - 1) { 472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* shift the formatted string right by 1 char */ 473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru memmove(result + 1, result, len * sizeof(UChar)); 474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result[0] = 0x0030; 475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru len += 1; 476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return handler->pad_and_justify(context, info, result, len); 479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_uinteger_handler(const u_printf_stream_handler *handler, 483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ufmt_args *args) 487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int64_t num = args[0].int64Value; 489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNumberFormat *format; 490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar result[UPRINTF_BUFFER_SIZE]; 491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t minDigits = -1; 492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t resultLen; 493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* TODO: Fix this once uint64_t can be formatted. */ 496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fIsShort) 497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru num &= UINT16_MAX; 498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if (!info->fIsLongLong) 499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru num &= UINT32_MAX; 500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* get the formatter */ 502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL); 503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* handle error */ 505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(format == 0) 506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the appropriate flags on the formatter */ 509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the minimum integer digits */ 511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(info->fPrecision != -1) { 512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the minimum # of digits */ 513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru minDigits = unum_getAttribute(format, UNUM_MIN_INTEGER_DIGITS); 514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, info->fPrecision); 515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* To mirror other stdio implementations, we ignore the sign argument */ 518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* format the number */ 520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru resultLen = unum_formatInt64(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); 521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru resultLen = 0; 524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* restore the number format */ 527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (minDigits != -1) { 528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, minDigits); 529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return handler->pad_and_justify(context, info, result, resultLen); 532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_pointer_handler(const u_printf_stream_handler *handler, 536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ufmt_args *args) 540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar result[UPRINTF_BUFFER_SIZE]; 542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = UPRINTF_BUFFER_SIZE; 543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* format the pointer in hex */ 545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ufmt_ptou(result, &len, args[0].ptrValue, TRUE/*, info->fPrecision*/); 546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return handler->pad_and_justify(context, info, result, len); 548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_scientific_handler(const u_printf_stream_handler *handler, 552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ufmt_args *args) 556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru double num = (double) (args[0].doubleValue); 558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNumberFormat *format; 559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar result[UPRINTF_BUFFER_SIZE]; 560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar prefixBuffer[UPRINTF_BUFFER_SIZE]; 561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t prefixBufferLen = sizeof(prefixBuffer); 562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t minDecimalDigits; 563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t maxDecimalDigits; 564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar srcExpBuf[UPRINTF_SYMBOL_BUFFER_SIZE]; 566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t srcLen, expLen; 567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t resultLen; 568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar expBuf[UPRINTF_SYMBOL_BUFFER_SIZE]; 569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru prefixBuffer[0] = 0; 571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* mask off any necessary bits */ 573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if(! info->fIsLongDouble) 574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru num &= DBL_MAX;*/ 575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* get the formatter */ 577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru format = u_locbund_getNumberFormat(formatBundle, UNUM_SCIENTIFIC); 578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* handle error */ 580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(format == 0) 581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the appropriate flags on the formatter */ 584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srcLen = unum_getSymbol(format, 586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNUM_EXPONENTIAL_SYMBOL, 587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srcExpBuf, 588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sizeof(srcExpBuf), 589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &status); 590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Upper/lower case the e */ 592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fSpec == (UChar)0x65 /* e */) { 593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru expLen = u_strToLower(expBuf, (int32_t)sizeof(expBuf), 594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srcExpBuf, srcLen, 595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru formatBundle->fLocale, 596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &status); 597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru expLen = u_strToUpper(expBuf, (int32_t)sizeof(expBuf), 600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srcExpBuf, srcLen, 601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru formatBundle->fLocale, 602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &status); 603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setSymbol(format, 606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNUM_EXPONENTIAL_SYMBOL, 607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru expBuf, 608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru expLen, 609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &status); 610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* save the formatter's state */ 612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS); 613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS); 614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the appropriate flags and number of decimal digits on the formatter */ 616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(info->fPrecision != -1) { 617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the # of decimal digits */ 618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fOrigSpec == (UChar)0x65 /* e */ || info->fOrigSpec == (UChar)0x45 /* E */) { 619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision); 620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, 1); 623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, info->fPrecision); 624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if(info->fAlt) { 627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* '#' means always show decimal point */ 628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy of printf behavior on Solaris - '#' shows 6 digits */ 629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); 630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* # of decimal digits is 6 if precision not specified */ 633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); 634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set whether to show the sign */ 637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fShowSign) { 638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_printf_set_sign(format, info, prefixBuffer, &prefixBufferLen, &status); 639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* format the number */ 642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru resultLen = unum_formatDouble(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); 643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru resultLen = 0; 646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* restore the number format */ 649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* TODO: Is this needed? */ 650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits); 651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits); 652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Since we're the only one using the scientific 654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru format, we don't need to save the old exponent value. */ 655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*unum_setSymbol(format, 656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNUM_EXPONENTIAL_SYMBOL, 657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srcExpBuf, 658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srcLen, 659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &status);*/ 660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fShowSign) { 662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Reset back to original value regardless of what the error was */ 663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode localStatus = U_ZERO_ERROR; 664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_printf_reset_sign(format, info, prefixBuffer, &prefixBufferLen, &localStatus); 665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return handler->pad_and_justify(context, info, result, resultLen); 668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_percent_handler(const u_printf_stream_handler *handler, 672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ufmt_args *args) 676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru double num = (double) (args[0].doubleValue); 678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNumberFormat *format; 679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar result[UPRINTF_BUFFER_SIZE]; 680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar prefixBuffer[UPRINTF_BUFFER_SIZE]; 681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t prefixBufferLen = sizeof(prefixBuffer); 682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t minDecimalDigits; 683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t maxDecimalDigits; 684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t resultLen; 685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru prefixBuffer[0] = 0; 688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* mask off any necessary bits */ 690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if(! info->fIsLongDouble) 691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru num &= DBL_MAX;*/ 692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* get the formatter */ 694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru format = u_locbund_getNumberFormat(formatBundle, UNUM_PERCENT); 695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* handle error */ 697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(format == 0) 698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* save the formatter's state */ 701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS); 702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS); 703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the appropriate flags and number of decimal digits on the formatter */ 705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(info->fPrecision != -1) { 706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the # of decimal digits */ 707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision); 708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if(info->fAlt) { 710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* '#' means always show decimal point */ 711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy of printf behavior on Solaris - '#' shows 6 digits */ 712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); 713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 715ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* # of decimal digits is 6 if precision not specified */ 716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); 717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set whether to show the sign */ 720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fShowSign) { 721ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_printf_set_sign(format, info, prefixBuffer, &prefixBufferLen, &status); 722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* format the number */ 725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru resultLen = unum_formatDouble(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); 726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru resultLen = 0; 729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* restore the number format */ 732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* TODO: Is this needed? */ 733ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits); 734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits); 735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fShowSign) { 737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Reset back to original value regardless of what the error was */ 738ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode localStatus = U_ZERO_ERROR; 739ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_printf_reset_sign(format, info, prefixBuffer, &prefixBufferLen, &localStatus); 740ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 741ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 742ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return handler->pad_and_justify(context, info, result, resultLen); 743ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 744ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 745ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 746ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_ustring_handler(const u_printf_stream_handler *handler, 747ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 748ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 749ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 750ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ufmt_args *args) 751ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len, written; 753ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *arg = (const UChar*)(args[0].ptrValue); 754ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 755ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* allocate enough space for the buffer */ 756ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (arg == NULL) { 757ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru arg = gNullStr; 758ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 759ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru len = u_strlen(arg); 760ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* width = minimum # of characters to write */ 762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* precision = maximum # of characters to write */ 763ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fPrecision != -1 && info->fPrecision < len) { 764ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru len = info->fPrecision; 765ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 766ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 767ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* determine if the string should be padded */ 768ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru written = handler->pad_and_justify(context, info, arg, len); 769ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 770ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return written; 771ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 772ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 774ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_uchar_handler(const u_printf_stream_handler *handler, 775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 776ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ufmt_args *args) 779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t written = 0; 781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar arg = (UChar)(args[0].int64Value); 782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* width = minimum # of characters to write */ 784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* precision = maximum # of characters to write */ 785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* precision is ignored when handling a uchar */ 786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* determine if the string should be padded */ 788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru written = handler->pad_and_justify(context, info, &arg, 1); 789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return written; 791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_scidbl_handler(const u_printf_stream_handler *handler, 795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ufmt_args *args) 799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_printf_spec_info scidbl_info; 801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru double num = args[0].doubleValue; 802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t retVal; 80385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UNumberFormat *format; 80485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho int32_t maxSigDecimalDigits, significantDigits; 805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru memcpy(&scidbl_info, info, sizeof(u_printf_spec_info)); 807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* determine whether to use 'd', 'e' or 'f' notation */ 809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (scidbl_info.fPrecision == -1 && num == uprv_trunc(num)) 810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* use 'f' notation */ 812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru scidbl_info.fSpec = 0x0066; 813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru scidbl_info.fPrecision = 0; 814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* call the double handler */ 815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru retVal = u_printf_double_handler(handler, context, formatBundle, &scidbl_info, args); 816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if(num < 0.0001 || (scidbl_info.fPrecision < 1 && 1000000.0 <= num) 818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru || (scidbl_info.fPrecision != -1 && num > uprv_pow10(scidbl_info.fPrecision))) 819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* use 'e' or 'E' notation */ 821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru scidbl_info.fSpec = scidbl_info.fSpec - 2; 822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (scidbl_info.fPrecision == -1) { 823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru scidbl_info.fPrecision = 5; 824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* call the scientific handler */ 826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru retVal = u_printf_scientific_handler(handler, context, formatBundle, &scidbl_info, args); 827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 82985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL); 83085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* Check for null pointer */ 83185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (format == NULL) { 83285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return 0; 83385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 83485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho maxSigDecimalDigits = unum_getAttribute(format, UNUM_MAX_SIGNIFICANT_DIGITS); 83585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho significantDigits = scidbl_info.fPrecision; 836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* use 'f' notation */ 838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru scidbl_info.fSpec = 0x0066; 839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (significantDigits == -1) { 840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru significantDigits = 6; 841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 842ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_SIGNIFICANT_DIGITS_USED, TRUE); 843ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_MAX_SIGNIFICANT_DIGITS, significantDigits); 844ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* call the double handler */ 845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru retVal = u_printf_double_handler(handler, context, formatBundle, &scidbl_info, args); 846ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_MAX_SIGNIFICANT_DIGITS, maxSigDecimalDigits); 847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_SIGNIFICANT_DIGITS_USED, FALSE); 848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 849ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return retVal; 850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 851ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 852ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 853ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_count_handler(const u_printf_stream_handler *handler, 854ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 856ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 857ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ufmt_args *args) 858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 859ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t *count = (int32_t*)(args[0].ptrValue); 860ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* in the special case of count, the u_printf_spec_info's width */ 862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* will contain the # of chars written thus far */ 863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *count = info->fWidth; 864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 867ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_spellout_handler(const u_printf_stream_handler *handler, 870ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 872ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const u_printf_spec_info *info, 873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ufmt_args *args) 874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 875ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru double num = (double) (args[0].doubleValue); 876ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNumberFormat *format; 877ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar result[UPRINTF_BUFFER_SIZE]; 878ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar prefixBuffer[UPRINTF_BUFFER_SIZE]; 879ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t prefixBufferLen = sizeof(prefixBuffer); 880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t minDecimalDigits; 881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t maxDecimalDigits; 882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t resultLen; 883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 885ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru prefixBuffer[0] = 0; 886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 887ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* mask off any necessary bits */ 888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if(! info->fIsLongDouble) 889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru num &= DBL_MAX;*/ 890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* get the formatter */ 892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru format = u_locbund_getNumberFormat(formatBundle, UNUM_SPELLOUT); 893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* handle error */ 895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(format == 0) 896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* save the formatter's state */ 899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS); 900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS); 901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the appropriate flags and number of decimal digits on the formatter */ 903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(info->fPrecision != -1) { 904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the # of decimal digits */ 905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision); 906ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 907ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if(info->fAlt) { 908ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* '#' means always show decimal point */ 909ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy of printf behavior on Solaris - '#' shows 6 digits */ 910ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); 911ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 912ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 913ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* # of decimal digits is 6 if precision not specified */ 914ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); 915ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 916ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set whether to show the sign */ 918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fShowSign) { 919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_printf_set_sign(format, info, prefixBuffer, &prefixBufferLen, &status); 920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* format the number */ 923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru resultLen = unum_formatDouble(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); 924ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 926ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru resultLen = 0; 927ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 928ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* restore the number format */ 930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* TODO: Is this needed? */ 931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits); 932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits); 933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info->fShowSign) { 935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Reset back to original value regardless of what the error was */ 936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode localStatus = U_ZERO_ERROR; 937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_printf_reset_sign(format, info, prefixBuffer, &prefixBufferLen, &localStatus); 938ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 940ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return handler->pad_and_justify(context, info, result, resultLen); 941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 942ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Use US-ASCII characters only for formatting. Most codepages have 944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru characters 20-7F from Unicode. Using any other codepage specific 945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru characters will make it very difficult to format the string on 946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru non-Unicode machines */ 947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const u_printf_info g_u_printf_infos[UPRINTF_NUM_FMT_HANDLERS] = { 948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 0x20 */ 949ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 950ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_SIMPLE_PERCENT,UFMT_EMPTY, UFMT_EMPTY, 951ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 952ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 953ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 954ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 0x30 */ 955ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 956ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 957ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 958ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 959ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 960ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 0x40 */ 961ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_UCHAR, 962ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_SCIENTIFIC, UFMT_EMPTY, UFMT_SCIDBL, 963ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef U_USE_OBSOLETE_IO_FORMATTING 964ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_UCHAR/*deprecated*/, 965ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 966ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 967ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 968ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 969ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 970ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 0x50 */ 971ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_PERCENT, UFMT_EMPTY, UFMT_EMPTY, UFMT_USTRING, 972ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef U_USE_OBSOLETE_IO_FORMATTING 973ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_USTRING/*deprecated*/,UFMT_SPELLOUT, UFMT_EMPTY, 974ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 975ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_EMPTY, UFMT_SPELLOUT, UFMT_EMPTY, 976ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 977ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_HEX, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 978ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 979ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 980ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 0x60 */ 981ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_CHAR, 982ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_INT, UFMT_SCIENTIFIC, UFMT_DOUBLE, UFMT_SCIDBL, 983ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_INT, UFMT_EMPTY, UFMT_EMPTY, 984ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_EMPTY, UFMT_COUNT, UFMT_OCTAL, 985ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 986ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 0x70 */ 987ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_POINTER, UFMT_EMPTY, UFMT_EMPTY, UFMT_STRING, 988ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_UINT, UFMT_EMPTY, UFMT_EMPTY, 989ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_HEX, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 990ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 991ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 992ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 993ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* flag characters for uprintf */ 994ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define FLAG_MINUS 0x002D 995ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define FLAG_PLUS 0x002B 996ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define FLAG_SPACE 0x0020 997ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define FLAG_POUND 0x0023 998ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define FLAG_ZERO 0x0030 999ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define FLAG_PAREN 0x0028 1000ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1001ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define ISFLAG(s) (s) == FLAG_MINUS || \ 1002ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (s) == FLAG_PLUS || \ 1003ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (s) == FLAG_SPACE || \ 1004ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (s) == FLAG_POUND || \ 1005ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (s) == FLAG_ZERO || \ 1006ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (s) == FLAG_PAREN 1007ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1008ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* special characters for uprintf */ 1009ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define SPEC_ASTERISK 0x002A 1010ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define SPEC_DOLLARSIGN 0x0024 1011ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define SPEC_PERIOD 0x002E 1012ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define SPEC_PERCENT 0x0025 1013ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1014ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* unicode digits */ 1015ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_ZERO 0x0030 1016ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_ONE 0x0031 1017ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_TWO 0x0032 1018ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_THREE 0x0033 1019ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_FOUR 0x0034 1020ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_FIVE 0x0035 1021ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_SIX 0x0036 1022ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_SEVEN 0x0037 1023ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_EIGHT 0x0038 1024ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_NINE 0x0039 1025ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1026ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define ISDIGIT(s) (s) == DIGIT_ZERO || \ 1027ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (s) == DIGIT_ONE || \ 1028ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (s) == DIGIT_TWO || \ 1029ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (s) == DIGIT_THREE || \ 1030ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (s) == DIGIT_FOUR || \ 1031ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (s) == DIGIT_FIVE || \ 1032ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (s) == DIGIT_SIX || \ 1033ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (s) == DIGIT_SEVEN || \ 1034ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (s) == DIGIT_EIGHT || \ 1035ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (s) == DIGIT_NINE 1036ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1037ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* u_printf modifiers */ 1038ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MOD_H 0x0068 1039ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MOD_LOWERL 0x006C 1040ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MOD_L 0x004C 1041ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1042ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define ISMOD(s) (s) == MOD_H || \ 1043ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (s) == MOD_LOWERL || \ 1044ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (s) == MOD_L 104585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* Returns an array of the parsed argument type given in the format string. */ 104685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic ufmt_args* parseArguments(const UChar *alias, va_list ap, UErrorCode *status) { 104785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ufmt_args *arglist = NULL; 104885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ufmt_type_info *typelist = NULL; 104985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UBool *islonglong = NULL; 105085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho int32_t size = 0; 105185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho int32_t pos = 0; 105285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UChar type; 105385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho uint16_t handlerNum; 105485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const UChar *aliasStart = alias; 105585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 105685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* get maximum number of arguments */ 105785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho for(;;) { 105885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* find % */ 105985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho while(*alias != UP_PERCENT && *alias != 0x0000) { 106085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho alias++; 106185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 106285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 106385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(*alias == 0x0000) { 106485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 106585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 106685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 106785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho alias++; 106885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 106985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* handle the pos number */ 107085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(ISDIGIT(*alias)) { 107185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 107285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* handle positional parameters */ 107385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(ISDIGIT(*alias)) { 107485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pos = (int) (*alias++ - DIGIT_ZERO); 107585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 107685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho while(ISDIGIT(*alias)) { 107785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pos *= 10; 107885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pos += (int) (*alias++ - DIGIT_ZERO); 107985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 108085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 108185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 108285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* if there is no '$', don't read anything */ 108385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(*alias != SPEC_DOLLARSIGN) { 108485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return NULL; 108585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 108685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } else { 108785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return NULL; 108885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 108985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 109085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (pos > size) { 109185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho size = pos; 109285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 109385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 109485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 109585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* create the parsed argument list */ 109685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho typelist = (ufmt_type_info*)uprv_malloc(sizeof(ufmt_type_info) * size); 109785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho islonglong = (UBool*)uprv_malloc(sizeof(UBool) * size); 109885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho arglist = (ufmt_args*)uprv_malloc(sizeof(ufmt_args) * size); 109985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 110085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* If malloc failed, return NULL */ 110185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (!typelist || !islonglong || !arglist) { 110285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (typelist) { 110385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho uprv_free(typelist); 110485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 110585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 110685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (islonglong) { 110785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho uprv_free(islonglong); 110885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 110985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 111085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (arglist) { 111185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho uprv_free(arglist); 111285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 111385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 111485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *status = U_MEMORY_ALLOCATION_ERROR; 111585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return NULL; 111685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 111785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 111885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* reset alias back to the beginning */ 111985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho alias = aliasStart; 112085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 112185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho for(;;) { 112285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* find % */ 112385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho while(*alias != UP_PERCENT && *alias != 0x0000) { 112485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho alias++; 112585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 112685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 112785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(*alias == 0x0000) { 112885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 112985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 113085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 113185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho alias++; 113285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 113385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* handle positional parameters */ 113485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(ISDIGIT(*alias)) { 113585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pos = (int) (*alias++ - DIGIT_ZERO); 113685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 113785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho while(ISDIGIT(*alias)) { 113885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pos *= 10; 113985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pos += (int) (*alias++ - DIGIT_ZERO); 114085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 114185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 114285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* offset position by 1 */ 114385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pos--; 114485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 114585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* skip over everything except for the type */ 114685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho while (ISMOD(*alias) || ISFLAG(*alias) || ISDIGIT(*alias) || 114785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *alias == SPEC_ASTERISK || *alias == SPEC_PERIOD || *alias == SPEC_DOLLARSIGN) { 114885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho islonglong[pos] = FALSE; 114985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (ISMOD(*alias)) { 115085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho alias++; 115185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (*alias == MOD_LOWERL) { 115285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho islonglong[pos] = TRUE; 115385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 115485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 115585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho alias++; 115685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 115785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho type = *alias; 115885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 115985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* store the argument type in the correct position of the parsed argument list */ 116085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho handlerNum = (uint16_t)(type - UPRINTF_BASE_FMT_HANDLERS); 116185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (handlerNum < UPRINTF_NUM_FMT_HANDLERS) { 116285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho typelist[pos] = g_u_printf_infos[ handlerNum ].info; 116385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } else { 116485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho typelist[pos] = ufmt_empty; 116585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 116685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 116785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 116885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* store argument in arglist */ 116985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho for (pos = 0; pos < size; pos++) { 117085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho switch (typelist[pos]) { 117185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_string: 117285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_ustring: 117385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_pointer: 117485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho arglist[pos].ptrValue = va_arg(ap, void*); 117585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 117685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_char: 117785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_uchar: 117885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_int: 117985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (islonglong[pos]) { 118085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho arglist[pos].int64Value = va_arg(ap, int64_t); 118185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 118285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho else { 118385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho arglist[pos].int64Value = va_arg(ap, int32_t); 118485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 118585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 118685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_float: 118785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho arglist[pos].floatValue = (float) va_arg(ap, double); 118885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 118985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_double: 119085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho arglist[pos].doubleValue = va_arg(ap, double); 119185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 119285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho default: 119385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* else args is ignored */ 119485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho arglist[pos].ptrValue = NULL; 119585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 119685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 119785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 119885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 119985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho uprv_free(typelist); 120085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho uprv_free(islonglong); 120185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 120285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return arglist; 120385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 1204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* We parse the argument list in Unicode */ 1206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CFUNC int32_t 1207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_printf_parse(const u_printf_stream_handler *streamHandler, 1208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *fmt, 1209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *context, 1210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_localized_print_string *locStringContext, 1211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ULocaleBundle *formatBundle, 1212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t *written, 1213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru va_list ap) 1214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t handlerNum; 1216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ufmt_args args; 1217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ufmt_type_info argType; 1218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_printf_handler *handler; 1219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_printf_spec spec; 1220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_printf_spec_info *info = &(spec.fInfo); 1221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *alias = fmt; 1223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *backup; 1224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *lastAlias; 122585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const UChar *orgAlias = fmt; 122685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* parsed argument list */ 122785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ufmt_args *arglist = NULL; /* initialized it to avoid compiler warnings */ 122885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UErrorCode status = U_ZERO_ERROR; 122985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (!locStringContext || locStringContext->available >= 0) { 123085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* get the parsed list of argument types */ 123185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho arglist = parseArguments(orgAlias, ap, &status); 123285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 123385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* Return error if parsing failed. */ 123485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (U_FAILURE(status)) { 123585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return -1; 123685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 123785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 123885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 1239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* iterate through the pattern */ 124085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho while(!locStringContext || locStringContext->available >= 0) { 1241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* find the next '%' */ 1243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lastAlias = alias; 1244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(*alias != UP_PERCENT && *alias != 0x0000) { 1245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alias++; 1246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* write any characters before the '%' */ 1249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(alias > lastAlias) { 1250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *written += (streamHandler->write)(context, lastAlias, (int32_t)(alias - lastAlias)); 1251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* break if at end of string */ 1254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*alias == 0x0000) { 1255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* initialize spec to default values */ 1259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru spec.fWidthPos = -1; 1260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru spec.fPrecisionPos = -1; 1261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru spec.fArgPos = -1; 1262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(info, 0, sizeof(*info)); 1264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fPrecision = -1; 1265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fWidth = -1; 1266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fPadChar = 0x0020; 1267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* skip over the initial '%' */ 1269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alias++; 1270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Check for positional argument */ 1272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ISDIGIT(*alias)) { 1273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Save the current position */ 1275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru backup = alias; 1276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* handle positional parameters */ 1278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ISDIGIT(*alias)) { 1279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru spec.fArgPos = (int) (*alias++ - DIGIT_ZERO); 1280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(ISDIGIT(*alias)) { 1282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru spec.fArgPos *= 10; 1283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru spec.fArgPos += (int) (*alias++ - DIGIT_ZERO); 1284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if there is no '$', don't read anything */ 1288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*alias != SPEC_DOLLARSIGN) { 1289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru spec.fArgPos = -1; 1290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alias = backup; 1291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* munge the '$' */ 1293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else 1294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alias++; 1295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Get any format flags */ 1298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(ISFLAG(*alias)) { 1299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch(*alias++) { 1300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* left justify */ 1302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case FLAG_MINUS: 1303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fLeft = TRUE; 1304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* always show sign */ 1307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case FLAG_PLUS: 1308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fShowSign = TRUE; 1309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* use space if no sign present */ 1312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case FLAG_SPACE: 1313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fShowSign = TRUE; 1314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fSpace = TRUE; 1315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* use alternate form */ 1318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case FLAG_POUND: 1319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fAlt = TRUE; 1320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* pad with leading zeroes */ 1323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case FLAG_ZERO: 1324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fZero = TRUE; 1325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fPadChar = 0x0030; 1326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* pad character specified */ 1329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case FLAG_PAREN: 1330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* TODO test that all four are numbers */ 1332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* first four characters are hex values for pad char */ 1333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fPadChar = (UChar)ufmt_digitvalue(*alias++); 1334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*alias++)); 1335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*alias++)); 1336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*alias++)); 1337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* final character is ignored */ 1339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alias++; 1340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Get the width */ 1346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* width is specified out of line */ 1348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*alias == SPEC_ASTERISK) { 1349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fWidth = -2; 1351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Skip the '*' */ 1353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alias++; 1354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Save the current position */ 1356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru backup = alias; 1357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* handle positional parameters */ 1359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ISDIGIT(*alias)) { 1360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru spec.fWidthPos = (int) (*alias++ - DIGIT_ZERO); 1361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(ISDIGIT(*alias)) { 1363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru spec.fWidthPos *= 10; 1364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru spec.fWidthPos += (int) (*alias++ - DIGIT_ZERO); 1365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if there is no '$', don't read anything */ 1369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*alias != SPEC_DOLLARSIGN) { 1370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru spec.fWidthPos = -1; 1371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alias = backup; 1372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* munge the '$' */ 1374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else 1375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alias++; 1376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* read the width, if present */ 1378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if(ISDIGIT(*alias)){ 1379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fWidth = (int) (*alias++ - DIGIT_ZERO); 1380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(ISDIGIT(*alias)) { 1382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fWidth *= 10; 1383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fWidth += (int) (*alias++ - DIGIT_ZERO); 1384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Get the precision */ 1388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*alias == SPEC_PERIOD) { 1390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* eat up the '.' */ 1392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alias++; 1393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* precision is specified out of line */ 1395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*alias == SPEC_ASTERISK) { 1396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fPrecision = -2; 1398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Skip the '*' */ 1400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alias++; 1401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* save the current position */ 1403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru backup = alias; 1404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* handle positional parameters */ 1406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ISDIGIT(*alias)) { 1407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru spec.fPrecisionPos = (int) (*alias++ - DIGIT_ZERO); 1408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(ISDIGIT(*alias)) { 1410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru spec.fPrecisionPos *= 10; 1411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru spec.fPrecisionPos += (int) (*alias++ - DIGIT_ZERO); 1412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if there is no '$', don't read anything */ 1415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*alias != SPEC_DOLLARSIGN) { 1416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru spec.fPrecisionPos = -1; 1417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alias = backup; 1418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 1420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* munge the '$' */ 1421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alias++; 1422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* read the precision */ 1426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if(ISDIGIT(*alias)){ 1427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fPrecision = (int) (*alias++ - DIGIT_ZERO); 1428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(ISDIGIT(*alias)) { 1430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fPrecision *= 10; 1431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fPrecision += (int) (*alias++ - DIGIT_ZERO); 1432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Get any modifiers */ 1437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ISMOD(*alias)) { 1438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch(*alias++) { 1439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* short */ 1441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MOD_H: 1442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fIsShort = TRUE; 1443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* long or long long */ 1446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MOD_LOWERL: 1447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*alias == MOD_LOWERL) { 1448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fIsLongLong = TRUE; 1449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* skip over the next 'l' */ 1450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alias++; 1451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else 1453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fIsLong = TRUE; 1454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* long double */ 1457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case MOD_L: 1458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fIsLongDouble = TRUE; 1459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* finally, get the specifier letter */ 1464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fSpec = *alias++; 1465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fOrigSpec = info->fSpec; 1466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* fill in the precision and width, if specified out of line */ 1468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* width specified out of line */ 1470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(spec.fInfo.fWidth == -2) { 1471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(spec.fWidthPos == -1) { 1472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* read the width from the argument list */ 1473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fWidth = va_arg(ap, int32_t); 1474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else handle positional parameter */ 1476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if it's negative, take the absolute value and set left alignment */ 1478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(info->fWidth < 0) { 1479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fWidth *= -1; /* Make positive */ 1480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fLeft = TRUE; 1481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* precision specified out of line */ 1485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(info->fPrecision == -2) { 1486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(spec.fPrecisionPos == -1) { 1487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* read the precision from the argument list */ 1488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fPrecision = va_arg(ap, int32_t); 1489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else handle positional parameter */ 1491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* if it's negative, set it to zero */ 1493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(info->fPrecision < 0) 1494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info->fPrecision = 0; 1495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru handlerNum = (uint16_t)(info->fSpec - UPRINTF_BASE_FMT_HANDLERS); 1498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (handlerNum < UPRINTF_NUM_FMT_HANDLERS) { 1499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* query the info function for argument information */ 1500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru argType = g_u_printf_infos[ handlerNum ].info; 150185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 150285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* goto the correct argument on arg_list if position is specified */ 150385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (spec.fArgPos > 0) { 150485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* offset position by 1 */ 150585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho spec.fArgPos--; 150685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho switch(argType) { 150785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_count: 150885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* set the spec's width to the # of chars written */ 150985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho info->fWidth = *written; 151085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* fall through to set the pointer */ 151185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_string: 151285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_ustring: 151385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_pointer: 151485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho args.ptrValue = arglist[spec.fArgPos].ptrValue; 151585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 151685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_char: 151785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_uchar: 151885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_int: 151985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho args.int64Value = arglist[spec.fArgPos].int64Value; 152085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 152185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_float: 152285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho args.floatValue = arglist[spec.fArgPos].floatValue; 152385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 152485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_double: 152585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho args.doubleValue = arglist[spec.fArgPos].doubleValue; 152685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 152785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho default: 152885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* else args is ignored */ 152985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho args.ptrValue = NULL; 153085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 1531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 153285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } else { /* no positional argument specified */ 153385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho switch(argType) { 153485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_count: 153585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* set the spec's width to the # of chars written */ 153685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho info->fWidth = *written; 153785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* fall through to set the pointer */ 153885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_string: 153985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_ustring: 154085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_pointer: 154185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho args.ptrValue = va_arg(ap, void*); 154285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 154385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_char: 154485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_uchar: 154585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_int: 154685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (info->fIsLongLong) { 154785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho args.int64Value = va_arg(ap, int64_t); 154885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 154985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho else { 155085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho args.int64Value = va_arg(ap, int32_t); 155185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 155285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 155385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_float: 155485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho args.floatValue = (float) va_arg(ap, double); 155585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 155685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case ufmt_double: 155785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho args.doubleValue = va_arg(ap, double); 155885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 155985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho default: 156085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* else args is ignored */ 156185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho args.ptrValue = NULL; 156285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 1563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* call the handler function */ 1567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru handler = g_u_printf_infos[ handlerNum ].handler; 1568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(handler != 0) { 1569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *written += (*handler)(streamHandler, context, formatBundle, info, &args); 1570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 1572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* just echo unknown tags */ 1573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *written += (streamHandler->write)(context, fmt, (int32_t)(alias - lastAlias)); 1574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 1577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* just echo unknown tags */ 1578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *written += (streamHandler->write)(context, fmt, (int32_t)(alias - lastAlias)); 1579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 158185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* delete parsed argument list */ 158285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (arglist != NULL) { 158385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho uprv_free(arglist); 158485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 1585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* return # of characters in this format that have been parsed. */ 1586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (int32_t)(alias - fmt); 1587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_FORMATTING */ 1590