intl/icu/source/io/sprintf.c

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /*
michael@0 2 ******************************************************************************
michael@0 3 *
michael@0 4 * Copyright (C) 2001-2008, International Business Machines
michael@0 5 * Corporation and others. All Rights Reserved.
michael@0 6 *
michael@0 7 ******************************************************************************
michael@0 8 *
michael@0 9 * File sprintf.c
michael@0 10 *
michael@0 11 * Modification History:
michael@0 12 *
michael@0 13 * Date Name Description
michael@0 14 * 02/08/2001 george Creation. Copied from uprintf.c
michael@0 15 * 03/27/2002 Mark Schneckloth Many fixes regarding alignment, null termination
michael@0 16 * (mschneckloth@atomz.com) and other various problems.
michael@0 17 * 08/07/2003 george Reunify printf implementations
michael@0 18 *******************************************************************************
michael@0 19 */
michael@0 20
michael@0 21 #include "unicode/utypes.h"
michael@0 22
michael@0 23 #if !UCONFIG_NO_FORMATTING
michael@0 24
michael@0 25 #include "unicode/ustdio.h"
michael@0 26 #include "unicode/ustring.h"
michael@0 27 #include "unicode/putil.h"
michael@0 28
michael@0 29 #include "uprintf.h"
michael@0 30 #include "locbund.h"
michael@0 31
michael@0 32 #include "cmemory.h"
michael@0 33 #include <ctype.h>
michael@0 34
michael@0 35 /* u_minstrncpy copies the minimum number of code units of (count or output->available) */
michael@0 36 static int32_t
michael@0 37 u_sprintf_write(void *context,
michael@0 38 const UChar *str,
michael@0 39 int32_t count)
michael@0 40 {
michael@0 41 u_localized_print_string *output = (u_localized_print_string *)context;
michael@0 42 int32_t size = ufmt_min(count, output->available);
michael@0 43
michael@0 44 u_strncpy(output->str + (output->len - output->available), str, size);
michael@0 45 output->available -= size;
michael@0 46 return size;
michael@0 47 }
michael@0 48
michael@0 49 static int32_t
michael@0 50 u_sprintf_pad_and_justify(void *context,
michael@0 51 const u_printf_spec_info *info,
michael@0 52 const UChar *result,
michael@0 53 int32_t resultLen)
michael@0 54 {
michael@0 55 u_localized_print_string *output = (u_localized_print_string *)context;
michael@0 56 int32_t written = 0;
michael@0 57 int32_t lengthOfResult = resultLen;
michael@0 58
michael@0 59 resultLen = ufmt_min(resultLen, output->available);
michael@0 60
michael@0 61 /* pad and justify, if needed */
michael@0 62 if(info->fWidth != -1 && resultLen < info->fWidth) {
michael@0 63 int32_t paddingLeft = info->fWidth - resultLen;
michael@0 64 int32_t outputPos = output->len - output->available;
michael@0 65
michael@0 66 if (paddingLeft + resultLen > output->available) {
michael@0 67 paddingLeft = output->available - resultLen;
michael@0 68 if (paddingLeft < 0) {
michael@0 69 paddingLeft = 0;
michael@0 70 }
michael@0 71 /* paddingLeft = output->available - resultLen;*/
michael@0 72 }
michael@0 73 written += paddingLeft;
michael@0 74
michael@0 75 /* left justify */
michael@0 76 if(info->fLeft) {
michael@0 77 written += u_sprintf_write(output, result, resultLen);
michael@0 78 u_memset(&output->str[outputPos + resultLen], info->fPadChar, paddingLeft);
michael@0 79 output->available -= paddingLeft;
michael@0 80 }
michael@0 81 /* right justify */
michael@0 82 else {
michael@0 83 u_memset(&output->str[outputPos], info->fPadChar, paddingLeft);
michael@0 84 output->available -= paddingLeft;
michael@0 85 written += u_sprintf_write(output, result, resultLen);
michael@0 86 }
michael@0 87 }
michael@0 88 /* just write the formatted output */
michael@0 89 else {
michael@0 90 written = u_sprintf_write(output, result, resultLen);
michael@0 91 }
michael@0 92
michael@0 93 if (written >= 0 && lengthOfResult > written) {
michael@0 94 return lengthOfResult;
michael@0 95 }
michael@0 96
michael@0 97 return written;
michael@0 98 }
michael@0 99
michael@0 100 U_CAPI int32_t U_EXPORT2
michael@0 101 u_sprintf(UChar *buffer,
michael@0 102 const char *patternSpecification,
michael@0 103 ... )
michael@0 104 {
michael@0 105 va_list ap;
michael@0 106 int32_t written;
michael@0 107
michael@0 108 va_start(ap, patternSpecification);
michael@0 109 written = u_vsnprintf(buffer, INT32_MAX, patternSpecification, ap);
michael@0 110 va_end(ap);
michael@0 111
michael@0 112 return written;
michael@0 113 }
michael@0 114
michael@0 115 U_CAPI int32_t U_EXPORT2
michael@0 116 u_sprintf_u(UChar *buffer,
michael@0 117 const UChar *patternSpecification,
michael@0 118 ... )
michael@0 119 {
michael@0 120 va_list ap;
michael@0 121 int32_t written;
michael@0 122
michael@0 123 va_start(ap, patternSpecification);
michael@0 124 written = u_vsnprintf_u(buffer, INT32_MAX, patternSpecification, ap);
michael@0 125 va_end(ap);
michael@0 126
michael@0 127 return written;
michael@0 128 }
michael@0 129
michael@0 130 U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
michael@0 131 u_vsprintf(UChar *buffer,
michael@0 132 const char *patternSpecification,
michael@0 133 va_list ap)
michael@0 134 {
michael@0 135 return u_vsnprintf(buffer, INT32_MAX, patternSpecification, ap);
michael@0 136 }
michael@0 137
michael@0 138 U_CAPI int32_t U_EXPORT2
michael@0 139 u_snprintf(UChar *buffer,
michael@0 140 int32_t count,
michael@0 141 const char *patternSpecification,
michael@0 142 ... )
michael@0 143 {
michael@0 144 va_list ap;
michael@0 145 int32_t written;
michael@0 146
michael@0 147 va_start(ap, patternSpecification);
michael@0 148 written = u_vsnprintf(buffer, count, patternSpecification, ap);
michael@0 149 va_end(ap);
michael@0 150
michael@0 151 return written;
michael@0 152 }
michael@0 153
michael@0 154 U_CAPI int32_t U_EXPORT2
michael@0 155 u_snprintf_u(UChar *buffer,
michael@0 156 int32_t count,
michael@0 157 const UChar *patternSpecification,
michael@0 158 ... )
michael@0 159 {
michael@0 160 va_list ap;
michael@0 161 int32_t written;
michael@0 162
michael@0 163 va_start(ap, patternSpecification);
michael@0 164 written = u_vsnprintf_u(buffer, count, patternSpecification, ap);
michael@0 165 va_end(ap);
michael@0 166
michael@0 167 return written;
michael@0 168 }
michael@0 169
michael@0 170 U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
michael@0 171 u_vsnprintf(UChar *buffer,
michael@0 172 int32_t count,
michael@0 173 const char *patternSpecification,
michael@0 174 va_list ap)
michael@0 175 {
michael@0 176 int32_t written;
michael@0 177 UChar *pattern;
michael@0 178 UChar patBuffer[UFMT_DEFAULT_BUFFER_SIZE];
michael@0 179 int32_t size = (int32_t)strlen(patternSpecification) + 1;
michael@0 180
michael@0 181 /* convert from the default codepage to Unicode */
michael@0 182 if (size >= MAX_UCHAR_BUFFER_SIZE(patBuffer)) {
michael@0 183 pattern = (UChar *)uprv_malloc(size * sizeof(UChar));
michael@0 184 if(pattern == 0) {
michael@0 185 return 0;
michael@0 186 }
michael@0 187 }
michael@0 188 else {
michael@0 189 pattern = patBuffer;
michael@0 190 }
michael@0 191 u_charsToUChars(patternSpecification, pattern, size);
michael@0 192
michael@0 193 /* do the work */
michael@0 194 written = u_vsnprintf_u(buffer, count, pattern, ap);
michael@0 195
michael@0 196 /* clean up */
michael@0 197 if (pattern != patBuffer) {
michael@0 198 uprv_free(pattern);
michael@0 199 }
michael@0 200
michael@0 201 return written;
michael@0 202 }
michael@0 203
michael@0 204 U_CAPI int32_t U_EXPORT2
michael@0 205 u_vsprintf_u(UChar *buffer,
michael@0 206 const UChar *patternSpecification,
michael@0 207 va_list ap)
michael@0 208 {
michael@0 209 return u_vsnprintf_u(buffer, INT32_MAX, patternSpecification, ap);
michael@0 210 }
michael@0 211
michael@0 212 static const u_printf_stream_handler g_sprintf_stream_handler = {
michael@0 213 u_sprintf_write,
michael@0 214 u_sprintf_pad_and_justify
michael@0 215 };
michael@0 216
michael@0 217 U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
michael@0 218 u_vsnprintf_u(UChar *buffer,
michael@0 219 int32_t count,
michael@0 220 const UChar *patternSpecification,
michael@0 221 va_list ap)
michael@0 222 {
michael@0 223 int32_t written = 0; /* haven't written anything yet */
michael@0 224 int32_t result = 0; /* test the return value of u_printf_parse */
michael@0 225
michael@0 226 u_localized_print_string outStr;
michael@0 227
michael@0 228 if (count < 0) {
michael@0 229 count = INT32_MAX;
michael@0 230 }
michael@0 231
michael@0 232 outStr.str = buffer;
michael@0 233 outStr.len = count;
michael@0 234 outStr.available = count;
michael@0 235
michael@0 236 if(u_locbund_init(&outStr.fBundle, "en_US_POSIX") == 0) {
michael@0 237 return 0;
michael@0 238 }
michael@0 239
michael@0 240 /* parse and print the whole format string */
michael@0 241 result = u_printf_parse(&g_sprintf_stream_handler, patternSpecification, &outStr, &outStr, &outStr.fBundle, &written, ap);
michael@0 242
michael@0 243 /* Terminate the buffer, if there's room. */
michael@0 244 if (outStr.available > 0) {
michael@0 245 buffer[outStr.len - outStr.available] = 0x0000;
michael@0 246 }
michael@0 247
michael@0 248 /* Release the cloned bundle, if we cloned it. */
michael@0 249 u_locbund_close(&outStr.fBundle);
michael@0 250
michael@0 251 /* parsing error */
michael@0 252 if (result < 0) {
michael@0 253 return result;
michael@0 254 }
michael@0 255 /* return # of UChars written */
michael@0 256 return written;
michael@0 257 }
michael@0 258
michael@0 259 #endif /* #if !UCONFIG_NO_FORMATTING */
michael@0 260

mercurial