ICU-3499 Fix printf va_list handling to get around some os/400 crashing issues

X-SVN-Rev: 15529
This commit is contained in:
George Rhoten 2004-05-25 16:59:00 +00:00
parent b37ec384d0
commit e95cc00b7d
4 changed files with 24 additions and 72 deletions

View file

@ -263,7 +263,7 @@
#define u_memset u_memset_3_0
#define u_parseMessage u_parseMessage_3_0
#define u_parseMessageWithError u_parseMessageWithError_3_0
#define u_printf_print_spec u_printf_print_spec_3_0
#define u_printf_parse u_printf_parse_3_0
#define u_releaseDefaultConverter u_releaseDefaultConverter_3_0
#define u_scanf_parse u_scanf_parse_3_0
#define u_setAtomicIncDecFunctions u_setAtomicIncDecFunctions_3_0

View file

@ -31,14 +31,6 @@
#include "cmemory.h"
#include <ctype.h>
typedef struct u_localized_print_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 */
} u_localized_print_string;
/* u_minstrncpy copies the minimum number of code units of (count or output->available) */
static int32_t
u_sprintf_write(void *context,
@ -222,9 +214,6 @@ u_vsnprintf_u(UChar *buffer,
const UChar *patternSpecification,
va_list ap)
{
const UChar *alias = patternSpecification; /* alias the pattern */
const UChar *lastAlias;
int32_t patCount;
int32_t written = 0; /* haven't written anything yet */
u_localized_print_string outStr;
@ -241,31 +230,8 @@ u_vsnprintf_u(UChar *buffer,
return 0;
}
/* iterate through the pattern */
while(outStr.available > 0) {
/* find the next '%' */
lastAlias = alias;
while(*alias != UP_PERCENT && *alias != 0x0000) {
alias++;
}
/* write any characters before the '%' */
if(alias > lastAlias) {
written += (*g_sprintf_stream_handler.write)(&outStr, lastAlias, (int32_t)(alias - lastAlias));
}
/* break if at end of string */
if(*alias == 0x0000) {
break;
}
/* parse and print the specifier */
patCount = u_printf_print_spec(&g_sprintf_stream_handler, alias, &outStr, &outStr.fBundle, (int32_t)(alias - lastAlias), &written, (va_list*)&ap);
/* update the pointer in pattern and continue */
alias += patCount;
}
/* parse and print the whole format string */
u_printf_parse(&g_sprintf_stream_handler, patternSpecification, &outStr, &outStr, &outStr.fBundle, &written, ap);
/* Terminate the buffer, if there's room. */
if (outStr.available > 0) {

View file

@ -149,36 +149,10 @@ u_vfprintf_u( UFILE *f,
const UChar *patternSpecification,
va_list ap)
{
const UChar *alias = patternSpecification; /* alias the pattern */
const UChar *lastAlias;
int32_t patCount;
int32_t written = 0; /* haven't written anything yet */
/* iterate through the pattern */
for(;;) {
/* find the next '%' */
lastAlias = alias;
while(*alias != UP_PERCENT && *alias != 0x0000) {
alias++;
}
/* write any characters before the '%' */
if(alias > lastAlias) {
written += (*g_stream_handler.write)(f, lastAlias, (int32_t)(alias - lastAlias));
}
/* break if at end of string */
if(*alias == 0x0000) {
break;
}
/* parse and print the specifier */
patCount = u_printf_print_spec(&g_stream_handler, alias, f, &f->str.fBundle, (int32_t)(alias - lastAlias), &written, (va_list*)&ap);
/* update the pointer in pattern and continue */
alias += patCount;
}
/* parse and print the whole format string */
u_printf_parse(&g_stream_handler, patternSpecification, f, NULL, &f->str.fBundle, &written, ap);
/* return # of UChars written */
return written;

View file

@ -65,6 +65,15 @@ typedef struct u_printf_stream_handler {
u_printf_pad_and_justify_stream *pad_and_justify;
} u_printf_stream_handler;
/* Used by sprintf */
typedef struct u_localized_print_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 */
} u_localized_print_string;
#define UP_PERCENT 0x0025
/**
@ -72,16 +81,19 @@ typedef struct u_printf_stream_handler {
* @param fmt A pointer to a '%' character in a u_printf format specification.
* @param spec A pointer to a <TT>u_printf_spec</TT> to receive the parsed
* format specifier.
* @param locStringContext If present, will make sure that it will only write
* to the buffer when space is available. It's done this way because
* va_list sometimes can't be passed by pointer.
* @return The number of characters contained in this specifier.
*/
U_CFUNC int32_t
u_printf_print_spec(const u_printf_stream_handler *streamHandler,
const UChar *fmt,
void *context,
ULocaleBundle *formatBundle,
int32_t patCount,
int32_t *written,
va_list *ap);
u_printf_parse(const u_printf_stream_handler *streamHandler,
const UChar *fmt,
void *context,
u_localized_print_string *locStringContext,
ULocaleBundle *formatBundle,
int32_t *written,
va_list ap);
#endif /* #if !UCONFIG_NO_FORMATTING */