mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-09 15:27:38 +00:00
ICU-3499 Fix printf va_list handling to get around some os/400 crashing issues
X-SVN-Rev: 15529
This commit is contained in:
parent
b37ec384d0
commit
e95cc00b7d
4 changed files with 24 additions and 72 deletions
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue