From: Martin Willi Date: Fri, 11 Oct 2013 08:55:05 +0000 (+0200) Subject: printf-hook-builtin: Add some preliminary floating point support X-Git-Tag: 5.1.1rc1~46^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=edc7a3d02f777e7980708a3e3500392787c5ec78;p=thirdparty%2Fstrongswan.git printf-hook-builtin: Add some preliminary floating point support This minimalistic implementation has no aspiration for completeness or accuracy, and just provides what we need. --- diff --git a/src/libstrongswan/tests/test_printf.c b/src/libstrongswan/tests/test_printf.c index 60655de8aa..f822e5f4b0 100644 --- a/src/libstrongswan/tests/test_printf.c +++ b/src/libstrongswan/tests/test_printf.c @@ -91,6 +91,31 @@ START_TEST(test_printf_hex) } END_TEST +START_TEST(test_printf_float) +{ + verify("0.000000", "%f", 0.0); + verify("1.000000", "%f", 1.0); + verify("12345.1", "%.1f", 12345.123); + verify("1", "%.0f", 1.0); + verify("1.4", "%.1f", 1.456789); + verify("1.34", "%.2f", 1.3456789); + verify("1.234", "%.3f", 1.23456789); + verify("1.1234", "%.4f", 1.123456789); + + verify("-1.000000", "%f", -1.0); + verify("-12345.1", "%.1f", -12345.123); + verify("-1", "%.0f", -1.0); + verify("-1.4", "%.1f", -1.456789); + verify("-1.34", "%.2f", -1.3456789); + verify("-1.234", "%.3f", -1.23456789); + verify("-1.1234", "%.4f", -1.123456789); + + verify(" 1.2", "%5.1f", 1.234); + verify("001.2", "%05.1f", 1.234); + verify("1.2 ", "%-5.1f", 1.234); +} +END_TEST + Suite *printf_suite_create() { Suite *s; @@ -118,5 +143,9 @@ Suite *printf_suite_create() tcase_add_test(tc, test_printf_hex); suite_add_tcase(s, tc); + tc = tcase_create("float"); + tcase_add_test(tc, test_printf_float); + suite_add_tcase(s, tc); + return s; } diff --git a/src/libstrongswan/utils/printf_hook/printf_hook_builtin.c b/src/libstrongswan/utils/printf_hook/printf_hook_builtin.c index 1c266d4549..6ba4841cd2 100644 --- a/src/libstrongswan/utils/printf_hook/printf_hook_builtin.c +++ b/src/libstrongswan/utils/printf_hook/printf_hook_builtin.c @@ -47,6 +47,7 @@ #include #include #include +#include #define PRINTF_BUF_LEN 8192 #define ARGS_MAX 3 @@ -222,14 +223,15 @@ typedef enum { #define EMIT(x) ({ if (o nchars) + { + while (width > nchars) + { + EMIT(' '); + width--; + } + } + + /* Emit nondigits */ + if (minus) + { + EMIT('-'); + } + else if (flags & FL_PLUS) + { + EMIT('+'); + } + else if (flags & FL_SPACE) + { + EMIT(' '); + } + + if ((flags & FL_HASH) && base == 16) + { + EMIT('0'); + EMIT((flags & FL_UPPER) ? 'X' : 'x'); + } + + /* Emit zero padding */ + if ((flags & (FL_MINUS | FL_ZERO)) == FL_ZERO && width > ndigits) + { + while (width > nchars) + { + EMIT('0'); + width--; + } + } + + /* Generate the number. This is done from right to left. */ + /* Advance the pointer to end of number */ + q += ndigits; + o += ndigits; + /* Temporary values */ + qq = q; + oo = o; + + tmpval = (uintmax_t)fabs(val); + while (ndigits > 0) + { + qq--; + oo--; + ndigits--; + if (oo < n) + { + *qq = digits[tmpval % base]; + } + tmpval /= base; + } + + if (prec) + { + EMIT('.'); + + q += prec; + o += prec; + qq = q; + oo = o; + + while (prec > 0) + { + tmpval = (uintmax_t)(fabs(val) * pow(base, prec)); + qq--; + oo--; + prec--; + if (oo < n) + { + *qq = digits[tmpval % base]; + } + } + } + + /* Emit late space padding */ + while ((flags & FL_MINUS) && width > nchars) + { + EMIT(' '); + width--; + } + + return o; +} + int builtin_vsnprintf(char *buffer, size_t n, const char *format, va_list ap) { const char *p = format; @@ -724,6 +875,47 @@ int builtin_vsnprintf(char *buffer, size_t n, const char *format, va_list ap) } break; } + case 'A': + { + base = 16; + flags |= FL_UPPER; + goto is_double; + } + case 'E': + case 'G': + { + /* currently not supported, fall */ + } + case 'F': + { + base = 10; + flags |= FL_UPPER; + goto is_double; + } + case 'a': + { + base = 16; + goto is_double; + } + case 'e': + case 'g': + { + /* currently not supported, fall */ + } + case 'f': + { + base = 10; + goto is_double; + } + is_double: + { + sz = format_double(q, (o < n) ? n - o : 0, + va_arg(ap, double), + flags, base, width, prec); + q += sz; + o += sz; + break; + } case 'n': { /* Output the number of characters written */