Index: fusl/src/locale/strfmon.c |
diff --git a/fusl/src/locale/strfmon.c b/fusl/src/locale/strfmon.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7cf2136a06fb211dcc357630cc4e4cc1611676b8 |
--- /dev/null |
+++ b/fusl/src/locale/strfmon.c |
@@ -0,0 +1,101 @@ |
+#include <stdio.h> |
+#include <ctype.h> |
+#include <stdarg.h> |
+#include <monetary.h> |
+#include <errno.h> |
+#include "locale_impl.h" |
+ |
+static ssize_t vstrfmon_l(char *s, size_t n, locale_t loc, const char *fmt, va_list ap) |
+{ |
+ size_t l; |
+ double x; |
+ int fill, nogrp, negpar, nosym, left, intl; |
+ int lp, rp, w, fw; |
+ char *s0=s; |
+ for (; n && *fmt; ) { |
+ if (*fmt != '%') { |
+ literal: |
+ *s++ = *fmt++; |
+ n--; |
+ continue; |
+ } |
+ fmt++; |
+ if (*fmt == '%') goto literal; |
+ |
+ fill = ' '; |
+ nogrp = 0; |
+ negpar = 0; |
+ nosym = 0; |
+ left = 0; |
+ for (; ; fmt++) { |
+ switch (*fmt) { |
+ case '=': |
+ fill = *++fmt; |
+ continue; |
+ case '^': |
+ nogrp = 1; |
+ continue; |
+ case '(': |
+ negpar = 1; |
+ case '+': |
+ continue; |
+ case '!': |
+ nosym = 1; |
+ continue; |
+ case '-': |
+ left = 1; |
+ continue; |
+ } |
+ break; |
+ } |
+ |
+ for (fw=0; isdigit(*fmt); fmt++) |
+ fw = 10*fw + (*fmt-'0'); |
+ lp = 0; |
+ rp = 2; |
+ if (*fmt=='#') for (lp=0, fmt++; isdigit(*fmt); fmt++) |
+ lp = 10*lp + (*fmt-'0'); |
+ if (*fmt=='.') for (rp=0, fmt++; isdigit(*fmt); fmt++) |
+ rp = 10*rp + (*fmt-'0'); |
+ |
+ intl = *fmt++ == 'i'; |
+ |
+ w = lp + 1 + rp; |
+ if (!left && fw>w) w = fw; |
+ |
+ x = va_arg(ap, double); |
+ l = snprintf(s, n, "%*.*f", w, rp, x); |
+ if (l >= n) { |
+ errno = E2BIG; |
+ return -1; |
+ } |
+ s += l; |
+ n -= l; |
+ } |
+ return s-s0; |
+} |
+ |
+ssize_t strfmon_l(char *restrict s, size_t n, locale_t loc, const char *restrict fmt, ...) |
+{ |
+ va_list ap; |
+ ssize_t ret; |
+ |
+ va_start(ap, fmt); |
+ ret = vstrfmon_l(s, n, loc, fmt, ap); |
+ va_end(ap); |
+ |
+ return ret; |
+} |
+ |
+ |
+ssize_t strfmon(char *restrict s, size_t n, const char *restrict fmt, ...) |
+{ |
+ va_list ap; |
+ ssize_t ret; |
+ |
+ va_start(ap, fmt); |
+ ret = vstrfmon_l(s, n, CURRENT_LOCALE, fmt, ap); |
+ va_end(ap); |
+ |
+ return ret; |
+} |