int
-bsd_vsnprintf(char **outbuf, size_t bufSize, const char *fmt0, va_list ap)
+bsd_vsnprintf_core(char **outbuf,
+ char *grouping,
+ char thousands_sep,
+ char *decimal_point,
+ size_t bufSize,
+ const char *fmt0,
+ va_list ap)
{
char *fmt; /* format string */
int ch; /* character from fmt */
int width; /* width from format (%8d), or 0 */
int prec; /* precision from format; <0 for N/A */
char sign; /* sign prefix (' ', '+', '-', or \0) */
- char thousands_sep; /* locale specific thousands separator */
- const char *grouping; /* locale specific numeric grouping rules */
#ifndef NO_FLOATING_POINT
/*
* D: expchar holds this character; '\0' if no exponent, e.g. %f
* F: at least two digits for decimal, at least one digit for hex
*/
- char *decimal_point; /* locale specific decimal point */
-#if defined __ANDROID__
- static const char dp = '.';
-#endif
int signflag; /* true if float is negative */
union { /* floating point arguments %[aAeEfFgG] */
double dbl;
xdigs = xdigs_lower;
thousands_sep = '\0';
- grouping = NULL;
convbuf = NULL;
#ifndef NO_FLOATING_POINT
dtoaresult = NULL;
-#if defined(__ANDROID__)
- /*
- * Struct lconv is not working! For decimal_point,
- * using '.' instead is a workaround.
- */
- NOT_TESTED();
- decimal_point = &dp;
-#else
- decimal_point = localeconv()->decimal_point;
-#endif
#endif
fmt = (char *)fmt0;
goto rflag;
case '\'':
flags |= GROUPING;
-#if defined(__ANDROID__)
- /*
- * Struct lconv is not working! The code below is a workaround.
- */
- NOT_TESTED();
- thousands_sep = ',';
-#else
- thousands_sep = *(localeconv()->thousands_sep);
- grouping = localeconv()->grouping;
-#endif
/*
* Grouping should not begin with 0, but it nevertheless
* does (see bug 281072) and makes the formatting code
#undef FIND_ARGUMENTS
}
+int
+bsd_vsnprintf_c_locale(char **outbuf,
+ size_t bufSize,
+ const char *fmt0,
+ va_list ap)
+{
+ char thousands_sep;
+ char *decimal_point;
+ static char dp = '.';
+
+ /*
+ * Perform a "%f" conversion always using the locale associated
+ * with the C locale - "," for thousands, '.' for decimal point.
+ */
+
+ thousands_sep = ',';
+ decimal_point = &dp;
+
+ return bsd_vsnprintf_core(outbuf, NULL, thousands_sep, decimal_point,
+ bufSize, fmt0, ap);
+}
+
+int
+bsd_vsnprintf(char **outbuf,
+ size_t bufSize,
+ const char *fmt0,
+ va_list ap)
+{
+ char *grouping;
+ char thousands_sep;
+ char *decimal_point;
+
+#if defined(__ANDROID__)
+ static char dp = '.';
+
+ /*
+ * Struct lconv is not working! The code below is a workaround.
+ */
+ NOT_TESTED();
+ grouping = NULL;
+ thousands_sep = ',';
+ decimal_point = &dp;
+#else
+ grouping = localeconv()->grouping;
+ thousands_sep = *(localeconv()->thousands_sep);
+ decimal_point = localeconv()->decimal_point;
+#endif
+
+ return bsd_vsnprintf_core(outbuf, grouping, thousands_sep, decimal_point,
+ bufSize, fmt0, ap);
+}
+
/*
* Find all arguments when a positional parameter is encountered. Returns a
* table, indexed by argument number, of pointers to each arguments. The
* initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
* It will be replaces with a malloc-ed one if it overflows.
*/
+
static void
__find_arguments (const char *fmt0, va_list ap, union arg **argtable)
{
* those cases.
*/
- if ((retval < 0 || retval >= size) && size > 0) {
- /* Find UTF-8 code point boundary and place NUL termination there */
- int trunc = CodeSet_Utf8FindCodePointBoundary(str, size - 1);
- str[trunc] = '\0';
+ if ((retval < 0) || (retval >= size)) {
+ if (size > 0) {
+ /* Find UTF-8 code point boundary and place NUL termination there */
+ int trunc = CodeSet_Utf8FindCodePointBoundary(str, size - 1);
+
+ str[trunc] = '\0';
+ }
}
if (retval >= size) {
return -1;
}
+#ifdef HAS_BSD_PRINTF
+/*
+ *----------------------------------------------------------------------
+ *
+ * Str_Sprintf_C_Locale --
+ *
+ * sprintf wrapper that fails on overflow. Enforces numeric C locale.
+ *
+ * Results:
+ * Returns the number of bytes stored in 'buf'.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Str_Sprintf_C_Locale(char *buf, // OUT:
+ size_t maxSize, // IN:
+ const char *fmt, // IN:
+ ...) // IN:
+{
+ uint32 *stack = (uint32*) &buf;
+ va_list args;
+ int retval;
+
+ ASSERT(buf);
+ ASSERT(fmt);
+
+ va_start(args, fmt);
+ retval = bsd_vsnprintf_c_locale(&buf, maxSize, fmt, args);
+ va_end(args);
+
+ if ((retval < 0) || (retval >= maxSize)) {
+ if (maxSize > 0) {
+ /* Find UTF-8 code point boundary and place NUL termination there */
+ int trunc = CodeSet_Utf8FindCodePointBoundary(buf, maxSize - 1);
+
+ buf[trunc] = '\0';
+ }
+ }
+
+ if (retval >= maxSize) {
+ Panic("%s:%d Buffer too small 0x%x\n", __FILE__, __LINE__, stack[-1]);
+ }
+
+ return retval;
+}
+#endif
+
+
/*
*----------------------------------------------------------------------
*