ICU-2256 Get both printf implementations ready for unification,

and remove the pointless loccache which is not thread safe and didn't really cache that much.

X-SVN-Rev: 12770
This commit is contained in:
George Rhoten 2003-08-06 16:18:38 +00:00
parent 85e7446047
commit 8f74281993
15 changed files with 533 additions and 830 deletions

View File

@ -51,7 +51,7 @@ CPPFLAGS += -I$(top_builddir)/common -I$(top_srcdir)/common -I$(top_srcdir)/i18n
DEFS += -DU_USTDIO_IMPLEMENTATION
LIBS = $(LIBICUUC) $(LIBICUI18N) $(DEFAULT_LIBS)
OBJECTS = locbund.o loccache.o ufile.o ufmt_cmn.o uprintf.o uprntf_p.o \
OBJECTS = locbund.o ufile.o ufmt_cmn.o uprintf.o uprntf_p.o \
uscanf.o uscanf_p.o uscanset.o ustdio.o sprintf.o \
sscanf.o ustream.o

View File

@ -29,197 +29,147 @@
#include "unicode/uloc.h"
ULocaleBundle*
u_locbund_init(ULocaleBundle *result, const char *loc)
{
int32_t len;
if(result == 0)
return 0;
if (loc == NULL) {
loc = uloc_getDefault();
}
uprv_memset(result, 0, sizeof(ULocaleBundle));
len = (int32_t)strlen(loc);
result->fLocale = (char*) uprv_malloc(len + 1);
if(result->fLocale == 0) {
uprv_free(result);
return 0;
}
strcpy(result->fLocale, loc);
return result;
}
/*ULocaleBundle*
u_locbund_new(const char *loc)
{
ULocaleBundle *result = (ULocaleBundle*) uprv_malloc(sizeof(ULocaleBundle));
int32_t len;
if(result == 0)
return 0;
len = (int32_t)(loc == 0 ? strlen(uloc_getDefault()) : strlen(loc));
result->fLocale = (char*) uprv_malloc(len + 1);
if(result->fLocale == 0) {
uprv_free(result);
return 0;
}
strcpy(result->fLocale, (loc == 0 ? uloc_getDefault() : loc) );
result->fNumberFormat = 0;
result->fPercentFormat = 0;
result->fCurrencyFormat = 0;
result->fScientificFormat = 0;
result->fSpelloutFormat = 0;
result->fDateFormat = 0;
result->fTimeFormat = 0;
return result;
ULocaleBundle *result = (ULocaleBundle*) uprv_malloc(sizeof(ULocaleBundle));
return u_locbund_init(result, loc);
}
ULocaleBundle*
u_locbund_clone(const ULocaleBundle *bundle)
{
ULocaleBundle *result = (ULocaleBundle*)uprv_malloc(sizeof(ULocaleBundle));
UErrorCode status = U_ZERO_ERROR;
if(result == 0)
return 0;
result->fLocale = (char*) uprv_malloc(strlen(bundle->fLocale) + 1);
if(result->fLocale == 0) {
uprv_free(result);
return 0;
}
strcpy(result->fLocale, bundle->fLocale );
result->fNumberFormat = (bundle->fNumberFormat == 0 ? 0 :
unum_clone(bundle->fNumberFormat, &status));
result->fPercentFormat = (bundle->fPercentFormat == 0 ? 0 :
unum_clone(bundle->fPercentFormat,
&status));
result->fCurrencyFormat = (bundle->fCurrencyFormat == 0 ? 0 :
unum_clone(bundle->fCurrencyFormat,
&status));
result->fScientificFormat = (bundle->fScientificFormat == 0 ? 0 :
unum_clone(bundle->fScientificFormat,
&status));
result->fSpelloutFormat = (bundle->fSpelloutFormat == 0 ? 0 :
unum_clone(bundle->fSpelloutFormat,
&status));
result->fDateFormat = (bundle->fDateFormat == 0 ? 0 :
udat_clone(bundle->fDateFormat, &status));
result->fTimeFormat = (bundle->fTimeFormat == 0 ? 0 :
udat_clone(bundle->fTimeFormat, &status));
return result;
}
ULocaleBundle *result = (ULocaleBundle*)uprv_malloc(sizeof(ULocaleBundle));
UErrorCode status = U_ZERO_ERROR;
int32_t styleIdx;
if(result == 0)
return 0;
result->fLocale = (char*) uprv_malloc(strlen(bundle->fLocale) + 1);
if(result->fLocale == 0) {
uprv_free(result);
return 0;
}
strcpy(result->fLocale, bundle->fLocale );
for (styleIdx = 0; styleIdx < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; styleIdx++) {
status = U_ZERO_ERROR;
if (result->fNumberFormat[styleIdx]) {
result->fNumberFormat[styleIdx] = unum_clone(bundle->fNumberFormat[styleIdx], &status);
if (U_FAILURE(status)) {
result->fNumberFormat[styleIdx] = NULL;
}
}
else {
result->fNumberFormat[styleIdx] = NULL;
}
}
result->fDateFormat = (bundle->fDateFormat == 0 ? 0 :
udat_clone(bundle->fDateFormat, &status));
result->fTimeFormat = (bundle->fTimeFormat == 0 ? 0 :
udat_clone(bundle->fTimeFormat, &status));
return result;
}*/
void
u_locbund_delete(ULocaleBundle *bundle)
u_locbund_close(ULocaleBundle *bundle)
{
uprv_free(bundle->fLocale);
int32_t styleIdx;
if(bundle->fNumberFormat != 0)
unum_close(bundle->fNumberFormat);
if(bundle->fPercentFormat != 0)
unum_close(bundle->fPercentFormat);
if(bundle->fCurrencyFormat != 0)
unum_close(bundle->fCurrencyFormat);
if(bundle->fScientificFormat != 0)
unum_close(bundle->fScientificFormat);
if(bundle->fSpelloutFormat != 0)
unum_close(bundle->fSpelloutFormat);
if(bundle->fDateFormat != 0)
udat_close(bundle->fDateFormat);
if(bundle->fTimeFormat != 0)
udat_close(bundle->fTimeFormat);
uprv_free(bundle);
}
UNumberFormat*
u_locbund_getNumberFormat(ULocaleBundle *bundle)
{
UErrorCode status = U_ZERO_ERROR;
if(bundle->fNumberFormat == 0) {
bundle->fNumberFormat = unum_open(UNUM_DEFAULT, NULL,0,bundle->fLocale,NULL, &status);
if(U_FAILURE(status))
return 0;
}
return bundle->fNumberFormat;
}
UNumberFormat*
u_locbund_getPercentFormat(ULocaleBundle *bundle)
{
UErrorCode status = U_ZERO_ERROR;
if(bundle->fPercentFormat == 0) {
bundle->fPercentFormat = unum_open(UNUM_PERCENT,NULL,0, bundle->fLocale,NULL, &status);
if(U_FAILURE(status))
return 0;
}
return bundle->fPercentFormat;
}
UNumberFormat*
u_locbund_getCurrencyFormat(ULocaleBundle *bundle)
{
UErrorCode status = U_ZERO_ERROR;
if(bundle->fCurrencyFormat == 0) {
bundle->fCurrencyFormat = unum_open(UNUM_CURRENCY,NULL,0, bundle->fLocale, NULL,&status);
if(U_FAILURE(status))
return 0;
}
return bundle->fCurrencyFormat;
}
#define PAT_SIZE 512
UNumberFormat*
u_locbund_getScientificFormat(ULocaleBundle *bundle)
{
UErrorCode status = U_ZERO_ERROR;
/* UChar pattern [PAT_SIZE];*/
if(bundle->fScientificFormat == 0) {
/* create the pattern for the locale */
/* u_uastrcpy(pattern, "0.000000E000");*/
uprv_free(bundle->fLocale);
bundle->fScientificFormat = unum_open(UNUM_SCIENTIFIC, NULL, 0,
bundle->fLocale, NULL,&status);
for (styleIdx = 0; styleIdx < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; styleIdx++) {
if (bundle->fNumberFormat[styleIdx]) {
unum_close(bundle->fNumberFormat[styleIdx]);
}
}
if(bundle->fDateFormat != 0)
udat_close(bundle->fDateFormat);
if(bundle->fTimeFormat != 0)
udat_close(bundle->fTimeFormat);
if(U_FAILURE(status))
return 0;
}
return bundle->fScientificFormat;
uprv_memset(bundle, 0, sizeof(ULocaleBundle));
/* uprv_free(bundle);*/
}
UNumberFormat*
u_locbund_getSpelloutFormat(ULocaleBundle *bundle)
u_locbund_getNumberFormat(ULocaleBundle *bundle, UNumberFormatStyle style)
{
UErrorCode status = U_ZERO_ERROR;
if(bundle->fSpelloutFormat == 0) {
bundle->fSpelloutFormat = unum_open(UNUM_SPELLOUT,NULL,0 ,bundle->fLocale, NULL,
&status);
}
return bundle->fSpelloutFormat;
if (style >= UNUM_IGNORE) {
UNumberFormat **formatAlias = &bundle->fNumberFormat[style-1];
if (*formatAlias == NULL) {
UErrorCode status = U_ZERO_ERROR;
*formatAlias = unum_open(style, NULL, 0, bundle->fLocale, NULL, &status);
if (U_FAILURE(status)) {
unum_close(*formatAlias);
*formatAlias = NULL;
}
}
return *formatAlias;
}
return NULL;
}
UDateFormat*
u_locbund_getDateFormat(ULocaleBundle *bundle)
{
UErrorCode status = U_ZERO_ERROR;
if(bundle->fDateFormat == 0) {
bundle->fDateFormat = udat_open(UDAT_NONE, UDAT_DEFAULT,
bundle->fLocale, 0, 0,NULL,0, &status);
}
return bundle->fDateFormat;
UErrorCode status = U_ZERO_ERROR;
if(bundle->fDateFormat == 0) {
bundle->fDateFormat = udat_open(UDAT_NONE, UDAT_DEFAULT,
bundle->fLocale, 0, 0,NULL,0, &status);
if (U_FAILURE(status)) {
udat_close(bundle->fDateFormat);
bundle->fDateFormat = NULL;
}
}
return bundle->fDateFormat;
}
UDateFormat*
u_locbund_getTimeFormat(ULocaleBundle *bundle)
{
UErrorCode status = U_ZERO_ERROR;
if(bundle->fTimeFormat == 0) {
bundle->fTimeFormat = udat_open(UDAT_DEFAULT, UDAT_NONE,
bundle->fLocale, 0, 0,NULL,0, &status);
}
return bundle->fTimeFormat;
UErrorCode status = U_ZERO_ERROR;
if(bundle->fTimeFormat == 0) {
bundle->fTimeFormat = udat_open(UDAT_DEFAULT, UDAT_NONE,
bundle->fLocale, 0, 0,NULL,0, &status);
if (U_FAILURE(status)) {
udat_close(bundle->fTimeFormat);
bundle->fTimeFormat = NULL;
}
}
return bundle->fTimeFormat;
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View File

@ -26,43 +26,49 @@
#include "unicode/unum.h"
#include "unicode/udat.h"
struct ULocaleBundle {
char *fLocale;
UNumberFormat *fNumberFormat;
UNumberFormat *fPercentFormat;
UNumberFormat *fCurrencyFormat;
UNumberFormat *fScientificFormat;
UNumberFormat *fSpelloutFormat;
#define ULOCALEBUNDLE_NUMBERFORMAT_COUNT ((int32_t)UNUM_SPELLOUT)
UDateFormat *fDateFormat;
UDateFormat *fTimeFormat;
};
typedef struct ULocaleBundle ULocaleBundle;
typedef struct ULocaleBundle {
char *fLocale;
UNumberFormat *fNumberFormat[ULOCALEBUNDLE_NUMBERFORMAT_COUNT];
UDateFormat *fDateFormat;
UDateFormat *fTimeFormat;
} ULocaleBundle;
/**
* Initialize a ULocaleBundle, initializing all formatters to 0.
* @param result A ULocaleBundle to initialize.
* @param loc The locale of the ULocaleBundle.
* @return A pointer to a ULocaleBundle, or 0 if <TT>loc</TT> was invalid.
*/
ULocaleBundle*
u_locbund_init(ULocaleBundle *result, const char *loc);
/**
* Create a new ULocaleBundle, initializing all formatters to 0.
* @param loc The locale of the ULocaleBundle.
* @return A pointer to a ULocaleBundle, or 0 if <TT>loc</TT> was invalid.
*/
ULocaleBundle*
u_locbund_new(const char *loc);
/*ULocaleBundle*
u_locbund_new(const char *loc);*/
/**
* Create a deep copy of this ULocaleBundle;
* @param bundle The ULocaleBundle to clone.
* @return A new ULocaleBundle.
*/
ULocaleBundle*
u_locbund_clone(const ULocaleBundle *bundle);
/*ULocaleBundle*
u_locbund_clone(const ULocaleBundle *bundle);*/
/**
* Delete the specified ULocaleBundle, freeing all associated memory.
* @param bundle The ULocaleBundle to delete
*/
void
u_locbund_delete(ULocaleBundle *bundle);
u_locbund_close(ULocaleBundle *bundle);
/**
* Get the NumberFormat used to format and parse numbers in a ULocaleBundle.
@ -70,39 +76,7 @@ u_locbund_delete(ULocaleBundle *bundle);
* @return A pointer to the NumberFormat used for number formatting and parsing.
*/
UNumberFormat*
u_locbund_getNumberFormat(ULocaleBundle *bundle);
/**
* Get the NumberFormat used to format and parse percents in a ULocaleBundle.
* @param bundle The ULocaleBundle to use
* @return A pointer to the NumberFormat used for percent formatting and parsing.
*/
UNumberFormat*
u_locbund_getPercentFormat(ULocaleBundle *bundle);
/**
* Get the NumberFormat used to format and parse currency in a ULocaleBundle.
* @param bundle The ULocaleBundle to use
* @return A pointer to the NumberFormat used for currency formatting and parsing.
*/
UNumberFormat*
u_locbund_getCurrencyFormat(ULocaleBundle *bundle);
/**
* Get the NumberFormat used to format and parse scientific numbers in a ULocaleBundle.
* @param bundle The ULocaleBundle to use
* @return A pointer to the NumberFormat used for scientific formatting and parsing.
*/
UNumberFormat*
u_locbund_getScientificFormat(ULocaleBundle *bundle);
/**
* Get the NumberFormat used format to and parse spelled-out numbers in a ULocaleBundle.
* @param bundle The ULocaleBundle to use
* @return A pointer to the NumberFormat used for spelled-out number formatting and parsing.
*/
UNumberFormat*
u_locbund_getSpelloutFormat(ULocaleBundle *bundle);
u_locbund_getNumberFormat(ULocaleBundle *bundle, UNumberFormatStyle style);
/**
* Get the DateFormat used to format and parse dates in a ULocaleBundle.

View File

@ -1,122 +0,0 @@
/*
*******************************************************************************
*
* Copyright (C) 1998-2003, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
*
* File loccache.c
*
* Modification History:
*
* Date Name Description
* 11/18/98 stephen Creation.
* 03/11/99 stephen Modified for new C API.
* 06/16/99 stephen Added #include for uloc.h
*******************************************************************************
*/
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
#include "loccache.h"
#include "uhash.h"
#include "unicode/uloc.h"
#include "umutex.h"
#include "ucln.h"
/* The global cache */
static UHashtable *gLocaleCache = NULL;
static void U_CALLCONV
hash_freeBundle(void* obj)
{
u_locbund_delete((ULocaleBundle *)obj);
}
ULocaleBundle*
u_loccache_get(const char *loc)
{
ULocaleBundle *result;
UErrorCode status = U_ZERO_ERROR;
/* Create the cache, if needed */
if(gLocaleCache == NULL) {
UHashtable *tempCache;
int32_t locCount = uloc_countAvailable();
tempCache = uhash_openSize(uhash_hashChars, uhash_compareChars, locCount, &status);
if(U_FAILURE(status))
return NULL;
uhash_setValueDeleter(tempCache, hash_freeBundle);
/* Lock the cache */
umtx_lock(NULL);
/* Make sure it didn't change while we were acquiring the lock */
if(gLocaleCache == NULL) {
gLocaleCache = tempCache;
}
else {
uhash_close(tempCache);
}
/* Unlock the cache */
umtx_unlock(NULL);
ucln_ustdio_registerCleanup();
}
/* Try and get the bundle from the cache */
/* This will be slightly wasteful the first time around, */
/* since we know the cache will be empty. But, it simplifies */
/* the code a great deal. */
result = (ULocaleBundle*)uhash_get(gLocaleCache, loc);
/* If the bundle wasn't found, create it and add it to the cache */
if(result == NULL) {
/* Create the bundle */
ULocaleBundle *tempBundle = u_locbund_new(loc);
/* Lock the cache */
umtx_lock(NULL);
/* Make sure the cache didn't change while we were locking it */
result = (ULocaleBundle*)uhash_get(gLocaleCache, loc);
if(result == NULL) {
result = tempBundle;
uhash_put(gLocaleCache, tempBundle->fLocale, tempBundle, &status);
}
else {
u_locbund_delete(tempBundle);
}
/* Unlock the cache */
umtx_unlock(NULL);
}
return result;
}
static UBool loccache_cleanup()
{
if (gLocaleCache) {
uhash_close(gLocaleCache);
gLocaleCache = NULL;
}
return TRUE; /* Everything was cleaned up */
}
static UBool ustdio_cleanup(void)
{
return loccache_cleanup();
}
void ucln_ustdio_registerCleanup()
{
ucln_registerCleanup(UCLN_USTDIO, ustdio_cleanup);
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View File

@ -1,36 +0,0 @@
/*
*******************************************************************************
*
* Copyright (C) 1998-2003, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
*
* File loccache.h
*
* Modification History:
*
* Date Name Description
* 11/18/98 stephen Creation.
* 03/11/99 stephen Modified for new C API.
*******************************************************************************
*/
#ifndef LOCCACHE_H
#define LOCCACHE_H
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
#include "locbund.h"
ULocaleBundle*
u_loccache_get(const char *loc);
/* Main library cleanup function. */
U_CFUNC void ucln_ustdio_registerCleanup(void);
#endif /* #if !UCONFIG_NO_FORMATTING */
#endif

View File

@ -30,7 +30,6 @@
#include "sprintf.h"
#include "uprntf_p.h"
#include "locbund.h"
#include "loccache.h"
#include "cmemory.h"
#include <ctype.h>
@ -41,55 +40,55 @@
/* Use US-ASCII characters only for formatting */
/* % */
#define UFMT_SIMPLE_PERCENT {ufmt_simple_percent, u_sprintf_simple_percent_handler}
#define UFMT_SIMPLE_PERCENT {ufmt_simple_percent, u_printf_simple_percent_handler}
/* s */
#define UFMT_STRING {ufmt_string, u_sprintf_string_handler}
#define UFMT_STRING {ufmt_string, u_printf_string_handler}
/* c */
#define UFMT_CHAR {ufmt_char, u_sprintf_char_handler}
#define UFMT_CHAR {ufmt_char, u_printf_char_handler}
/* d, i */
#define UFMT_INT {ufmt_int, u_sprintf_integer_handler}
#define UFMT_INT {ufmt_int, u_printf_integer_handler}
/* u */
#define UFMT_UINT {ufmt_int, u_sprintf_uinteger_handler}
#define UFMT_UINT {ufmt_int, u_printf_uinteger_handler}
/* o */
#define UFMT_OCTAL {ufmt_int, u_sprintf_octal_handler}
#define UFMT_OCTAL {ufmt_int, u_printf_octal_handler}
/* x, X */
#define UFMT_HEX {ufmt_int, u_sprintf_hex_handler}
#define UFMT_HEX {ufmt_int, u_printf_hex_handler}
/* f */
#define UFMT_DOUBLE {ufmt_double, u_sprintf_double_handler}
#define UFMT_DOUBLE {ufmt_double, u_printf_double_handler}
/* e, E */
#define UFMT_SCIENTIFIC {ufmt_double, u_sprintf_scientific_handler}
#define UFMT_SCIENTIFIC {ufmt_double, u_printf_scientific_handler}
/* g, G */
#define UFMT_SCIDBL {ufmt_double, u_sprintf_scidbl_handler}
#define UFMT_SCIDBL {ufmt_double, u_printf_scidbl_handler}
/* n */
#define UFMT_COUNT {ufmt_count, u_sprintf_count_handler}
#define UFMT_COUNT {ufmt_count, u_printf_count_handler}
/* non-ANSI extensions */
/* Use US-ASCII characters only for formatting */
/* p */
#define UFMT_POINTER {ufmt_pointer, u_sprintf_pointer_handler}
#define UFMT_POINTER {ufmt_pointer, u_printf_pointer_handler}
/* D */
#define UFMT_DATE {ufmt_date, u_sprintf_date_handler}
#define UFMT_DATE {ufmt_date, u_printf_date_handler}
/* T */
#define UFMT_TIME {ufmt_date, u_sprintf_time_handler}
#define UFMT_TIME {ufmt_date, u_printf_time_handler}
/* V */
#define UFMT_SPELLOUT {ufmt_double, u_sprintf_spellout_handler}
#define UFMT_SPELLOUT {ufmt_double, u_printf_spellout_handler}
/* P */
#define UFMT_PERCENT {ufmt_double, u_sprintf_percent_handler}
#define UFMT_PERCENT {ufmt_double, u_printf_percent_handler}
/* M */
#define UFMT_CURRENCY {ufmt_double, u_sprintf_currency_handler}
#define UFMT_CURRENCY {ufmt_double, u_printf_currency_handler}
/* K */
#define UFMT_UCHAR {ufmt_uchar, u_sprintf_uchar_handler}
#define UFMT_UCHAR {ufmt_uchar, u_printf_uchar_handler}
/* U */
#define UFMT_USTRING {ufmt_ustring, u_sprintf_ustring_handler}
#define UFMT_USTRING {ufmt_ustring, u_printf_ustring_handler}
#define UFMT_EMPTY {ufmt_empty, NULL}
typedef struct u_sprintf_info {
typedef struct u_printf_info {
ufmt_type_info info;
u_sprintf_handler handler;
} u_sprintf_info;
u_printf_handler *handler;
} u_printf_info;
#define UPRINTF_NUM_FMT_HANDLERS 108
@ -104,9 +103,13 @@ static const UChar gNullStr[] = {0x28, 0x6E, 0x75, 0x6C, 0x6C, 0x29, 0}; /* "(nu
static const UChar gSpaceStr[] = {0x20, 0}; /* " " */
/* copies the minimum number of code units of (count or output->available) */
/* u_minstrncpy copies the minimum number of code units of (count or output->available) */
static int32_t
u_minstrncpy(u_localized_string *output, const UChar *str, int32_t count) {
u_sprintf_write(void *context,
const UChar *str,
int32_t count)
{
u_localized_string *output = (u_localized_string *)context;
int32_t size = ufmt_min(count, output->available);
u_strncpy(output->str + (output->len - output->available), str, size);
@ -115,11 +118,12 @@ u_minstrncpy(u_localized_string *output, const UChar *str, int32_t count) {
}
static int32_t
u_sprintf_pad_and_justify(u_localized_string *output,
u_sprintf_pad_and_justify(void *context,
const u_printf_spec_info *info,
const UChar *result,
int32_t resultLen)
{
u_localized_string *output = (u_localized_string *)context;
int32_t written = 0;
resultLen = ufmt_min(resultLen, output->available);
@ -140,7 +144,7 @@ u_sprintf_pad_and_justify(u_localized_string *output,
/* left justify */
if(info->fLeft) {
written += u_minstrncpy(output, result, resultLen);
written += u_sprintf_write(output, result, resultLen);
u_memset(&output->str[outputPos + resultLen], info->fPadChar, paddingLeft);
output->available -= paddingLeft;
}
@ -148,12 +152,12 @@ u_sprintf_pad_and_justify(u_localized_string *output,
else {
u_memset(&output->str[outputPos], info->fPadChar, paddingLeft);
output->available -= paddingLeft;
written += u_minstrncpy(output, result, resultLen);
written += u_sprintf_write(output, result, resultLen);
}
}
/* just write the formatted output */
else {
written = u_minstrncpy(output, result, resultLen);
written = u_sprintf_write(output, result, resultLen);
}
return written;
@ -192,22 +196,23 @@ u_printf_set_sign(UNumberFormat *format,
/* handle a '%' */
static int32_t
u_sprintf_simple_percent_handler(u_localized_string *output,
u_printf_simple_percent_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
static const UChar PERCENT[] = { UP_PERCENT };
/* put a single '%' onto the output */
if (output->available >= 1) {
output->str[output->len - output->available--] = 0x0025;
/* we wrote one character */
return 1;
}
return 0;
return handler->write(context, PERCENT, 1);
}
/* handle 's' */
static int32_t
u_sprintf_string_handler(u_localized_string *output,
u_printf_string_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -244,11 +249,11 @@ u_sprintf_string_handler(u_localized_string *output,
/* precision takes precedence over width */
/* determine if the string should be truncated */
if(info->fPrecision != -1 && len > info->fPrecision) {
written = u_minstrncpy(output, s, info->fPrecision);
written = handler->write(context, s, info->fPrecision);
}
/* determine if the string should be padded */
else {
written = u_sprintf_pad_and_justify(output, info, s, len);
written = handler->pad_and_justify(context, info, s, len);
}
/* clean up */
@ -260,7 +265,9 @@ u_sprintf_string_handler(u_localized_string *output,
}
static int32_t
u_sprintf_char_handler(u_localized_string *output,
u_printf_char_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -282,18 +289,20 @@ u_sprintf_char_handler(u_localized_string *output,
/* precision takes precedence over width */
/* determine if the string should be truncated */
if(info->fPrecision != -1 && len > info->fPrecision) {
written = u_minstrncpy(output, s, info->fPrecision);
written = handler->write(context, s, info->fPrecision);
}
else {
/* determine if the string should be padded */
written = u_sprintf_pad_and_justify(output, info, s, len);
written = handler->pad_and_justify(context, info, s, len);
}
return written;
}
static int32_t
u_sprintf_double_handler(u_localized_string *output,
u_printf_double_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -309,27 +318,17 @@ u_sprintf_double_handler(u_localized_string *output,
num &= DBL_MAX;*/
/* get the formatter */
format = u_locbund_getNumberFormat(output->fBundle);
format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL);
/* handle error */
if(format == 0)
return 0;
/* set the appropriate flags on the formatter */
/* clone the output's bundle if it isn't owned */
if(! output->fOwnBundle) {
output->fBundle = u_locbund_clone(output->fBundle);
output->fOwnBundle = TRUE;
format = u_locbund_getNumberFormat(output->fBundle);
}
/* set the number of decimal digits */
/* save the formatter's state */
minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS);
maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS);
/* set the appropriate flags and number of decimal digits on the formatter */
if(info->fPrecision != -1) {
/* set the # of decimal digits */
unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision);
@ -358,12 +357,14 @@ u_sprintf_double_handler(u_localized_string *output,
unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits);
unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits);
return u_sprintf_pad_and_justify(output, info, result, u_strlen(result));
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
/* HSYS */
static int32_t
u_sprintf_integer_handler(u_localized_string *output,
u_printf_integer_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -373,7 +374,6 @@ u_sprintf_integer_handler(u_localized_string *output,
int32_t minDigits = -1;
UErrorCode status = U_ZERO_ERROR;
/* mask off any necessary bits */
if(info->fIsShort)
num &= UINT16_MAX;
@ -381,7 +381,7 @@ u_sprintf_integer_handler(u_localized_string *output,
num &= UINT32_MAX;
/* get the formatter */
format = u_locbund_getNumberFormat(output->fBundle);
format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL);
/* handle error */
if(format == 0)
@ -391,13 +391,6 @@ u_sprintf_integer_handler(u_localized_string *output,
/* set the minimum integer digits */
if(info->fPrecision != -1) {
/* clone the output's bundle if it isn't owned */
if(! output->fOwnBundle) {
output->fBundle = u_locbund_clone(output->fBundle);
output->fOwnBundle = TRUE;
format = u_locbund_getNumberFormat(output->fBundle);
}
/* set the minimum # of digits */
minDigits = unum_getAttribute(format, UNUM_MIN_INTEGER_DIGITS);
unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, info->fPrecision);
@ -405,13 +398,6 @@ u_sprintf_integer_handler(u_localized_string *output,
/* set whether to show the sign */
if(info->fShowSign) {
/* clone the output's bundle if it isn't owned */
if(! output->fOwnBundle) {
output->fBundle = u_locbund_clone(output->fBundle);
output->fOwnBundle = TRUE;
format = u_locbund_getNumberFormat(output->fBundle);
}
u_printf_set_sign(format, info, &status);
}
@ -423,11 +409,13 @@ u_sprintf_integer_handler(u_localized_string *output,
unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, minDigits);
}
return u_sprintf_pad_and_justify(output, info, result, u_strlen(result));
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
static int32_t
u_sprintf_hex_handler(u_localized_string *output,
u_printf_hex_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -456,11 +444,13 @@ u_sprintf_hex_handler(u_localized_string *output,
len += 2;
}
return u_sprintf_pad_and_justify(output, info, result, len);
return handler->pad_and_justify(context, info, result, len);
}
static int32_t
u_sprintf_octal_handler(u_localized_string *output,
u_printf_octal_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -488,12 +478,13 @@ u_sprintf_octal_handler(u_localized_string *output,
len += 1;
}
return u_sprintf_pad_and_justify(output, info, result, len);
return handler->pad_and_justify(context, info, result, len);
}
static int32_t
u_sprintf_uinteger_handler(u_localized_string *output,
u_printf_uinteger_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -509,11 +500,13 @@ u_sprintf_uinteger_handler(u_localized_string *output,
/* Get around int32_t limitations */
uint_args.doubleValue = ((double) ((uint32_t) (uint_args.intValue)));
return u_sprintf_double_handler(output, &uint_info, &uint_args);
return u_printf_double_handler(handler, context, formatBundle, &uint_info, &uint_args);
}
static int32_t
u_sprintf_pointer_handler(u_localized_string *output,
u_printf_pointer_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -525,11 +518,13 @@ u_sprintf_pointer_handler(u_localized_string *output,
/* format the pointer in hex */
ufmt_ltou(result, &len, num, 16, TRUE, info->fPrecision);
return u_sprintf_pad_and_justify(output, info, result, len);
return handler->pad_and_justify(context, info, result, len);
}
static int32_t
u_sprintf_scientific_handler(u_localized_string *output,
u_printf_scientific_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -549,7 +544,7 @@ u_sprintf_scientific_handler(u_localized_string *output,
num &= DBL_MAX;*/
/* get the formatter */
format = u_locbund_getScientificFormat(output->fBundle);
format = u_locbund_getNumberFormat(formatBundle, UNUM_SCIENTIFIC);
/* handle error */
if(format == 0)
@ -557,13 +552,6 @@ u_sprintf_scientific_handler(u_localized_string *output,
/* set the appropriate flags on the formatter */
/* clone the output's bundle if it isn't owned */
if(! output->fOwnBundle) {
output->fBundle = u_locbund_clone(output->fBundle);
output->fOwnBundle = TRUE;
format = u_locbund_getScientificFormat(output->fBundle);
}
srcLen = unum_getSymbol(format,
UNUM_EXPONENTIAL_SYMBOL,
srcExpBuf,
@ -574,13 +562,13 @@ u_sprintf_scientific_handler(u_localized_string *output,
if (info->fSpec == (UChar)0x65 /* e */) {
expLen = u_strToLower(expBuf, (int32_t)sizeof(expBuf),
srcExpBuf, srcLen,
output->fBundle->fLocale,
formatBundle->fLocale,
&status);
}
else {
expLen = u_strToUpper(expBuf, (int32_t)sizeof(expBuf),
srcExpBuf, srcLen,
output->fBundle->fLocale,
formatBundle->fLocale,
&status);
}
@ -590,12 +578,11 @@ u_sprintf_scientific_handler(u_localized_string *output,
expLen,
&status);
/* set the number of decimal digits */
/* save the formatter's state */
minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS);
maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS);
/* set the appropriate flags and number of decimal digits on the formatter */
if(info->fPrecision != -1) {
/* set the # of decimal digits */
unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision);
@ -632,11 +619,13 @@ u_sprintf_scientific_handler(u_localized_string *output,
srcLen,
&status);*/
return u_sprintf_pad_and_justify(output, info, result, u_strlen(result));
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
static int32_t
u_sprintf_date_handler(u_localized_string *output,
u_printf_date_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -647,7 +636,7 @@ u_sprintf_date_handler(u_localized_string *output,
/* get the formatter */
format = u_locbund_getDateFormat(output->fBundle);
format = u_locbund_getDateFormat(formatBundle);
/* handle error */
if(format == 0)
@ -656,11 +645,13 @@ u_sprintf_date_handler(u_localized_string *output,
/* format the date */
udat_format(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status);
return u_sprintf_pad_and_justify(output, info, result, u_strlen(result));
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
static int32_t
u_sprintf_time_handler(u_localized_string *output,
u_printf_time_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -671,7 +662,7 @@ u_sprintf_time_handler(u_localized_string *output,
/* get the formatter */
format = u_locbund_getTimeFormat(output->fBundle);
format = u_locbund_getTimeFormat(formatBundle);
/* handle error */
if(format == 0)
@ -680,12 +671,13 @@ u_sprintf_time_handler(u_localized_string *output,
/* format the time */
udat_format(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status);
return u_sprintf_pad_and_justify(output, info, result, u_strlen(result));
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
static int32_t
u_sprintf_percent_handler(u_localized_string *output,
u_printf_percent_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -702,27 +694,17 @@ u_sprintf_percent_handler(u_localized_string *output,
num &= DBL_MAX;*/
/* get the formatter */
format = u_locbund_getPercentFormat(output->fBundle);
format = u_locbund_getNumberFormat(formatBundle, UNUM_PERCENT);
/* handle error */
if(format == 0)
return 0;
/* set the appropriate flags on the formatter */
/* clone the output's bundle if it isn't owned */
if(! output->fOwnBundle) {
output->fBundle = u_locbund_clone(output->fBundle);
output->fOwnBundle = TRUE;
format = u_locbund_getPercentFormat(output->fBundle);
}
/* set the number of decimal digits */
/* save the formatter's state */
minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS);
maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS);
/* set the appropriate flags and number of decimal digits on the formatter */
if(info->fPrecision != -1) {
/* set the # of decimal digits */
unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision);
@ -751,12 +733,13 @@ u_sprintf_percent_handler(u_localized_string *output,
unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits);
unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits);
return u_sprintf_pad_and_justify(output, info, result, u_strlen(result));
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
static int32_t
u_sprintf_currency_handler(u_localized_string *output,
u_printf_currency_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -773,27 +756,17 @@ u_sprintf_currency_handler(u_localized_string *output,
num &= DBL_MAX;*/
/* get the formatter */
format = u_locbund_getCurrencyFormat(output->fBundle);
format = u_locbund_getNumberFormat(formatBundle, UNUM_CURRENCY);
/* handle error */
if(format == 0)
return 0;
/* set the appropriate flags on the formatter */
/* clone the output's bundle if it isn't owned */
if(! output->fOwnBundle) {
output->fBundle = u_locbund_clone(output->fBundle);
output->fOwnBundle = TRUE;
format = u_locbund_getCurrencyFormat(output->fBundle);
}
/* set the number of decimal digits */
/* save the formatter's state */
minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS);
maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS);
/* set the appropriate flags and number of decimal digits on the formatter */
if(info->fPrecision != -1) {
/* set the # of decimal digits */
unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision);
@ -822,11 +795,13 @@ u_sprintf_currency_handler(u_localized_string *output,
unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits);
unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits);
return u_sprintf_pad_and_justify(output, info, result, u_strlen(result));
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
static int32_t
u_sprintf_ustring_handler(u_localized_string *output,
u_printf_ustring_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -845,18 +820,20 @@ u_sprintf_ustring_handler(u_localized_string *output,
/* precision takes precedence over width */
/* determine if the string should be truncated */
if(info->fPrecision != -1 && len > info->fPrecision) {
written = u_minstrncpy(output, arg, info->fPrecision);
written = handler->write(context, arg, info->fPrecision);
}
else {
/* determine if the string should be padded */
written = u_sprintf_pad_and_justify(output, info, arg, len);
written = handler->pad_and_justify(context, info, arg, len);
}
return written;
}
static int32_t
u_sprintf_uchar_handler(u_localized_string *output,
u_printf_uchar_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -875,14 +852,16 @@ u_sprintf_uchar_handler(u_localized_string *output,
}
else {
/* determine if the string should be padded */
written = u_sprintf_pad_and_justify(output, info, &arg, 1);
written = handler->pad_and_justify(context, info, &arg, 1);
}
return written;
}
static int32_t
u_sprintf_scidbl_handler(u_localized_string *output,
u_printf_scidbl_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -898,7 +877,7 @@ u_sprintf_scidbl_handler(u_localized_string *output,
scidbl_info.fSpec = 0x0066;
scidbl_info.fPrecision = 0;
/* call the double handler */
return u_sprintf_double_handler(output, &scidbl_info, args);
return u_printf_double_handler(handler, context, formatBundle, &scidbl_info, args);
}
else if(num < 0.0001 || (scidbl_info.fPrecision < 1 && 1000000.0 <= num)
|| (scidbl_info.fPrecision != -1 && num > uprv_pow10(scidbl_info.fPrecision)))
@ -906,19 +885,20 @@ u_sprintf_scidbl_handler(u_localized_string *output,
/* use 'e' or 'E' notation */
scidbl_info.fSpec = scidbl_info.fSpec - 2;
/* call the scientific handler */
return u_sprintf_scientific_handler(output, &scidbl_info, args);
return u_printf_scientific_handler(handler, context, formatBundle, &scidbl_info, args);
}
else {
/* use 'f' notation */
scidbl_info.fSpec = 0x0066;
/* call the double handler */
return u_sprintf_double_handler(output, &scidbl_info, args);
return u_printf_double_handler(handler, context, formatBundle, &scidbl_info, args);
}
}
static int32_t
u_sprintf_count_handler(u_localized_string *output,
u_printf_count_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -932,7 +912,9 @@ u_sprintf_count_handler(u_localized_string *output,
}
static int32_t
u_sprintf_spellout_handler(u_localized_string *output,
u_printf_spellout_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
@ -949,27 +931,17 @@ u_sprintf_spellout_handler(u_localized_string *output,
num &= DBL_MAX;*/
/* get the formatter */
format = u_locbund_getSpelloutFormat(output->fBundle);
format = u_locbund_getNumberFormat(formatBundle, UNUM_SPELLOUT);
/* handle error */
if(format == 0)
return 0;
/* set the appropriate flags on the formatter */
/* clone the output's bundle if it isn't owned */
if(! output->fOwnBundle) {
output->fBundle = u_locbund_clone(output->fBundle);
output->fOwnBundle = TRUE;
format = u_locbund_getSpelloutFormat(output->fBundle);
}
/* set the number of decimal digits */
/* save the formatter's state */
minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS);
maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS);
/* set the appropriate flags and number of decimal digits on the formatter */
if(info->fPrecision != -1) {
/* set the # of decimal digits */
unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision);
@ -998,7 +970,7 @@ u_sprintf_spellout_handler(u_localized_string *output,
unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits);
unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits);
return u_sprintf_pad_and_justify(output, info, result, u_strlen(result));
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
U_CAPI int32_t U_EXPORT2
@ -1124,7 +1096,7 @@ u_vsprintf_u(UChar *buffer,
characters 20-7F from Unicode. Using any other codepage specific
characters will make it very difficult to format the string on
non-Unicode machines */
static const u_sprintf_info g_u_sprintf_infos[UPRINTF_NUM_FMT_HANDLERS] = {
static const u_printf_info g_u_printf_infos[UPRINTF_NUM_FMT_HANDLERS] = {
/* 0x20 */
UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY,
UFMT_EMPTY, UFMT_SIMPLE_PERCENT,UFMT_EMPTY, UFMT_EMPTY,
@ -1162,6 +1134,11 @@ static const u_sprintf_info g_u_sprintf_infos[UPRINTF_NUM_FMT_HANDLERS] = {
UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY,
};
static const u_printf_stream_handler g_sprintf_stream_handler = {
u_sprintf_write,
u_sprintf_pad_and_justify
};
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
u_vsnprintf_u(UChar *buffer,
int32_t count,
@ -1179,7 +1156,7 @@ u_vsnprintf_u(UChar *buffer,
u_localized_string outStr;
u_printf_spec spec;
ufmt_type_info info;
u_sprintf_handler handler;
u_printf_handler *handler;
if (count < 0) {
count = INT32_MAX;
@ -1193,12 +1170,10 @@ u_vsnprintf_u(UChar *buffer,
if(locale == 0) {
locale = uloc_getDefault();
}
outStr.fBundle = u_loccache_get(locale);
if(outStr.fBundle == 0) {
if(u_locbund_init(&outStr.fBundle, locale) == 0) {
return 0;
}
outStr.fOwnBundle = FALSE;
/* iterate through the pattern */
while(outStr.available > 0) {
@ -1211,7 +1186,7 @@ u_vsnprintf_u(UChar *buffer,
/* write any characters before the '%' */
if(alias > lastAlias) {
written += u_minstrncpy(&outStr, lastAlias, (int32_t)(alias - lastAlias));
written += (*g_sprintf_stream_handler.write)(&outStr, lastAlias, (int32_t)(alias - lastAlias));
}
/* break if at end of string */
@ -1259,7 +1234,7 @@ u_vsnprintf_u(UChar *buffer,
handlerNum = (uint16_t)(spec.fInfo.fSpec - UPRINTF_BASE_FMT_HANDLERS);
if (handlerNum < UPRINTF_NUM_FMT_HANDLERS) {
/* query the info function for argument information */
info = g_u_sprintf_infos[ handlerNum ].info;
info = g_u_printf_infos[ handlerNum ].info;
if(info > ufmt_simple_percent) {
switch(info) {
case ufmt_count:
@ -1300,18 +1275,18 @@ u_vsnprintf_u(UChar *buffer,
}
/* call the handler function */
handler = g_u_sprintf_infos[ handlerNum ].handler;
handler = g_u_printf_infos[ handlerNum ].handler;
if(handler != 0) {
written += (*handler)(&outStr, &spec.fInfo, &args);
written += (*handler)(&g_sprintf_stream_handler, &outStr, &outStr.fBundle, &spec.fInfo, &args);
}
else {
/* just echo unknown tags */
written += u_minstrncpy(&outStr, lastAlias, (int32_t)(alias - lastAlias));
written += (*g_sprintf_stream_handler.write)(&outStr, lastAlias, (int32_t)(alias - lastAlias));
}
}
else {
/* just echo unknown tags */
written += u_minstrncpy(&outStr, lastAlias, (int32_t)(alias - lastAlias));
written += (*g_sprintf_stream_handler.write)(&outStr, lastAlias, (int32_t)(alias - lastAlias));
}
/* update the pointer in pattern and continue */
@ -1324,14 +1299,11 @@ u_vsnprintf_u(UChar *buffer,
}
/* Release the cloned bundle, if we cloned it. */
if(outStr.fOwnBundle) {
u_locbund_delete(outStr.fBundle);
outStr.fBundle = NULL;
outStr.fOwnBundle = FALSE;
}
u_locbund_close(&outStr.fBundle);
/* return # of UChars written */
return written;
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View File

@ -22,33 +22,17 @@
#if !UCONFIG_NO_FORMATTING
#include "unicode/ustdio.h"
#include "uprintf.h"
#include "ufmt_cmn.h"
#include "locbund.h"
#include "uprintf.h"
struct u_localized_string {
UChar *str; /* Place to write the string */
int32_t available;/* Number of codeunits available to write to */
int32_t len; /* Maximum number of code units that can be written to output */
typedef struct u_localized_string {
UChar *str; /* Place to write the string */
int32_t available;/* Number of codeunits available to write to */
int32_t len; /* Maximum number of code units that can be written to output */
ULocaleBundle *fBundle; /* formatters */
UBool fOwnBundle; /* TRUE if fBundle should be deleted */
};
typedef struct u_localized_string u_localized_string;
/**
* A u_printf handler function.
* A u_printf handler is responsible for handling a single u_printf
* format specification, for example 'd' or 's'.
* @param info A pointer to a <TT>u_printf_spec_info</TT> struct containing
* information on the format specification.
* @param args A pointer to the argument data
* @return The number of Unicode characters written to <TT>stream</TT>.
*/
typedef int32_t (*u_sprintf_handler) (u_localized_string *output,
const u_printf_spec_info *info,
const ufmt_args *args);
ULocaleBundle fBundle; /* formatters */
} u_localized_string;
#endif /* #if !UCONFIG_NO_FORMATTING */

View File

@ -30,7 +30,6 @@
#include "uscanf_p.h"
#include "uscanset.h"
#include "locbund.h"
#include "loccache.h"
#include "cmemory.h"
#include "ustr_imp.h"
@ -286,7 +285,7 @@ u_sscanf_double_handler(u_localized_string *input,
len = ufmt_min(len, info->fWidth);
/* get the formatter */
format = u_locbund_getNumberFormat(input->fBundle);
format = u_locbund_getNumberFormat(&input->fBundle, UNUM_DECIMAL);
/* handle error */
if(format == 0)
@ -331,7 +330,7 @@ u_sscanf_scientific_handler(u_localized_string *input,
len = ufmt_min(len, info->fWidth);
/* get the formatter */
format = u_locbund_getScientificFormat(input->fBundle);
format = u_locbund_getNumberFormat(&input->fBundle, UNUM_SCIENTIFIC);
/* handle error */
if(format == 0)
@ -385,8 +384,8 @@ u_sscanf_scidbl_handler(u_localized_string *input,
len = ufmt_min(len, info->fWidth);
/* get the formatters */
scientificFormat = u_locbund_getScientificFormat(input->fBundle);
genericFormat = u_locbund_getNumberFormat(input->fBundle);
scientificFormat = u_locbund_getNumberFormat(&input->fBundle, UNUM_SCIENTIFIC);
genericFormat = u_locbund_getNumberFormat(&input->fBundle, UNUM_DECIMAL);
/* handle error */
if(scientificFormat == 0 || genericFormat == 0)
@ -447,7 +446,7 @@ u_sscanf_integer_handler(u_localized_string *input,
len = ufmt_min(len, info->fWidth);
/* get the formatter */
format = u_locbund_getNumberFormat(input->fBundle);
format = u_locbund_getNumberFormat(&input->fBundle, UNUM_DECIMAL);
/* handle error */
if(format == 0)
@ -514,7 +513,7 @@ u_sscanf_currency_handler(u_localized_string *input,
len = ufmt_min(len, info->fWidth);
/* get the formatter */
format = u_locbund_getCurrencyFormat(input->fBundle);
format = u_locbund_getNumberFormat(&input->fBundle, UNUM_CURRENCY);
/* handle error */
if(format == 0)
@ -559,7 +558,7 @@ u_sscanf_percent_handler(u_localized_string *input,
len = ufmt_min(len, info->fWidth);
/* get the formatter */
format = u_locbund_getPercentFormat(input->fBundle);
format = u_locbund_getNumberFormat(&input->fBundle, UNUM_PERCENT);
/* handle error */
if(format == 0)
@ -604,7 +603,7 @@ u_sscanf_date_handler(u_localized_string *input,
len = ufmt_min(len, info->fWidth);
/* get the formatter */
format = u_locbund_getDateFormat(input->fBundle);
format = u_locbund_getDateFormat(&input->fBundle);
/* handle error */
if(format == 0)
@ -645,7 +644,7 @@ u_sscanf_time_handler(u_localized_string *input,
len = ufmt_min(len, info->fWidth);
/* get the formatter */
format = u_locbund_getTimeFormat(input->fBundle);
format = u_locbund_getTimeFormat(&input->fBundle);
/* handle error */
if(format == 0)
@ -743,7 +742,7 @@ u_sscanf_spellout_handler(u_localized_string *input,
len = ufmt_min(len, info->fWidth);
/* get the formatter */
format = u_locbund_getSpelloutFormat(input->fBundle);
format = u_locbund_getNumberFormat(&input->fBundle, UNUM_SPELLOUT);
/* handle error */
if(format == 0)
@ -1079,12 +1078,10 @@ u_vsscanf_u(const UChar *buffer,
if(locale == 0) {
locale = uloc_getDefault();
}
inStr.fBundle = u_loccache_get(locale);
if(inStr.fBundle == 0) {
if(u_locbund_init(&inStr.fBundle, locale) == 0) {
return 0;
}
inStr.fOwnBundle = FALSE;
/* iterate through the pattern */
for(;;) {
@ -1188,6 +1185,7 @@ u_vsscanf_u(const UChar *buffer,
/* just ignore unknown tags */
}
u_locbund_close(&inStr.fBundle);
/* return # of items converted */
return converted;

View File

@ -32,8 +32,7 @@ struct u_localized_string {
int32_t pos; /* Number of codeunits available to write to */
int32_t len; /* Maximum number of code units that can be written to output */
ULocaleBundle *fBundle; /* formatters */
UBool fOwnBundle; /* TRUE if fBundle should be deleted */
ULocaleBundle fBundle; /* formatters */
};
typedef struct u_localized_string u_localized_string;

View File

@ -22,7 +22,6 @@
#include "unicode/ustdio.h"
#include "ufile.h"
#include "unicode/uloc.h"
#include "loccache.h"
#include "unicode/ures.h"
#include "unicode/ucnv.h"
#include "cstring.h"
@ -53,28 +52,6 @@ static UBool hasICUData(const char *cp) {
}
U_CAPI UFILE* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
u_fopen(const char *filename,
const char *perm,
const char *locale,
const char *codepage)
{
UFILE *result;
FILE *systemFile = fopen(filename, perm);
if(systemFile == 0) {
return 0;
}
result = u_finit(systemFile, locale, codepage);
if (result) {
result->fOwnFile = TRUE;
}
return result;
}
U_CAPI UFILE* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
u_finit(FILE *f,
const char *locale,
@ -104,8 +81,7 @@ u_finit(FILE *f,
locale = uloc_getDefault();
}
result->fBundle = u_loccache_get(locale);
if(result->fBundle == 0) {
if(u_locbund_init(&result->fBundle, locale) == 0) {
/* DO NOT FCLOSE HERE! */
uprv_free(result);
return 0;
@ -140,6 +116,27 @@ u_finit(FILE *f,
return result;
}
U_CAPI UFILE* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
u_fopen(const char *filename,
const char *perm,
const char *locale,
const char *codepage)
{
UFILE *result;
FILE *systemFile = fopen(filename, perm);
if(systemFile == 0) {
return 0;
}
result = u_finit(systemFile, locale, codepage);
if (result) {
result->fOwnFile = TRUE;
}
return result;
}
U_CAPI void U_EXPORT2
u_fflush(UFILE *file)
@ -159,8 +156,7 @@ u_fclose(UFILE *file)
fclose(file->fFile);
#if !UCONFIG_NO_FORMATTING
if(file->fOwnBundle)
u_locbund_delete(file->fBundle);
u_locbund_close(&file->fBundle);
#endif
ucnv_close(file->fConverter);
@ -178,20 +174,16 @@ u_fgetfile( UFILE *f)
U_CAPI const char* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
u_fgetlocale( UFILE *file)
{
return file->fBundle->fLocale;
return file->fBundle.fLocale;
}
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
u_fsetlocale(const char *locale,
UFILE *file)
{
if(file->fOwnBundle)
u_locbund_delete(file->fBundle);
u_locbund_close(&file->fBundle);
file->fBundle = u_loccache_get(locale);
file->fOwnBundle = FALSE;
return file->fBundle == 0 ? -1 : 0;
return u_locbund_init(&file->fBundle, locale) == 0 ? -1 : 0;
}
#endif
@ -219,7 +211,7 @@ u_fsetcodepage( const char *codepage,
#if !UCONFIG_NO_FORMATTING
/* if the codepage is 0, use the default for the locale */
if(codepage == 0) {
codepage = uprv_defaultCodePageForLocale(file->fBundle->fLocale);
codepage = uprv_defaultCodePageForLocale(file->fBundle.fLocale);
/* if the codepage is still 0, fall back on the default codepage */
}

View File

@ -49,8 +49,7 @@ struct UFILE {
UBool fOwnFile; /* TRUE if fFile should be closed */
#if !UCONFIG_NO_FORMATTING
ULocaleBundle *fBundle; /* formatters */
UBool fOwnBundle; /* TRUE if fBundle should be deleted */
ULocaleBundle fBundle; /* formatters */
#endif
UConverter *fConverter; /* for codeset conversion */

View File

@ -86,7 +86,7 @@
typedef struct u_printf_info {
ufmt_type_info info;
u_printf_handler handler;
u_printf_handler *handler;
} u_printf_info;
#define UPRINTF_NUM_FMT_HANDLERS 108
@ -101,12 +101,21 @@ typedef struct u_printf_info {
static const UChar gNullStr[] = {0x28, 0x6E, 0x75, 0x6C, 0x6C, 0x29, 0}; /* "(null)" */
static const UChar gSpaceStr[] = {0x20, 0}; /* " " */
static int32_t U_EXPORT2
u_printf_write(void *context,
const UChar *str,
int32_t count)
{
return u_file_write(str, count, (UFILE *)context);
}
static int32_t
u_printf_pad_and_justify(UFILE *output,
u_printf_pad_and_justify(void *context,
const u_printf_spec_info *info,
const UChar *result,
int32_t resultLen)
{
UFILE *output = (UFILE *)context;
int32_t written, i;
/* pad and justify, if needed */
@ -168,22 +177,25 @@ u_printf_set_sign(UNumberFormat *format,
/* handle a '%' */
static int32_t
u_printf_simple_percent_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_simple_percent_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
static const UChar PERCENT[] = { UP_PERCENT };
/* put a single '%' onto the output */
u_fputc(0x0025, output);
/* we wrote one character */
return 1;
return handler->write(context, PERCENT, 1);
}
/* handle 's' */
static int32_t
u_printf_string_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_string_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
UChar *s;
UChar buffer[UFMT_DEFAULT_BUFFER_SIZE];
@ -218,11 +230,11 @@ u_printf_string_handler(UFILE *output,
/* precision takes precedence over width */
/* determine if the string should be truncated */
if(info->fPrecision != -1 && len > info->fPrecision) {
written = u_file_write(s, info->fPrecision, output);
written = handler->write(context, s, info->fPrecision);
}
/* determine if the string should be padded */
else {
written = u_printf_pad_and_justify(output, info, s, len);
written = handler->pad_and_justify(context, info, s, len);
}
/* clean up */
@ -234,9 +246,11 @@ u_printf_string_handler(UFILE *output,
}
static int32_t
u_printf_char_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_char_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
UChar s[UTF_MAX_CHAR_LENGTH+1];
int32_t len = 1, written;
@ -256,54 +270,46 @@ u_printf_char_handler(UFILE *output,
/* precision takes precedence over width */
/* determine if the string should be truncated */
if(info->fPrecision != -1 && len > info->fPrecision) {
written = u_file_write(s, info->fPrecision, output);
written = handler->write(context, s, info->fPrecision);
}
else {
/* determine if the string should be padded */
written = u_printf_pad_and_justify(output, info, s, len);
written = handler->pad_and_justify(context, info, s, len);
}
return written;
}
static int32_t
u_printf_double_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_double_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
double num = (double) (args[0].doubleValue);
UNumberFormat *format;
UChar result [UPRINTF_BUFFER_SIZE];
UNumberFormat *format;
UChar result [UPRINTF_BUFFER_SIZE];
int32_t minDecimalDigits;
int32_t maxDecimalDigits;
UErrorCode status = U_ZERO_ERROR;
UErrorCode status = U_ZERO_ERROR;
/* mask off any necessary bits */
/* if(! info->fIsLongDouble)
num &= DBL_MAX;*/
/* get the formatter */
format = u_locbund_getNumberFormat(output->fBundle);
format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL);
/* handle error */
if(format == 0)
return 0;
/* set the appropriate flags on the formatter */
/* clone the output's bundle if it isn't owned */
if(! output->fOwnBundle) {
output->fBundle = u_locbund_clone(output->fBundle);
output->fOwnBundle = TRUE;
format = u_locbund_getNumberFormat(output->fBundle);
}
/* set the number of decimal digits */
/* save the formatter's state */
minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS);
maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS);
/* set the appropriate flags and number of decimal digits on the formatter */
if(info->fPrecision != -1) {
/* set the # of decimal digits */
unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision);
@ -332,14 +338,16 @@ u_printf_double_handler(UFILE *output,
unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits);
unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits);
return u_printf_pad_and_justify(output, info, result, u_strlen(result));
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
/* HSYS */
static int32_t
u_printf_integer_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_integer_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
long num = (long) (args[0].intValue);
UNumberFormat *format;
@ -354,7 +362,7 @@ u_printf_integer_handler(UFILE *output,
num &= UINT32_MAX;
/* get the formatter */
format = u_locbund_getNumberFormat(output->fBundle);
format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL);
/* handle error */
if(format == 0)
@ -364,13 +372,6 @@ u_printf_integer_handler(UFILE *output,
/* set the minimum integer digits */
if(info->fPrecision != -1) {
/* clone the output's bundle if it isn't owned */
if(! output->fOwnBundle) {
output->fBundle = u_locbund_clone(output->fBundle);
output->fOwnBundle = TRUE;
format = u_locbund_getNumberFormat(output->fBundle);
}
/* set the minimum # of digits */
minDigits = unum_getAttribute(format, UNUM_MIN_INTEGER_DIGITS);
unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, info->fPrecision);
@ -378,13 +379,6 @@ u_printf_integer_handler(UFILE *output,
/* set whether to show the sign */
if(info->fShowSign) {
/* clone the output's bundle if it isn't owned */
if(! output->fOwnBundle) {
output->fBundle = u_locbund_clone(output->fBundle);
output->fOwnBundle = TRUE;
format = u_locbund_getNumberFormat(output->fBundle);
}
u_printf_set_sign(format, info, &status);
}
@ -396,13 +390,15 @@ u_printf_integer_handler(UFILE *output,
unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, minDigits);
}
return u_printf_pad_and_justify(output, info, result, u_strlen(result));
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
static int32_t
u_printf_hex_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_hex_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
long num = (long) (args[0].intValue);
UChar result[UPRINTF_BUFFER_SIZE];
@ -429,13 +425,15 @@ u_printf_hex_handler(UFILE *output,
len += 2;
}
return u_printf_pad_and_justify(output, info, result, len);
return handler->pad_and_justify(context, info, result, len);
}
static int32_t
u_printf_octal_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_octal_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
long num = (long) (args[0].intValue);
UChar result[UPRINTF_BUFFER_SIZE];
@ -461,13 +459,15 @@ u_printf_octal_handler(UFILE *output,
len += 1;
}
return u_printf_pad_and_justify(output, info, result, len);
return handler->pad_and_justify(context, info, result, len);
}
static int32_t
u_printf_uinteger_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_uinteger_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
u_printf_spec_info uint_info;
ufmt_args uint_args;
@ -481,13 +481,15 @@ u_printf_uinteger_handler(UFILE *output,
/* Get around int32_t limitations */
uint_args.doubleValue = ((double) ((uint32_t) (uint_args.intValue)));
return u_printf_double_handler(output, &uint_info, &uint_args);
return u_printf_double_handler(handler, context, formatBundle, &uint_info, &uint_args);
}
static int32_t
u_printf_pointer_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_pointer_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
long num = (long) (args[0].intValue);
UChar result[UPRINTF_BUFFER_SIZE];
@ -497,13 +499,15 @@ u_printf_pointer_handler(UFILE *output,
/* format the pointer in hex */
ufmt_ltou(result, &len, num, 16, TRUE, info->fPrecision);
return u_printf_pad_and_justify(output, info, result, len);
return handler->pad_and_justify(context, info, result, len);
}
static int32_t
u_printf_scientific_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_scientific_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
double num = (double) (args[0].doubleValue);
UNumberFormat *format;
@ -521,7 +525,7 @@ u_printf_scientific_handler(UFILE *output,
num &= DBL_MAX;*/
/* get the formatter */
format = u_locbund_getScientificFormat(output->fBundle);
format = u_locbund_getNumberFormat(formatBundle, UNUM_SCIENTIFIC);
/* handle error */
if(format == 0)
@ -529,13 +533,6 @@ u_printf_scientific_handler(UFILE *output,
/* set the appropriate flags on the formatter */
/* clone the output's bundle if it isn't owned */
if(! output->fOwnBundle) {
output->fBundle = u_locbund_clone(output->fBundle);
output->fOwnBundle = TRUE;
format = u_locbund_getScientificFormat(output->fBundle);
}
srcLen = unum_getSymbol(format,
UNUM_EXPONENTIAL_SYMBOL,
srcExpBuf,
@ -546,13 +543,13 @@ u_printf_scientific_handler(UFILE *output,
if (info->fSpec == (UChar)0x65 /* e */) {
expLen = u_strToLower(expBuf, (int32_t)sizeof(expBuf),
srcExpBuf, srcLen,
output->fBundle->fLocale,
formatBundle->fLocale,
&status);
}
else {
expLen = u_strToUpper(expBuf, (int32_t)sizeof(expBuf),
srcExpBuf, srcLen,
output->fBundle->fLocale,
formatBundle->fLocale,
&status);
}
@ -562,12 +559,11 @@ u_printf_scientific_handler(UFILE *output,
expLen,
&status);
/* set the number of decimal digits */
/* save the formatter's state */
minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS);
maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS);
/* set the appropriate flags and number of decimal digits on the formatter */
if(info->fPrecision != -1) {
/* set the # of decimal digits */
unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision);
@ -604,13 +600,15 @@ u_printf_scientific_handler(UFILE *output,
srcLen,
&status);*/
return u_printf_pad_and_justify(output, info, result, u_strlen(result));
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
static int32_t
u_printf_date_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_date_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
UDate num = (UDate) (args[0].dateValue);
UDateFormat *format;
@ -619,7 +617,7 @@ u_printf_date_handler(UFILE *output,
/* get the formatter */
format = u_locbund_getDateFormat(output->fBundle);
format = u_locbund_getDateFormat(formatBundle);
/* handle error */
if(format == 0)
@ -628,22 +626,24 @@ u_printf_date_handler(UFILE *output,
/* format the date */
udat_format(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status);
return u_printf_pad_and_justify(output, info, result, u_strlen(result));
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
static int32_t
u_printf_time_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_time_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
UDate num = (UDate) (args[0].dateValue);
UDateFormat *format;
UChar result [UPRINTF_BUFFER_SIZE];
UErrorCode status = U_ZERO_ERROR;
UDate num = (UDate) (args[0].dateValue);
UDateFormat *format;
UChar result [UPRINTF_BUFFER_SIZE];
UErrorCode status = U_ZERO_ERROR;
/* get the formatter */
format = u_locbund_getTimeFormat(output->fBundle);
format = u_locbund_getTimeFormat(formatBundle);
/* handle error */
if(format == 0)
@ -652,13 +652,15 @@ u_printf_time_handler(UFILE *output,
/* format the time */
udat_format(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status);
return u_printf_pad_and_justify(output, info, result, u_strlen(result));
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
static int32_t
u_printf_percent_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_percent_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
double num = (double) (args[0].doubleValue);
UNumberFormat *format;
@ -673,27 +675,17 @@ u_printf_percent_handler(UFILE *output,
num &= DBL_MAX;*/
/* get the formatter */
format = u_locbund_getPercentFormat(output->fBundle);
format = u_locbund_getNumberFormat(formatBundle, UNUM_PERCENT);
/* handle error */
if(format == 0)
return 0;
/* set the appropriate flags on the formatter */
/* clone the output's bundle if it isn't owned */
if(! output->fOwnBundle) {
output->fBundle = u_locbund_clone(output->fBundle);
output->fOwnBundle = TRUE;
format = u_locbund_getPercentFormat(output->fBundle);
}
/* set the number of decimal digits */
/* save the formatter's state */
minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS);
maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS);
/* set the appropriate flags and number of decimal digits on the formatter */
if(info->fPrecision != -1) {
/* set the # of decimal digits */
unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision);
@ -722,13 +714,15 @@ u_printf_percent_handler(UFILE *output,
unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits);
unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits);
return u_printf_pad_and_justify(output, info, result, u_strlen(result));
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
static int32_t
u_printf_currency_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_currency_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
double num = (double) (args[0].doubleValue);
UNumberFormat *format;
@ -743,27 +737,17 @@ u_printf_currency_handler(UFILE *output,
num &= DBL_MAX;*/
/* get the formatter */
format = u_locbund_getCurrencyFormat(output->fBundle);
format = u_locbund_getNumberFormat(formatBundle, UNUM_CURRENCY);
/* handle error */
if(format == 0)
return 0;
/* set the appropriate flags on the formatter */
/* clone the output's bundle if it isn't owned */
if(! output->fOwnBundle) {
output->fBundle = u_locbund_clone(output->fBundle);
output->fOwnBundle = TRUE;
format = u_locbund_getCurrencyFormat(output->fBundle);
}
/* set the number of decimal digits */
/* save the formatter's state */
minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS);
maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS);
/* set the appropriate flags and number of decimal digits on the formatter */
if(info->fPrecision != -1) {
/* set the # of decimal digits */
unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision);
@ -792,13 +776,15 @@ u_printf_currency_handler(UFILE *output,
unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits);
unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits);
return u_printf_pad_and_justify(output, info, result, u_strlen(result));
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
static int32_t
u_printf_ustring_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_ustring_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
int32_t len, written;
const UChar *arg = (const UChar*)(args[0].ptrValue);
@ -815,20 +801,22 @@ u_printf_ustring_handler(UFILE *output,
/* precision takes precedence over width */
/* determine if the string should be truncated */
if(info->fPrecision != -1 && len > info->fPrecision) {
written = u_file_write(arg, info->fPrecision, output);
written = handler->write(context, arg, info->fPrecision);
}
else {
/* determine if the string should be padded */
written = u_printf_pad_and_justify(output, info, arg, len);
written = handler->pad_and_justify(context, info, arg, len);
}
return written;
}
static int32_t
u_printf_uchar_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_uchar_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
int32_t written = 0;
UChar arg = (UChar)(args[0].intValue);
@ -845,16 +833,18 @@ u_printf_uchar_handler(UFILE *output,
}
else {
/* determine if the string should be padded */
written = u_printf_pad_and_justify(output, info, &arg, 1);
written = handler->pad_and_justify(context, info, &arg, 1);
}
return written;
}
static int32_t
u_printf_scidbl_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_scidbl_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
u_printf_spec_info scidbl_info;
double num = args[0].doubleValue;
@ -868,7 +858,7 @@ u_printf_scidbl_handler(UFILE *output,
scidbl_info.fSpec = 0x0066;
scidbl_info.fPrecision = 0;
/* call the double handler */
return u_printf_double_handler(output, &scidbl_info, args);
return u_printf_double_handler(handler, context, formatBundle, &scidbl_info, args);
}
else if(num < 0.0001 || (scidbl_info.fPrecision < 1 && 1000000.0 <= num)
|| (scidbl_info.fPrecision != -1 && num > uprv_pow10(scidbl_info.fPrecision)))
@ -876,20 +866,22 @@ u_printf_scidbl_handler(UFILE *output,
/* use 'e' or 'E' notation */
scidbl_info.fSpec = scidbl_info.fSpec - 2;
/* call the scientific handler */
return u_printf_scientific_handler(output, &scidbl_info, args);
return u_printf_scientific_handler(handler, context, formatBundle, &scidbl_info, args);
}
else {
/* use 'f' notation */
scidbl_info.fSpec = 0x0066;
/* call the double handler */
return u_printf_double_handler(output, &scidbl_info, args);
return u_printf_double_handler(handler, context, formatBundle, &scidbl_info, args);
}
}
static int32_t
u_printf_count_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_count_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
int *count = (int*)(args[0].ptrValue);
@ -901,9 +893,11 @@ u_printf_count_handler(UFILE *output,
}
static int32_t
u_printf_spellout_handler(UFILE *output,
const u_printf_spec_info *info,
const ufmt_args *args)
u_printf_spellout_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args)
{
double num = (double) (args[0].doubleValue);
UNumberFormat *format;
@ -918,27 +912,17 @@ u_printf_spellout_handler(UFILE *output,
num &= DBL_MAX;*/
/* get the formatter */
format = u_locbund_getSpelloutFormat(output->fBundle);
format = u_locbund_getNumberFormat(formatBundle, UNUM_SPELLOUT);
/* handle error */
if(format == 0)
return 0;
/* set the appropriate flags on the formatter */
/* clone the output's bundle if it isn't owned */
if(! output->fOwnBundle) {
output->fBundle = u_locbund_clone(output->fBundle);
output->fOwnBundle = TRUE;
format = u_locbund_getSpelloutFormat(output->fBundle);
}
/* set the number of decimal digits */
/* save the formatter's state */
minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS);
maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS);
/* set the appropriate flags and number of decimal digits on the formatter */
if(info->fPrecision != -1) {
/* set the # of decimal digits */
unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision);
@ -967,7 +951,7 @@ u_printf_spellout_handler(UFILE *output,
unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits);
unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits);
return u_printf_pad_and_justify(output, info, result, u_strlen(result));
return handler->pad_and_justify(context, info, result, u_strlen(result));
}
U_CAPI int32_t U_EXPORT2
@ -1075,6 +1059,11 @@ static const u_printf_info g_u_printf_infos[UPRINTF_NUM_FMT_HANDLERS] = {
UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY, UFMT_EMPTY,
};
static const u_printf_stream_handler g_stream_handler = {
u_printf_write,
u_printf_pad_and_justify
};
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
u_vfprintf_u( UFILE *f,
const UChar *patternSpecification,
@ -1088,7 +1077,7 @@ u_vfprintf_u( UFILE *f,
ufmt_args args;
u_printf_spec spec;
ufmt_type_info info;
u_printf_handler handler;
u_printf_handler *handler;
/* iterate through the pattern */
for(;;) {
@ -1102,7 +1091,7 @@ u_vfprintf_u( UFILE *f,
/* write any characters before the '%' */
if(patCount > 0) {
written += u_file_write(alias - patCount, patCount, f);
written += (*g_stream_handler.write)(f, alias - patCount, patCount);
}
/* break if at end of string */
@ -1153,49 +1142,38 @@ u_vfprintf_u( UFILE *f,
info = g_u_printf_infos[ handlerNum ].info;
if(info > ufmt_simple_percent) {
switch(info) {
case ufmt_count:
/* set the spec's width to the # of chars written */
spec.fInfo.fWidth = written;
case ufmt_char:
case ufmt_uchar:
case ufmt_int:
args.intValue = va_arg(ap, int);
break;
case ufmt_wchar:
args.wcharValue = va_arg(ap, wchar_t);
break;
case ufmt_string:
args.ptrValue = va_arg(ap, char*);
break;
case ufmt_wstring:
args.ptrValue = va_arg(ap, wchar_t*);
break;
case ufmt_ustring:
args.ptrValue = va_arg(ap, UChar*);
break;
case ufmt_pointer:
args.ptrValue = va_arg(ap, void*);
break;
case ufmt_float:
args.floatValue = (float) va_arg(ap, double);
break;
case ufmt_double:
args.doubleValue = va_arg(ap, double);
break;
case ufmt_date:
args.dateValue = va_arg(ap, UDate);
break;
default:
break; /* Should never get here */
}
@ -1204,16 +1182,16 @@ u_vfprintf_u( UFILE *f,
/* call the handler function */
handler = g_u_printf_infos[ handlerNum ].handler;
if(handler != 0) {
written += (*handler)(f, &spec.fInfo, &args);
written += (*handler)(&g_stream_handler, f, &f->fBundle, &spec.fInfo, &args);
}
else {
/* just echo unknown tags */
written += u_file_write(alias, patCount, f);
written += (*g_stream_handler.write)(f, alias, patCount);
}
}
else {
/* just echo unknown tags */
written += u_file_write(alias, patCount, f);
written += (*g_stream_handler.write)(f, alias, patCount);
}
/* update the pointer in pattern and continue */
@ -1225,3 +1203,4 @@ u_vfprintf_u( UFILE *f,
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View File

@ -25,11 +25,12 @@
#include "unicode/ustdio.h"
#include "ufmt_cmn.h"
#include "locbund.h"
/**
* Struct encapsulating a single uprintf format specification.
*/
struct u_printf_spec_info {
typedef struct u_printf_spec_info {
UChar fSpec; /* Conversion specification */
int32_t fPrecision; /* Precision */
@ -47,9 +48,25 @@ struct u_printf_spec_info {
UBool fIsShort; /* h flag */
UBool fIsLong; /* l flag */
UBool fIsLongLong; /* ll flag */
};
typedef struct u_printf_spec_info u_printf_spec_info;
} u_printf_spec_info;
typedef struct u_printf_stream_handler u_printf_stream_handler;
typedef int32_t U_EXPORT2
u_printf_write_stream(void *context,
const UChar *str,
int32_t count);
typedef int32_t U_EXPORT2
u_printf_pad_and_justify_stream(void *context,
const u_printf_spec_info *info,
const UChar *result,
int32_t resultLen);
typedef struct u_printf_stream_handler {
u_printf_write_stream *write;
u_printf_pad_and_justify_stream *pad_and_justify;
} u_printf_stream_handler;
/**
* A u_printf handler function.
@ -61,9 +78,12 @@ typedef struct u_printf_spec_info u_printf_spec_info;
* @param args A pointer to the argument data
* @return The number of Unicode characters written to <TT>stream</TT>.
*/
typedef int32_t (*u_printf_handler) (UFILE *stream,
const u_printf_spec_info *info,
const ufmt_args *args);
typedef int32_t U_EXPORT2
u_printf_handler(const u_printf_stream_handler *handler,
void *context,
ULocaleBundle *formatBundle,
const u_printf_spec_info *info,
const ufmt_args *args);
#endif /* #if !UCONFIG_NO_FORMATTING */

View File

@ -286,7 +286,7 @@ u_scanf_double_handler(UFILE *stream,
len = ufmt_min(len, info->fWidth);
/* get the formatter */
format = u_locbund_getNumberFormat(stream->fBundle);
format = u_locbund_getNumberFormat(&stream->fBundle, UNUM_DECIMAL);
/* handle error */
if(format == 0)
@ -334,7 +334,7 @@ u_scanf_scientific_handler(UFILE *stream,
len = ufmt_min(len, info->fWidth);
/* get the formatter */
format = u_locbund_getScientificFormat(stream->fBundle);
format = u_locbund_getNumberFormat(&stream->fBundle, UNUM_SCIENTIFIC);
/* handle error */
if(format == 0)
@ -391,8 +391,8 @@ u_scanf_scidbl_handler(UFILE *stream,
len = ufmt_min(len, info->fWidth);
/* get the formatters */
scientificFormat = u_locbund_getScientificFormat(stream->fBundle);
genericFormat = u_locbund_getNumberFormat(stream->fBundle);
scientificFormat = u_locbund_getNumberFormat(&stream->fBundle, UNUM_SCIENTIFIC);
genericFormat = u_locbund_getNumberFormat(&stream->fBundle, UNUM_DECIMAL);
/* handle error */
if(scientificFormat == 0 || genericFormat == 0)
@ -457,7 +457,7 @@ u_scanf_integer_handler(UFILE *stream,
len = ufmt_min(len, info->fWidth);
/* get the formatter */
format = u_locbund_getNumberFormat(stream->fBundle);
format = u_locbund_getNumberFormat(&stream->fBundle, UNUM_DECIMAL);
/* handle error */
if(format == 0)
@ -527,7 +527,7 @@ u_scanf_currency_handler(UFILE *stream,
len = ufmt_min(len, info->fWidth);
/* get the formatter */
format = u_locbund_getCurrencyFormat(stream->fBundle);
format = u_locbund_getNumberFormat(&stream->fBundle, UNUM_CURRENCY);
/* handle error */
if(format == 0)
@ -575,7 +575,7 @@ u_scanf_percent_handler(UFILE *stream,
len = ufmt_min(len, info->fWidth);
/* get the formatter */
format = u_locbund_getPercentFormat(stream->fBundle);
format = u_locbund_getNumberFormat(&stream->fBundle, UNUM_PERCENT);
/* handle error */
if(format == 0)
@ -623,7 +623,7 @@ u_scanf_date_handler(UFILE *stream,
len = ufmt_min(len, info->fWidth);
/* get the formatter */
format = u_locbund_getDateFormat(stream->fBundle);
format = u_locbund_getDateFormat(&stream->fBundle);
/* handle error */
if(format == 0)
@ -667,7 +667,7 @@ u_scanf_time_handler(UFILE *stream,
len = ufmt_min(len, info->fWidth);
/* get the formatter */
format = u_locbund_getTimeFormat(stream->fBundle);
format = u_locbund_getTimeFormat(&stream->fBundle);
/* handle error */
if(format == 0)
@ -768,7 +768,7 @@ u_scanf_spellout_handler(UFILE *stream,
len = ufmt_min(len, info->fWidth);
/* get the formatter */
format = u_locbund_getSpelloutFormat(stream->fBundle);
format = u_locbund_getNumberFormat(&stream->fBundle, UNUM_SPELLOUT);
/* handle error */
if(format == 0)

View File

@ -141,9 +141,6 @@
<File
RelativePath=".\locbund.c">
</File>
<File
RelativePath=".\loccache.c">
</File>
<File
RelativePath=".\sprintf.c">
</File>
@ -196,9 +193,6 @@
<File
RelativePath=".\locbund.h">
</File>
<File
RelativePath=".\loccache.h">
</File>
<File
RelativePath=".\sprintf.h">
</File>