1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/io/sprintf.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,260 @@ 1.4 +/* 1.5 +****************************************************************************** 1.6 +* 1.7 +* Copyright (C) 2001-2008, International Business Machines 1.8 +* Corporation and others. All Rights Reserved. 1.9 +* 1.10 +****************************************************************************** 1.11 +* 1.12 +* File sprintf.c 1.13 +* 1.14 +* Modification History: 1.15 +* 1.16 +* Date Name Description 1.17 +* 02/08/2001 george Creation. Copied from uprintf.c 1.18 +* 03/27/2002 Mark Schneckloth Many fixes regarding alignment, null termination 1.19 +* (mschneckloth@atomz.com) and other various problems. 1.20 +* 08/07/2003 george Reunify printf implementations 1.21 +******************************************************************************* 1.22 +*/ 1.23 + 1.24 +#include "unicode/utypes.h" 1.25 + 1.26 +#if !UCONFIG_NO_FORMATTING 1.27 + 1.28 +#include "unicode/ustdio.h" 1.29 +#include "unicode/ustring.h" 1.30 +#include "unicode/putil.h" 1.31 + 1.32 +#include "uprintf.h" 1.33 +#include "locbund.h" 1.34 + 1.35 +#include "cmemory.h" 1.36 +#include <ctype.h> 1.37 + 1.38 +/* u_minstrncpy copies the minimum number of code units of (count or output->available) */ 1.39 +static int32_t 1.40 +u_sprintf_write(void *context, 1.41 + const UChar *str, 1.42 + int32_t count) 1.43 +{ 1.44 + u_localized_print_string *output = (u_localized_print_string *)context; 1.45 + int32_t size = ufmt_min(count, output->available); 1.46 + 1.47 + u_strncpy(output->str + (output->len - output->available), str, size); 1.48 + output->available -= size; 1.49 + return size; 1.50 +} 1.51 + 1.52 +static int32_t 1.53 +u_sprintf_pad_and_justify(void *context, 1.54 + const u_printf_spec_info *info, 1.55 + const UChar *result, 1.56 + int32_t resultLen) 1.57 +{ 1.58 + u_localized_print_string *output = (u_localized_print_string *)context; 1.59 + int32_t written = 0; 1.60 + int32_t lengthOfResult = resultLen; 1.61 + 1.62 + resultLen = ufmt_min(resultLen, output->available); 1.63 + 1.64 + /* pad and justify, if needed */ 1.65 + if(info->fWidth != -1 && resultLen < info->fWidth) { 1.66 + int32_t paddingLeft = info->fWidth - resultLen; 1.67 + int32_t outputPos = output->len - output->available; 1.68 + 1.69 + if (paddingLeft + resultLen > output->available) { 1.70 + paddingLeft = output->available - resultLen; 1.71 + if (paddingLeft < 0) { 1.72 + paddingLeft = 0; 1.73 + } 1.74 + /* paddingLeft = output->available - resultLen;*/ 1.75 + } 1.76 + written += paddingLeft; 1.77 + 1.78 + /* left justify */ 1.79 + if(info->fLeft) { 1.80 + written += u_sprintf_write(output, result, resultLen); 1.81 + u_memset(&output->str[outputPos + resultLen], info->fPadChar, paddingLeft); 1.82 + output->available -= paddingLeft; 1.83 + } 1.84 + /* right justify */ 1.85 + else { 1.86 + u_memset(&output->str[outputPos], info->fPadChar, paddingLeft); 1.87 + output->available -= paddingLeft; 1.88 + written += u_sprintf_write(output, result, resultLen); 1.89 + } 1.90 + } 1.91 + /* just write the formatted output */ 1.92 + else { 1.93 + written = u_sprintf_write(output, result, resultLen); 1.94 + } 1.95 + 1.96 + if (written >= 0 && lengthOfResult > written) { 1.97 + return lengthOfResult; 1.98 + } 1.99 + 1.100 + return written; 1.101 +} 1.102 + 1.103 +U_CAPI int32_t U_EXPORT2 1.104 +u_sprintf(UChar *buffer, 1.105 + const char *patternSpecification, 1.106 + ... ) 1.107 +{ 1.108 + va_list ap; 1.109 + int32_t written; 1.110 + 1.111 + va_start(ap, patternSpecification); 1.112 + written = u_vsnprintf(buffer, INT32_MAX, patternSpecification, ap); 1.113 + va_end(ap); 1.114 + 1.115 + return written; 1.116 +} 1.117 + 1.118 +U_CAPI int32_t U_EXPORT2 1.119 +u_sprintf_u(UChar *buffer, 1.120 + const UChar *patternSpecification, 1.121 + ... ) 1.122 +{ 1.123 + va_list ap; 1.124 + int32_t written; 1.125 + 1.126 + va_start(ap, patternSpecification); 1.127 + written = u_vsnprintf_u(buffer, INT32_MAX, patternSpecification, ap); 1.128 + va_end(ap); 1.129 + 1.130 + return written; 1.131 +} 1.132 + 1.133 +U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ 1.134 +u_vsprintf(UChar *buffer, 1.135 + const char *patternSpecification, 1.136 + va_list ap) 1.137 +{ 1.138 + return u_vsnprintf(buffer, INT32_MAX, patternSpecification, ap); 1.139 +} 1.140 + 1.141 +U_CAPI int32_t U_EXPORT2 1.142 +u_snprintf(UChar *buffer, 1.143 + int32_t count, 1.144 + const char *patternSpecification, 1.145 + ... ) 1.146 +{ 1.147 + va_list ap; 1.148 + int32_t written; 1.149 + 1.150 + va_start(ap, patternSpecification); 1.151 + written = u_vsnprintf(buffer, count, patternSpecification, ap); 1.152 + va_end(ap); 1.153 + 1.154 + return written; 1.155 +} 1.156 + 1.157 +U_CAPI int32_t U_EXPORT2 1.158 +u_snprintf_u(UChar *buffer, 1.159 + int32_t count, 1.160 + const UChar *patternSpecification, 1.161 + ... ) 1.162 +{ 1.163 + va_list ap; 1.164 + int32_t written; 1.165 + 1.166 + va_start(ap, patternSpecification); 1.167 + written = u_vsnprintf_u(buffer, count, patternSpecification, ap); 1.168 + va_end(ap); 1.169 + 1.170 + return written; 1.171 +} 1.172 + 1.173 +U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ 1.174 +u_vsnprintf(UChar *buffer, 1.175 + int32_t count, 1.176 + const char *patternSpecification, 1.177 + va_list ap) 1.178 +{ 1.179 + int32_t written; 1.180 + UChar *pattern; 1.181 + UChar patBuffer[UFMT_DEFAULT_BUFFER_SIZE]; 1.182 + int32_t size = (int32_t)strlen(patternSpecification) + 1; 1.183 + 1.184 + /* convert from the default codepage to Unicode */ 1.185 + if (size >= MAX_UCHAR_BUFFER_SIZE(patBuffer)) { 1.186 + pattern = (UChar *)uprv_malloc(size * sizeof(UChar)); 1.187 + if(pattern == 0) { 1.188 + return 0; 1.189 + } 1.190 + } 1.191 + else { 1.192 + pattern = patBuffer; 1.193 + } 1.194 + u_charsToUChars(patternSpecification, pattern, size); 1.195 + 1.196 + /* do the work */ 1.197 + written = u_vsnprintf_u(buffer, count, pattern, ap); 1.198 + 1.199 + /* clean up */ 1.200 + if (pattern != patBuffer) { 1.201 + uprv_free(pattern); 1.202 + } 1.203 + 1.204 + return written; 1.205 +} 1.206 + 1.207 +U_CAPI int32_t U_EXPORT2 1.208 +u_vsprintf_u(UChar *buffer, 1.209 + const UChar *patternSpecification, 1.210 + va_list ap) 1.211 +{ 1.212 + return u_vsnprintf_u(buffer, INT32_MAX, patternSpecification, ap); 1.213 +} 1.214 + 1.215 +static const u_printf_stream_handler g_sprintf_stream_handler = { 1.216 + u_sprintf_write, 1.217 + u_sprintf_pad_and_justify 1.218 +}; 1.219 + 1.220 +U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ 1.221 +u_vsnprintf_u(UChar *buffer, 1.222 + int32_t count, 1.223 + const UChar *patternSpecification, 1.224 + va_list ap) 1.225 +{ 1.226 + int32_t written = 0; /* haven't written anything yet */ 1.227 + int32_t result = 0; /* test the return value of u_printf_parse */ 1.228 + 1.229 + u_localized_print_string outStr; 1.230 + 1.231 + if (count < 0) { 1.232 + count = INT32_MAX; 1.233 + } 1.234 + 1.235 + outStr.str = buffer; 1.236 + outStr.len = count; 1.237 + outStr.available = count; 1.238 + 1.239 + if(u_locbund_init(&outStr.fBundle, "en_US_POSIX") == 0) { 1.240 + return 0; 1.241 + } 1.242 + 1.243 + /* parse and print the whole format string */ 1.244 + result = u_printf_parse(&g_sprintf_stream_handler, patternSpecification, &outStr, &outStr, &outStr.fBundle, &written, ap); 1.245 + 1.246 + /* Terminate the buffer, if there's room. */ 1.247 + if (outStr.available > 0) { 1.248 + buffer[outStr.len - outStr.available] = 0x0000; 1.249 + } 1.250 + 1.251 + /* Release the cloned bundle, if we cloned it. */ 1.252 + u_locbund_close(&outStr.fBundle); 1.253 + 1.254 + /* parsing error */ 1.255 + if (result < 0) { 1.256 + return result; 1.257 + } 1.258 + /* return # of UChars written */ 1.259 + return written; 1.260 +} 1.261 + 1.262 +#endif /* #if !UCONFIG_NO_FORMATTING */ 1.263 +