1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)****************************************************************************** 3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Copyright (C) 1998-2008, International Business Machines 5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Corporation and others. All Rights Reserved. 6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)****************************************************************************** 8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* File uprntf_p.c 10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Modification History: 12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Date Name Description 14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 11/23/98 stephen Creation. 15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 03/12/99 stephen Modified for new C API. 16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 08/07/2003 george Reunify printf implementations 17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)****************************************************************************** 18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h" 21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_FORMATTING 23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ustring.h" 25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uprintf.h" 27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ufmt_cmn.h" 28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmemory.h" 29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "putilimp.h" 30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* ANSI style formatting */ 32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Use US-ASCII characters only for formatting */ 33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* % */ 35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UFMT_SIMPLE_PERCENT {ufmt_simple_percent, u_printf_simple_percent_handler} 36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* s */ 37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UFMT_STRING {ufmt_string, u_printf_string_handler} 38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* c */ 39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UFMT_CHAR {ufmt_char, u_printf_char_handler} 40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* d, i */ 41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UFMT_INT {ufmt_int, u_printf_integer_handler} 42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* u */ 43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UFMT_UINT {ufmt_int, u_printf_uinteger_handler} 44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* o */ 45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UFMT_OCTAL {ufmt_int, u_printf_octal_handler} 46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* x, X */ 47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UFMT_HEX {ufmt_int, u_printf_hex_handler} 48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* f */ 49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UFMT_DOUBLE {ufmt_double, u_printf_double_handler} 50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* e, E */ 51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UFMT_SCIENTIFIC {ufmt_double, u_printf_scientific_handler} 52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* g, G */ 53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UFMT_SCIDBL {ufmt_double, u_printf_scidbl_handler} 54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* n */ 55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UFMT_COUNT {ufmt_count, u_printf_count_handler} 56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* non-ANSI extensions */ 58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Use US-ASCII characters only for formatting */ 59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* p */ 61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UFMT_POINTER {ufmt_pointer, u_printf_pointer_handler} 62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* V */ 63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UFMT_SPELLOUT {ufmt_double, u_printf_spellout_handler} 64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* P */ 65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UFMT_PERCENT {ufmt_double, u_printf_percent_handler} 66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* C K is old format */ 67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UFMT_UCHAR {ufmt_uchar, u_printf_uchar_handler} 68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* S U is old format */ 69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UFMT_USTRING {ufmt_ustring, u_printf_ustring_handler} 70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UFMT_EMPTY {ufmt_empty, NULL} 73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * A u_printf handler function. 76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * A u_printf handler is responsible for handling a single u_printf 77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * format specification, for example 'd' or 's'. 78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param stream The UFILE to which to write output. 79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param info A pointer to a <TT>u_printf_spec_info</TT> struct containing 80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * information on the format specification. 81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param args A pointer to the argument data 82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @return The number of Unicode characters written to <TT>stream</TT>. 83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)typedef int32_t U_EXPORT2 85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_handler(const u_printf_stream_handler *handler, 86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ufmt_args *args); 91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)typedef struct u_printf_info { 93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ufmt_type_info info; 94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_printf_handler *handler; 95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} u_printf_info; 96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Struct encapsulating a single uprintf format specification. 99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)typedef struct u_printf_spec { 101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_printf_spec_info fInfo; /* Information on this spec */ 102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t fWidthPos; /* Position of width in arg list */ 103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t fPrecisionPos; /* Position of precision in arg list */ 104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t fArgPos; /* Position of data in arg list */ 105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} u_printf_spec; 106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UPRINTF_NUM_FMT_HANDLERS 108 108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* We do not use handlers for 0-0x1f */ 110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UPRINTF_BASE_FMT_HANDLERS 0x20 111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* buffer size for formatting */ 113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UPRINTF_BUFFER_SIZE 1024 114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UPRINTF_SYMBOL_BUFFER_SIZE 8 115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gNullStr[] = {0x28, 0x6E, 0x75, 0x6C, 0x6C, 0x29, 0}; /* "(null)" */ 117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gSpaceStr[] = {0x20, 0}; /* " " */ 118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Sets the sign of a format based on u_printf_spec_info */ 120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* TODO: Is setting the prefix symbol to a positive sign a good idea in all locales? */ 121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void 122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_set_sign(UNumberFormat *format, 123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *prefixBuffer, 125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t *prefixBufLen, 126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *status) 127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(info->fShowSign) { 129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *prefixBufLen = unum_getTextAttribute(format, 130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UNUM_POSITIVE_PREFIX, 131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prefixBuffer, 132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *prefixBufLen, 133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status); 134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fSpace) { 135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Setting UNUM_PLUS_SIGN_SYMBOL affects the exponent too. */ 136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* unum_setSymbol(format, UNUM_PLUS_SIGN_SYMBOL, gSpaceStr, 1, &status); */ 137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setTextAttribute(format, UNUM_POSITIVE_PREFIX, gSpaceStr, 1, status); 138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar plusSymbol[UPRINTF_SYMBOL_BUFFER_SIZE]; 141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t symbolLen; 142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) symbolLen = unum_getSymbol(format, 144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UNUM_PLUS_SIGN_SYMBOL, 145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) plusSymbol, 146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sizeof(plusSymbol)/sizeof(*plusSymbol), 147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status); 148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setTextAttribute(format, 149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UNUM_POSITIVE_PREFIX, 150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) plusSymbol, 151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) symbolLen, 152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status); 153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *prefixBufLen = 0; 157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void 161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_reset_sign(UNumberFormat *format, 162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *prefixBuffer, 164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t *prefixBufLen, 165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *status) 166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(info->fShowSign) { 168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setTextAttribute(format, 169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UNUM_POSITIVE_PREFIX, 170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prefixBuffer, 171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *prefixBufLen, 172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status); 173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* handle a '%' */ 178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_simple_percent_handler(const u_printf_stream_handler *handler, 180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ufmt_args *args) 184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) static const UChar PERCENT[] = { UP_PERCENT }; 186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* put a single '%' onto the output */ 188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return handler->write(context, PERCENT, 1); 189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* handle 's' */ 192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_string_handler(const u_printf_stream_handler *handler, 194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ufmt_args *args) 198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *s; 200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar buffer[UFMT_DEFAULT_BUFFER_SIZE]; 201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t len, written; 202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t argSize; 203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *arg = (const char*)(args[0].ptrValue); 204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* convert from the default codepage to Unicode */ 206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (arg) { 207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) argSize = (int32_t)strlen(arg) + 1; 208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (argSize >= MAX_UCHAR_BUFFER_SIZE(buffer)) { 209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s = ufmt_defaultCPToUnicode(arg, argSize, 210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (UChar *)uprv_malloc(MAX_UCHAR_BUFFER_NEEDED(argSize)), 211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) MAX_UCHAR_BUFFER_NEEDED(argSize)); 212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(s == NULL) { 213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s = ufmt_defaultCPToUnicode(arg, argSize, buffer, 218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sizeof(buffer)/sizeof(UChar)); 219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s = (UChar *)gNullStr; 223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) len = u_strlen(s); 225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* width = minimum # of characters to write */ 227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* precision = maximum # of characters to write */ 228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fPrecision != -1 && info->fPrecision < len) { 229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) len = info->fPrecision; 230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) written = handler->pad_and_justify(context, info, s, len); 233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* clean up */ 235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (gNullStr != s && buffer != s) { 236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(s); 237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return written; 240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_char_handler(const u_printf_stream_handler *handler, 244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ufmt_args *args) 248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar s[UTF_MAX_CHAR_LENGTH+1]; 250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t len = 1, written; 251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unsigned char arg = (unsigned char)(args[0].int64Value); 252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* convert from default codepage to Unicode */ 254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ufmt_defaultCPToUnicode((const char *)&arg, 2, s, sizeof(s)/sizeof(UChar)); 255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Remember that this may be an MBCS character */ 257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (arg != 0) { 258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) len = u_strlen(s); 259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* width = minimum # of characters to write */ 262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* precision = maximum # of characters to write */ 263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* precision is ignored when handling a char */ 264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) written = handler->pad_and_justify(context, info, s, len); 266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return written; 268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_double_handler(const u_printf_stream_handler *handler, 272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ufmt_args *args) 276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) double num = (double) (args[0].doubleValue); 278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UNumberFormat *format; 279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar result[UPRINTF_BUFFER_SIZE]; 280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar prefixBuffer[UPRINTF_BUFFER_SIZE]; 281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t prefixBufferLen = sizeof(prefixBuffer); 282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t minDecimalDigits; 283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t maxDecimalDigits; 284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t resultLen; 285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prefixBuffer[0] = 0; 288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* mask off any necessary bits */ 290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* if(! info->fIsLongDouble) 291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) num &= DBL_MAX;*/ 292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* get the formatter */ 294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL); 295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* handle error */ 297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(format == 0) 298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* save the formatter's state */ 301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS); 302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS); 303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set the appropriate flags and number of decimal digits on the formatter */ 305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(info->fPrecision != -1) { 306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set the # of decimal digits */ 307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision); 308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else if(info->fAlt) { 310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* '#' means always show decimal point */ 311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* copy of printf behavior on Solaris - '#' shows 6 digits */ 312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); 313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* # of decimal digits is 6 if precision not specified regardless of locale */ 316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); 317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set whether to show the sign */ 320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fShowSign) { 321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_printf_set_sign(format, info, prefixBuffer, &prefixBufferLen, &status); 322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* format the number */ 325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLen = unum_formatDouble(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); 326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLen = 0; 329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* restore the number format */ 332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* TODO: Is this needed? */ 333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits); 334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits); 335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fShowSign) { 337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Reset back to original value regardless of what the error was */ 338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode localStatus = U_ZERO_ERROR; 339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_printf_reset_sign(format, info, prefixBuffer, &prefixBufferLen, &localStatus); 340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return handler->pad_and_justify(context, info, result, resultLen); 343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* HSYS */ 346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_integer_handler(const u_printf_stream_handler *handler, 348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ufmt_args *args) 352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int64_t num = args[0].int64Value; 354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UNumberFormat *format; 355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar result[UPRINTF_BUFFER_SIZE]; 356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar prefixBuffer[UPRINTF_BUFFER_SIZE]; 357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t prefixBufferLen = sizeof(prefixBuffer); 358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t minDigits = -1; 359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t resultLen; 360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prefixBuffer[0] = 0; 363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* mask off any necessary bits */ 365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fIsShort) 366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) num = (int16_t)num; 367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else if (!info->fIsLongLong) 368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) num = (int32_t)num; 369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* get the formatter */ 371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL); 372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* handle error */ 374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(format == 0) 375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set the appropriate flags on the formatter */ 378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set the minimum integer digits */ 380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(info->fPrecision != -1) { 381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set the minimum # of digits */ 382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) minDigits = unum_getAttribute(format, UNUM_MIN_INTEGER_DIGITS); 383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, info->fPrecision); 384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set whether to show the sign */ 387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(info->fShowSign) { 388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_printf_set_sign(format, info, prefixBuffer, &prefixBufferLen, &status); 389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* format the number */ 392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLen = unum_formatInt64(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); 393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLen = 0; 396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* restore the number format */ 399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (minDigits != -1) { 400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, minDigits); 401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fShowSign) { 404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Reset back to original value regardless of what the error was */ 405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode localStatus = U_ZERO_ERROR; 406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_printf_reset_sign(format, info, prefixBuffer, &prefixBufferLen, &localStatus); 407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return handler->pad_and_justify(context, info, result, resultLen); 410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_hex_handler(const u_printf_stream_handler *handler, 414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ufmt_args *args) 418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int64_t num = args[0].int64Value; 420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar result[UPRINTF_BUFFER_SIZE]; 421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t len = UPRINTF_BUFFER_SIZE; 422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* mask off any necessary bits */ 425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fIsShort) 426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) num &= UINT16_MAX; 427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else if (!info->fIsLongLong) 428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) num &= UINT32_MAX; 429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* format the number, preserving the minimum # of digits */ 431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ufmt_64tou(result, &len, num, 16, 432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (UBool)(info->fSpec == 0x0078), 433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (info->fPrecision == -1 && info->fZero) ? info->fWidth : info->fPrecision); 434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* convert to alt form, if desired */ 436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(num != 0 && info->fAlt && len < UPRINTF_BUFFER_SIZE - 2) { 437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* shift the formatted string right by 2 chars */ 438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) memmove(result + 2, result, len * sizeof(UChar)); 439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result[0] = 0x0030; 440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result[1] = info->fSpec; 441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) len += 2; 442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return handler->pad_and_justify(context, info, result, len); 445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_octal_handler(const u_printf_stream_handler *handler, 449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ufmt_args *args) 453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int64_t num = args[0].int64Value; 455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar result[UPRINTF_BUFFER_SIZE]; 456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t len = UPRINTF_BUFFER_SIZE; 457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* mask off any necessary bits */ 460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fIsShort) 461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) num &= UINT16_MAX; 462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else if (!info->fIsLongLong) 463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) num &= UINT32_MAX; 464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* format the number, preserving the minimum # of digits */ 466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ufmt_64tou(result, &len, num, 8, 467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) FALSE, /* doesn't matter for octal */ 468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fPrecision == -1 && info->fZero ? info->fWidth : info->fPrecision); 469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* convert to alt form, if desired */ 471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(info->fAlt && result[0] != 0x0030 && len < UPRINTF_BUFFER_SIZE - 1) { 472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* shift the formatted string right by 1 char */ 473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) memmove(result + 1, result, len * sizeof(UChar)); 474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result[0] = 0x0030; 475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) len += 1; 476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return handler->pad_and_justify(context, info, result, len); 479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_uinteger_handler(const u_printf_stream_handler *handler, 483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ufmt_args *args) 487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int64_t num = args[0].int64Value; 489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UNumberFormat *format; 490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar result[UPRINTF_BUFFER_SIZE]; 491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t minDigits = -1; 492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t resultLen; 493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* TODO: Fix this once uint64_t can be formatted. */ 496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fIsShort) 497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) num &= UINT16_MAX; 498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else if (!info->fIsLongLong) 499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) num &= UINT32_MAX; 500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* get the formatter */ 502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL); 503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* handle error */ 505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(format == 0) 506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set the appropriate flags on the formatter */ 509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set the minimum integer digits */ 511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(info->fPrecision != -1) { 512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set the minimum # of digits */ 513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) minDigits = unum_getAttribute(format, UNUM_MIN_INTEGER_DIGITS); 514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, info->fPrecision); 515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* To mirror other stdio implementations, we ignore the sign argument */ 518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* format the number */ 520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLen = unum_formatInt64(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); 521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLen = 0; 524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* restore the number format */ 527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (minDigits != -1) { 528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, minDigits); 529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return handler->pad_and_justify(context, info, result, resultLen); 532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_pointer_handler(const u_printf_stream_handler *handler, 536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ufmt_args *args) 540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar result[UPRINTF_BUFFER_SIZE]; 542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t len = UPRINTF_BUFFER_SIZE; 543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* format the pointer in hex */ 545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ufmt_ptou(result, &len, args[0].ptrValue, TRUE/*, info->fPrecision*/); 546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return handler->pad_and_justify(context, info, result, len); 548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_scientific_handler(const u_printf_stream_handler *handler, 552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ufmt_args *args) 556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) double num = (double) (args[0].doubleValue); 558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UNumberFormat *format; 559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar result[UPRINTF_BUFFER_SIZE]; 560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar prefixBuffer[UPRINTF_BUFFER_SIZE]; 561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t prefixBufferLen = sizeof(prefixBuffer); 562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t minDecimalDigits; 563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t maxDecimalDigits; 564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar srcExpBuf[UPRINTF_SYMBOL_BUFFER_SIZE]; 566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t srcLen, expLen; 567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t resultLen; 568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar expBuf[UPRINTF_SYMBOL_BUFFER_SIZE]; 569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prefixBuffer[0] = 0; 571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* mask off any necessary bits */ 573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* if(! info->fIsLongDouble) 574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) num &= DBL_MAX;*/ 575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* get the formatter */ 577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) format = u_locbund_getNumberFormat(formatBundle, UNUM_SCIENTIFIC); 578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* handle error */ 580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(format == 0) 581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set the appropriate flags on the formatter */ 584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcLen = unum_getSymbol(format, 586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UNUM_EXPONENTIAL_SYMBOL, 587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcExpBuf, 588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sizeof(srcExpBuf), 589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &status); 590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Upper/lower case the e */ 592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fSpec == (UChar)0x65 /* e */) { 593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) expLen = u_strToLower(expBuf, (int32_t)sizeof(expBuf), 594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcExpBuf, srcLen, 595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) formatBundle->fLocale, 596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &status); 597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) expLen = u_strToUpper(expBuf, (int32_t)sizeof(expBuf), 600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcExpBuf, srcLen, 601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) formatBundle->fLocale, 602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &status); 603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setSymbol(format, 606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UNUM_EXPONENTIAL_SYMBOL, 607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) expBuf, 608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) expLen, 609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &status); 610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* save the formatter's state */ 612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS); 613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS); 614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set the appropriate flags and number of decimal digits on the formatter */ 616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(info->fPrecision != -1) { 617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set the # of decimal digits */ 618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fOrigSpec == (UChar)0x65 /* e */ || info->fOrigSpec == (UChar)0x45 /* E */) { 619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision); 620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, 1); 623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, info->fPrecision); 624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else if(info->fAlt) { 627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* '#' means always show decimal point */ 628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* copy of printf behavior on Solaris - '#' shows 6 digits */ 629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); 630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* # of decimal digits is 6 if precision not specified */ 633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); 634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set whether to show the sign */ 637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fShowSign) { 638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_printf_set_sign(format, info, prefixBuffer, &prefixBufferLen, &status); 639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* format the number */ 642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLen = unum_formatDouble(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); 643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 645f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLen = 0; 646f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 647f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 648f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* restore the number format */ 649f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* TODO: Is this needed? */ 650f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits); 651f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits); 652f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 653f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Since we're the only one using the scientific 654f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) format, we don't need to save the old exponent value. */ 655f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /*unum_setSymbol(format, 656f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UNUM_EXPONENTIAL_SYMBOL, 657f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcExpBuf, 658f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcLen, 659f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &status);*/ 660f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 661f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fShowSign) { 662f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Reset back to original value regardless of what the error was */ 663f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode localStatus = U_ZERO_ERROR; 664f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_printf_reset_sign(format, info, prefixBuffer, &prefixBufferLen, &localStatus); 665f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 666f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 667f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return handler->pad_and_justify(context, info, result, resultLen); 668f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 669f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 670f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 671f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_percent_handler(const u_printf_stream_handler *handler, 672f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 673f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 674f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 675f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ufmt_args *args) 676f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 677f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) double num = (double) (args[0].doubleValue); 678f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UNumberFormat *format; 679f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar result[UPRINTF_BUFFER_SIZE]; 680f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar prefixBuffer[UPRINTF_BUFFER_SIZE]; 681f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t prefixBufferLen = sizeof(prefixBuffer); 682f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t minDecimalDigits; 683f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t maxDecimalDigits; 684f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t resultLen; 685f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 686f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 687f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prefixBuffer[0] = 0; 688f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 689f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* mask off any necessary bits */ 690f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* if(! info->fIsLongDouble) 691f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) num &= DBL_MAX;*/ 692f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 693f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* get the formatter */ 694f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) format = u_locbund_getNumberFormat(formatBundle, UNUM_PERCENT); 695f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 696f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* handle error */ 697f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(format == 0) 698f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 699f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 700f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* save the formatter's state */ 701f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS); 702f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS); 703f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 704f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set the appropriate flags and number of decimal digits on the formatter */ 705f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(info->fPrecision != -1) { 706f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set the # of decimal digits */ 707f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision); 708f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 709f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else if(info->fAlt) { 710f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* '#' means always show decimal point */ 711f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* copy of printf behavior on Solaris - '#' shows 6 digits */ 712f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); 713f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 714f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 715f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* # of decimal digits is 6 if precision not specified */ 716f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); 717f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 718f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 719f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set whether to show the sign */ 720f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fShowSign) { 721f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_printf_set_sign(format, info, prefixBuffer, &prefixBufferLen, &status); 722f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 723f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 724f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* format the number */ 725f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLen = unum_formatDouble(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); 726f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 727f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 728f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLen = 0; 729f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 730f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 731f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* restore the number format */ 732f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* TODO: Is this needed? */ 733f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits); 734f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits); 735f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 736f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fShowSign) { 737f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Reset back to original value regardless of what the error was */ 738f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode localStatus = U_ZERO_ERROR; 739f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_printf_reset_sign(format, info, prefixBuffer, &prefixBufferLen, &localStatus); 740f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 741f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 742f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return handler->pad_and_justify(context, info, result, resultLen); 743f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 744f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 745f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 746f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_ustring_handler(const u_printf_stream_handler *handler, 747f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 748f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 749f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 750f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ufmt_args *args) 751f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 752f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t len, written; 753f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *arg = (const UChar*)(args[0].ptrValue); 754f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 755f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* allocate enough space for the buffer */ 756f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (arg == NULL) { 757f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) arg = gNullStr; 758f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 759f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) len = u_strlen(arg); 760f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 761f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* width = minimum # of characters to write */ 762f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* precision = maximum # of characters to write */ 763f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fPrecision != -1 && info->fPrecision < len) { 764f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) len = info->fPrecision; 765f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 766f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 767f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* determine if the string should be padded */ 768f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) written = handler->pad_and_justify(context, info, arg, len); 769f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 770f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return written; 771f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 772f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 773f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 774f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_uchar_handler(const u_printf_stream_handler *handler, 775f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 776f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 777f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 778f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ufmt_args *args) 779f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 780f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t written = 0; 781f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar arg = (UChar)(args[0].int64Value); 782f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 783f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* width = minimum # of characters to write */ 784f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* precision = maximum # of characters to write */ 785f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* precision is ignored when handling a uchar */ 786f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 787f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* determine if the string should be padded */ 788f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) written = handler->pad_and_justify(context, info, &arg, 1); 789f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 790f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return written; 791f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 792f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 793f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 794f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_scidbl_handler(const u_printf_stream_handler *handler, 795f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 796f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 797f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 798f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ufmt_args *args) 799f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 800f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_printf_spec_info scidbl_info; 801f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) double num = args[0].doubleValue; 802f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t retVal; 803f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UNumberFormat *format; 804f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t maxSigDecimalDigits, significantDigits; 805f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 806f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) memcpy(&scidbl_info, info, sizeof(u_printf_spec_info)); 807f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 808f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* determine whether to use 'd', 'e' or 'f' notation */ 809f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (scidbl_info.fPrecision == -1 && num == uprv_trunc(num)) 810f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 811f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* use 'f' notation */ 812f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) scidbl_info.fSpec = 0x0066; 813f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) scidbl_info.fPrecision = 0; 814f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* call the double handler */ 815f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) retVal = u_printf_double_handler(handler, context, formatBundle, &scidbl_info, args); 816f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 817f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else if(num < 0.0001 || (scidbl_info.fPrecision < 1 && 1000000.0 <= num) 818f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) || (scidbl_info.fPrecision != -1 && num > uprv_pow10(scidbl_info.fPrecision))) 819f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 820f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* use 'e' or 'E' notation */ 821f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) scidbl_info.fSpec = scidbl_info.fSpec - 2; 822f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (scidbl_info.fPrecision == -1) { 823f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) scidbl_info.fPrecision = 5; 824f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 825f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* call the scientific handler */ 826f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) retVal = u_printf_scientific_handler(handler, context, formatBundle, &scidbl_info, args); 827f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 828f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 829f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL); 830f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Check for null pointer */ 831f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (format == NULL) { 832f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 833f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 834f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) maxSigDecimalDigits = unum_getAttribute(format, UNUM_MAX_SIGNIFICANT_DIGITS); 835f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) significantDigits = scidbl_info.fPrecision; 836f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 837f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* use 'f' notation */ 838f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) scidbl_info.fSpec = 0x0066; 839f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (significantDigits == -1) { 840f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) significantDigits = 6; 841f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 842f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_SIGNIFICANT_DIGITS_USED, TRUE); 843f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_MAX_SIGNIFICANT_DIGITS, significantDigits); 844f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* call the double handler */ 845f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) retVal = u_printf_double_handler(handler, context, formatBundle, &scidbl_info, args); 846f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_MAX_SIGNIFICANT_DIGITS, maxSigDecimalDigits); 847f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_SIGNIFICANT_DIGITS_USED, FALSE); 848f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 849f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return retVal; 850f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 851f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 852f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 853f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_count_handler(const u_printf_stream_handler *handler, 854f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 855f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 856f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 857f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ufmt_args *args) 858f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 859f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t *count = (int32_t*)(args[0].ptrValue); 860f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 861f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* in the special case of count, the u_printf_spec_info's width */ 862f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* will contain the # of chars written thus far */ 863f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *count = info->fWidth; 864f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 865f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 866f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 867f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 868f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 869f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_spellout_handler(const u_printf_stream_handler *handler, 870f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 871f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 872f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const u_printf_spec_info *info, 873f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ufmt_args *args) 874f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 875f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) double num = (double) (args[0].doubleValue); 876f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UNumberFormat *format; 877f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar result[UPRINTF_BUFFER_SIZE]; 878f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar prefixBuffer[UPRINTF_BUFFER_SIZE]; 879f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t prefixBufferLen = sizeof(prefixBuffer); 880f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t minDecimalDigits; 881f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t maxDecimalDigits; 882f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t resultLen; 883f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 884f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 885f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) prefixBuffer[0] = 0; 886f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 887f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* mask off any necessary bits */ 888f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* if(! info->fIsLongDouble) 889f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) num &= DBL_MAX;*/ 890f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 891f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* get the formatter */ 892f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) format = u_locbund_getNumberFormat(formatBundle, UNUM_SPELLOUT); 893f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 894f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* handle error */ 895f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(format == 0) 896f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 897f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 898f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* save the formatter's state */ 899f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS); 900f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS); 901f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 902f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set the appropriate flags and number of decimal digits on the formatter */ 903f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(info->fPrecision != -1) { 904f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set the # of decimal digits */ 905f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision); 906f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 907f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else if(info->fAlt) { 908f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* '#' means always show decimal point */ 909f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* copy of printf behavior on Solaris - '#' shows 6 digits */ 910f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); 911f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 912f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 913f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* # of decimal digits is 6 if precision not specified */ 914f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6); 915f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 916f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 917f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set whether to show the sign */ 918f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fShowSign) { 919f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_printf_set_sign(format, info, prefixBuffer, &prefixBufferLen, &status); 920f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 921f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 922f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* format the number */ 923f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLen = unum_formatDouble(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); 924f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 925f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 926f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resultLen = 0; 927f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 928f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 929f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* restore the number format */ 930f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* TODO: Is this needed? */ 931f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits); 932f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits); 933f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 934f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fShowSign) { 935f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Reset back to original value regardless of what the error was */ 936f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode localStatus = U_ZERO_ERROR; 937f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_printf_reset_sign(format, info, prefixBuffer, &prefixBufferLen, &localStatus); 938f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 939f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 940f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return handler->pad_and_justify(context, info, result, resultLen); 941f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 942f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 943f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Use US-ASCII characters only for formatting. Most codepages have 944f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) characters 20-7F from Unicode. Using any other codepage specific 945f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) characters will make it very difficult to format the string on 946f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) non-Unicode machines */ 947f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const u_printf_info g_u_printf_infos[UPRINTF_NUM_FMT_HANDLERS] = { 948f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 0x20 */ 949f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 950f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_SIMPLE_PERCENT,UFMT_EMPTY, UFMT_EMPTY, 951f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 952f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 953f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 954f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 0x30 */ 955f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 956f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 957f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 958f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 959f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 960f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 0x40 */ 961f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_UCHAR, 962f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_SCIENTIFIC, UFMT_EMPTY, UFMT_SCIDBL, 963f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef U_USE_OBSOLETE_IO_FORMATTING 964f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_UCHAR/*deprecated*/, 965f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else 966f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 967f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 968f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 969f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 970f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 0x50 */ 971f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_PERCENT, UFMT_EMPTY, UFMT_EMPTY, UFMT_USTRING, 972f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef U_USE_OBSOLETE_IO_FORMATTING 973f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_USTRING/*deprecated*/,UFMT_SPELLOUT, UFMT_EMPTY, 974f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else 975f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_EMPTY, UFMT_SPELLOUT, UFMT_EMPTY, 976f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 977f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_HEX, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 978f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 979f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 980f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 0x60 */ 981f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_CHAR, 982f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_INT, UFMT_SCIENTIFIC, UFMT_DOUBLE, UFMT_SCIDBL, 983f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_INT, UFMT_EMPTY, UFMT_EMPTY, 984f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_EMPTY, UFMT_COUNT, UFMT_OCTAL, 985f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 986f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 0x70 */ 987f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_POINTER, UFMT_EMPTY, UFMT_EMPTY, UFMT_STRING, 988f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_UINT, UFMT_EMPTY, UFMT_EMPTY, 989f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_HEX, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 990f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, 991f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}; 992f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 993f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* flag characters for uprintf */ 994f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define FLAG_MINUS 0x002D 995f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define FLAG_PLUS 0x002B 996f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define FLAG_SPACE 0x0020 997f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define FLAG_POUND 0x0023 998f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define FLAG_ZERO 0x0030 999f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define FLAG_PAREN 0x0028 1000f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1001f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define ISFLAG(s) (s) == FLAG_MINUS || \ 1002f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (s) == FLAG_PLUS || \ 1003f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (s) == FLAG_SPACE || \ 1004f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (s) == FLAG_POUND || \ 1005f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (s) == FLAG_ZERO || \ 1006f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (s) == FLAG_PAREN 1007f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1008f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* special characters for uprintf */ 1009f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define SPEC_ASTERISK 0x002A 1010f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define SPEC_DOLLARSIGN 0x0024 1011f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define SPEC_PERIOD 0x002E 1012f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define SPEC_PERCENT 0x0025 1013f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1014f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* unicode digits */ 1015f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DIGIT_ZERO 0x0030 1016f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DIGIT_ONE 0x0031 1017f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DIGIT_TWO 0x0032 1018f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DIGIT_THREE 0x0033 1019f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DIGIT_FOUR 0x0034 1020f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DIGIT_FIVE 0x0035 1021f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DIGIT_SIX 0x0036 1022f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DIGIT_SEVEN 0x0037 1023f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DIGIT_EIGHT 0x0038 1024f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DIGIT_NINE 0x0039 1025f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1026f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define ISDIGIT(s) (s) == DIGIT_ZERO || \ 1027f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (s) == DIGIT_ONE || \ 1028f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (s) == DIGIT_TWO || \ 1029f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (s) == DIGIT_THREE || \ 1030f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (s) == DIGIT_FOUR || \ 1031f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (s) == DIGIT_FIVE || \ 1032f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (s) == DIGIT_SIX || \ 1033f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (s) == DIGIT_SEVEN || \ 1034f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (s) == DIGIT_EIGHT || \ 1035f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (s) == DIGIT_NINE 1036f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1037f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* u_printf modifiers */ 1038f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MOD_H 0x0068 1039f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MOD_LOWERL 0x006C 1040f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MOD_L 0x004C 1041f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1042f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define ISMOD(s) (s) == MOD_H || \ 1043f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (s) == MOD_LOWERL || \ 1044f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (s) == MOD_L 1045f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Returns an array of the parsed argument type given in the format string. */ 1046f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static ufmt_args* parseArguments(const UChar *alias, va_list ap, UErrorCode *status) { 1047f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ufmt_args *arglist = NULL; 1048f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ufmt_type_info *typelist = NULL; 1049f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool *islonglong = NULL; 1050f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t size = 0; 1051f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t pos = 0; 1052f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar type; 1053f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t handlerNum; 1054f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *aliasStart = alias; 1055f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1056f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* get maximum number of arguments */ 1057f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;;) { 1058f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* find % */ 1059f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(*alias != UP_PERCENT && *alias != 0x0000) { 1060f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias++; 1061f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1062f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1063f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*alias == 0x0000) { 1064f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1065f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1066f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1067f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias++; 1068f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1069f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* handle the pos number */ 1070f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(ISDIGIT(*alias)) { 1071f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1072f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* handle positional parameters */ 1073f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(ISDIGIT(*alias)) { 1074f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pos = (int) (*alias++ - DIGIT_ZERO); 1075f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1076f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(ISDIGIT(*alias)) { 1077f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pos *= 10; 1078f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pos += (int) (*alias++ - DIGIT_ZERO); 1079f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1080f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1081f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1082f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* if there is no '$', don't read anything */ 1083f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*alias != SPEC_DOLLARSIGN) { 1084f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 1085f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1086f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1087f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 1088f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1089f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1090f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (pos > size) { 1091f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) size = pos; 1092f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1093f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1094f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1095f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* create the parsed argument list */ 1096f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) typelist = (ufmt_type_info*)uprv_malloc(sizeof(ufmt_type_info) * size); 1097f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) islonglong = (UBool*)uprv_malloc(sizeof(UBool) * size); 1098f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) arglist = (ufmt_args*)uprv_malloc(sizeof(ufmt_args) * size); 1099f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* If malloc failed, return NULL */ 1101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!typelist || !islonglong || !arglist) { 1102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (typelist) { 1103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(typelist); 1104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (islonglong) { 1107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(islonglong); 1108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (arglist) { 1111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(arglist); 1112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 1115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 1116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* reset alias back to the beginning */ 1119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias = aliasStart; 1120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;;) { 1122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* find % */ 1123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(*alias != UP_PERCENT && *alias != 0x0000) { 1124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias++; 1125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*alias == 0x0000) { 1128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias++; 1132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* handle positional parameters */ 1134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(ISDIGIT(*alias)) { 1135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pos = (int) (*alias++ - DIGIT_ZERO); 1136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(ISDIGIT(*alias)) { 1138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pos *= 10; 1139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pos += (int) (*alias++ - DIGIT_ZERO); 1140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* offset position by 1 */ 1143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pos--; 1144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* skip over everything except for the type */ 1146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (ISMOD(*alias) || ISFLAG(*alias) || ISDIGIT(*alias) || 1147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *alias == SPEC_ASTERISK || *alias == SPEC_PERIOD || *alias == SPEC_DOLLARSIGN) { 1148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) islonglong[pos] = FALSE; 1149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (ISMOD(*alias)) { 1150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias++; 1151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (*alias == MOD_LOWERL) { 1152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) islonglong[pos] = TRUE; 1153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias++; 1156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) type = *alias; 1158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* store the argument type in the correct position of the parsed argument list */ 1160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) handlerNum = (uint16_t)(type - UPRINTF_BASE_FMT_HANDLERS); 1161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (handlerNum < UPRINTF_NUM_FMT_HANDLERS) { 1162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) typelist[pos] = g_u_printf_infos[ handlerNum ].info; 1163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) typelist[pos] = ufmt_empty; 1165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* store argument in arglist */ 1169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (pos = 0; pos < size; pos++) { 1170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch (typelist[pos]) { 1171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_string: 1172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_ustring: 1173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_pointer: 1174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) arglist[pos].ptrValue = va_arg(ap, void*); 1175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_char: 1177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_uchar: 1178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_int: 1179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (islonglong[pos]) { 1180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) arglist[pos].int64Value = va_arg(ap, int64_t); 1181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 1183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) arglist[pos].int64Value = va_arg(ap, int32_t); 1184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_float: 1187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) arglist[pos].floatValue = (float) va_arg(ap, double); 1188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_double: 1190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) arglist[pos].doubleValue = va_arg(ap, double); 1191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) default: 1193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* else args is ignored */ 1194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) arglist[pos].ptrValue = NULL; 1195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(typelist); 1200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(islonglong); 1201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return arglist; 1203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* We parse the argument list in Unicode */ 1206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CFUNC int32_t 1207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_printf_parse(const u_printf_stream_handler *streamHandler, 1208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *fmt, 1209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *context, 1210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_localized_print_string *locStringContext, 1211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ULocaleBundle *formatBundle, 1212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t *written, 1213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) va_list ap) 1214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 1215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t handlerNum; 1216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ufmt_args args; 1217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ufmt_type_info argType; 1218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_printf_handler *handler; 1219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_printf_spec spec; 1220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_printf_spec_info *info = &(spec.fInfo); 1221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *alias = fmt; 1223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *backup; 1224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *lastAlias; 1225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *orgAlias = fmt; 1226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* parsed argument list */ 1227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ufmt_args *arglist = NULL; /* initialized it to avoid compiler warnings */ 1228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 1229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!locStringContext || locStringContext->available >= 0) { 1230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* get the parsed list of argument types */ 1231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) arglist = parseArguments(orgAlias, ap, &status); 1232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Return error if parsing failed. */ 1234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return -1; 1236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* iterate through the pattern */ 1240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(!locStringContext || locStringContext->available >= 0) { 1241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* find the next '%' */ 1243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) lastAlias = alias; 1244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(*alias != UP_PERCENT && *alias != 0x0000) { 1245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias++; 1246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* write any characters before the '%' */ 1249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(alias > lastAlias) { 1250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *written += (streamHandler->write)(context, lastAlias, (int32_t)(alias - lastAlias)); 1251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* break if at end of string */ 1254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*alias == 0x0000) { 1255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* initialize spec to default values */ 1259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) spec.fWidthPos = -1; 1260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) spec.fPrecisionPos = -1; 1261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) spec.fArgPos = -1; 1262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memset(info, 0, sizeof(*info)); 1264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fPrecision = -1; 1265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fWidth = -1; 1266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fPadChar = 0x0020; 1267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* skip over the initial '%' */ 1269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias++; 1270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Check for positional argument */ 1272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(ISDIGIT(*alias)) { 1273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Save the current position */ 1275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) backup = alias; 1276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* handle positional parameters */ 1278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(ISDIGIT(*alias)) { 1279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) spec.fArgPos = (int) (*alias++ - DIGIT_ZERO); 1280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(ISDIGIT(*alias)) { 1282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) spec.fArgPos *= 10; 1283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) spec.fArgPos += (int) (*alias++ - DIGIT_ZERO); 1284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* if there is no '$', don't read anything */ 1288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*alias != SPEC_DOLLARSIGN) { 1289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) spec.fArgPos = -1; 1290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias = backup; 1291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* munge the '$' */ 1293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else 1294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias++; 1295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Get any format flags */ 1298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(ISFLAG(*alias)) { 1299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch(*alias++) { 1300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* left justify */ 1302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case FLAG_MINUS: 1303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fLeft = TRUE; 1304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* always show sign */ 1307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case FLAG_PLUS: 1308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fShowSign = TRUE; 1309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* use space if no sign present */ 1312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case FLAG_SPACE: 1313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fShowSign = TRUE; 1314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fSpace = TRUE; 1315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* use alternate form */ 1318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case FLAG_POUND: 1319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fAlt = TRUE; 1320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* pad with leading zeroes */ 1323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case FLAG_ZERO: 1324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fZero = TRUE; 1325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fPadChar = 0x0030; 1326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* pad character specified */ 1329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case FLAG_PAREN: 1330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* TODO test that all four are numbers */ 1332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* first four characters are hex values for pad char */ 1333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fPadChar = (UChar)ufmt_digitvalue(*alias++); 1334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*alias++)); 1335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*alias++)); 1336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*alias++)); 1337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* final character is ignored */ 1339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias++; 1340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Get the width */ 1346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* width is specified out of line */ 1348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*alias == SPEC_ASTERISK) { 1349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fWidth = -2; 1351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Skip the '*' */ 1353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias++; 1354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Save the current position */ 1356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) backup = alias; 1357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* handle positional parameters */ 1359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(ISDIGIT(*alias)) { 1360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) spec.fWidthPos = (int) (*alias++ - DIGIT_ZERO); 1361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(ISDIGIT(*alias)) { 1363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) spec.fWidthPos *= 10; 1364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) spec.fWidthPos += (int) (*alias++ - DIGIT_ZERO); 1365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* if there is no '$', don't read anything */ 1369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*alias != SPEC_DOLLARSIGN) { 1370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) spec.fWidthPos = -1; 1371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias = backup; 1372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* munge the '$' */ 1374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else 1375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias++; 1376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* read the width, if present */ 1378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else if(ISDIGIT(*alias)){ 1379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fWidth = (int) (*alias++ - DIGIT_ZERO); 1380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(ISDIGIT(*alias)) { 1382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fWidth *= 10; 1383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fWidth += (int) (*alias++ - DIGIT_ZERO); 1384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Get the precision */ 1388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*alias == SPEC_PERIOD) { 1390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* eat up the '.' */ 1392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias++; 1393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* precision is specified out of line */ 1395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*alias == SPEC_ASTERISK) { 1396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fPrecision = -2; 1398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Skip the '*' */ 1400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias++; 1401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* save the current position */ 1403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) backup = alias; 1404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* handle positional parameters */ 1406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(ISDIGIT(*alias)) { 1407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) spec.fPrecisionPos = (int) (*alias++ - DIGIT_ZERO); 1408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(ISDIGIT(*alias)) { 1410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) spec.fPrecisionPos *= 10; 1411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) spec.fPrecisionPos += (int) (*alias++ - DIGIT_ZERO); 1412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* if there is no '$', don't read anything */ 1415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*alias != SPEC_DOLLARSIGN) { 1416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) spec.fPrecisionPos = -1; 1417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias = backup; 1418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 1420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* munge the '$' */ 1421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias++; 1422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* read the precision */ 1426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else if(ISDIGIT(*alias)){ 1427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fPrecision = (int) (*alias++ - DIGIT_ZERO); 1428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(ISDIGIT(*alias)) { 1430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fPrecision *= 10; 1431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fPrecision += (int) (*alias++ - DIGIT_ZERO); 1432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Get any modifiers */ 1437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(ISMOD(*alias)) { 1438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch(*alias++) { 1439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* short */ 1441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case MOD_H: 1442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fIsShort = TRUE; 1443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* long or long long */ 1446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case MOD_LOWERL: 1447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*alias == MOD_LOWERL) { 1448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fIsLongLong = TRUE; 1449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* skip over the next 'l' */ 1450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias++; 1451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else 1453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fIsLong = TRUE; 1454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* long double */ 1457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case MOD_L: 1458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fIsLongDouble = TRUE; 1459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* finally, get the specifier letter */ 1464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fSpec = *alias++; 1465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fOrigSpec = info->fSpec; 1466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* fill in the precision and width, if specified out of line */ 1468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* width specified out of line */ 1470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(spec.fInfo.fWidth == -2) { 1471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(spec.fWidthPos == -1) { 1472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* read the width from the argument list */ 1473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fWidth = va_arg(ap, int32_t); 1474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* else handle positional parameter */ 1476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* if it's negative, take the absolute value and set left alignment */ 1478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(info->fWidth < 0) { 1479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fWidth *= -1; /* Make positive */ 1480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fLeft = TRUE; 1481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* precision specified out of line */ 1485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(info->fPrecision == -2) { 1486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(spec.fPrecisionPos == -1) { 1487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* read the precision from the argument list */ 1488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fPrecision = va_arg(ap, int32_t); 1489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* else handle positional parameter */ 1491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* if it's negative, set it to zero */ 1493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(info->fPrecision < 0) 1494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fPrecision = 0; 1495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) handlerNum = (uint16_t)(info->fSpec - UPRINTF_BASE_FMT_HANDLERS); 1498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (handlerNum < UPRINTF_NUM_FMT_HANDLERS) { 1499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* query the info function for argument information */ 1500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) argType = g_u_printf_infos[ handlerNum ].info; 1501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* goto the correct argument on arg_list if position is specified */ 1503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (spec.fArgPos > 0) { 1504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* offset position by 1 */ 1505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) spec.fArgPos--; 1506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch(argType) { 1507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_count: 1508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set the spec's width to the # of chars written */ 1509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fWidth = *written; 1510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* fall through to set the pointer */ 1511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_string: 1512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_ustring: 1513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_pointer: 1514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args.ptrValue = arglist[spec.fArgPos].ptrValue; 1515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_char: 1517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_uchar: 1518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_int: 1519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args.int64Value = arglist[spec.fArgPos].int64Value; 1520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_float: 1522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args.floatValue = arglist[spec.fArgPos].floatValue; 1523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_double: 1525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args.doubleValue = arglist[spec.fArgPos].doubleValue; 1526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) default: 1528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* else args is ignored */ 1529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args.ptrValue = NULL; 1530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { /* no positional argument specified */ 1533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch(argType) { 1534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_count: 1535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* set the spec's width to the # of chars written */ 1536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) info->fWidth = *written; 1537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* fall through to set the pointer */ 1538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_string: 1539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_ustring: 1540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_pointer: 1541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args.ptrValue = va_arg(ap, void*); 1542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_char: 1544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_uchar: 1545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_int: 1546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (info->fIsLongLong) { 1547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args.int64Value = va_arg(ap, int64_t); 1548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 1550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args.int64Value = va_arg(ap, int32_t); 1551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_float: 1554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args.floatValue = (float) va_arg(ap, double); 1555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ufmt_double: 1557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args.doubleValue = va_arg(ap, double); 1558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) default: 1560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* else args is ignored */ 1561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args.ptrValue = NULL; 1562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* call the handler function */ 1567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) handler = g_u_printf_infos[ handlerNum ].handler; 1568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(handler != 0) { 1569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *written += (*handler)(streamHandler, context, formatBundle, info, &args); 1570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 1572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* just echo unknown tags */ 1573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *written += (streamHandler->write)(context, fmt, (int32_t)(alias - lastAlias)); 1574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 1577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* just echo unknown tags */ 1578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *written += (streamHandler->write)(context, fmt, (int32_t)(alias - lastAlias)); 1579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* delete parsed argument list */ 1582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (arglist != NULL) { 1583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(arglist); 1584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* return # of characters in this format that have been parsed. */ 1586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (int32_t)(alias - fmt); 1587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !UCONFIG_NO_FORMATTING */ 1590