aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libsbutil/sb_printf.c48
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/sb_printf.at2
-rw-r--r--tests/sb_printf_tst.c14
4 files changed, 52 insertions, 14 deletions
diff --git a/libsbutil/sb_printf.c b/libsbutil/sb_printf.c
index 1ad9e23..30b90d4 100644
--- a/libsbutil/sb_printf.c
+++ b/libsbutil/sb_printf.c
@@ -15,19 +15,23 @@
* p - pointer
*
* The following modifiers are supported:
- * z - size_t
- * * - width is an argument
+ * z - size_t
+ * l - long
+ * ll - long long
+ * * - width is an argument
+ * # - for %x, we always do this, so it's kind of ignored
*
- * Copyright 1999-2008 Gentoo Foundation
+ * Copyright 1999-2012 Gentoo Foundation
* Licensed under the GPL-2
*/
#include "headers.h"
#include "sbutil.h"
-#define MOD_STAR (1 << 0)
-#define MOD_SIZE_T (1 << 1)
-#define MOD_LONG_T (1 << 2)
+#define MOD_STAR (1 << 0)
+#define MOD_SIZE_T (1 << 1)
+#define MOD_LONG_T (1 << 2)
+#define MOD_LONG_LONG_T (1 << 3)
void sb_vfdprintf(int fd, const char *format, va_list args)
{
@@ -47,7 +51,7 @@ void sb_vfdprintf(int fd, const char *format, va_list args)
char buf[50];
size_t idx;
- unsigned int u, x;
+ unsigned long long int u, x;
char hex_base;
size_t padding = 0;
@@ -67,9 +71,12 @@ void sb_vfdprintf(int fd, const char *format, va_list args)
break;
case 'l':
++conv;
- if (modifiers & MOD_LONG_T)
- goto inv_modifier;
- modifiers |= MOD_LONG_T;
+ if (modifiers & MOD_LONG_T) {
+ if (modifiers & MOD_LONG_LONG_T)
+ goto inv_modifier;
+ modifiers = (modifiers & ~MOD_LONG_T) | MOD_LONG_LONG_T;
+ } else
+ modifiers |= MOD_LONG_T;
goto eat_more;
case 'z':
++conv;
@@ -84,6 +91,10 @@ void sb_vfdprintf(int fd, const char *format, va_list args)
modifiers |= MOD_STAR;
padding = va_arg(args, int);
goto eat_more;
+ case '#':
+ /* ignore */
+ ++conv;
+ goto eat_more;
case 'c': {
char c = va_arg(args, int);
@@ -103,11 +114,13 @@ void sb_vfdprintf(int fd, const char *format, va_list args)
case 'd':
case 'i': {
- long i;
+ long long i;
if (modifiers & MOD_SIZE_T)
i = va_arg(args, ssize_t);
else if (modifiers & MOD_LONG_T)
i = va_arg(args, long);
+ else if (modifiers & MOD_LONG_LONG_T)
+ i = va_arg(args, long long);
else
i = va_arg(args, int);
u = i;
@@ -125,7 +138,14 @@ void sb_vfdprintf(int fd, const char *format, va_list args)
break;
}
case 'u': {
- u = va_arg(args, unsigned int);
+ if (modifiers & MOD_SIZE_T)
+ u = va_arg(args, size_t);
+ else if (modifiers & MOD_LONG_T)
+ u = va_arg(args, unsigned long);
+ else if (modifiers & MOD_LONG_LONG_T)
+ u = va_arg(args, unsigned long long);
+ else
+ u = va_arg(args, unsigned int);
goto out_uint;
break;
}
@@ -139,6 +159,10 @@ void sb_vfdprintf(int fd, const char *format, va_list args)
out_hex:
if (modifiers & MOD_SIZE_T)
x = va_arg(args, size_t);
+ else if (modifiers & MOD_LONG_T)
+ x = va_arg(args, unsigned long);
+ else if (modifiers & MOD_LONG_LONG_T)
+ x = va_arg(args, unsigned long long);
else
x = va_arg(args, unsigned int);
out_ptr:
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 6a05fe3..a923ddc 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -109,5 +109,5 @@ $(TESTSUITE): $(AT_FILES) testsuite.list.at
testsuite.list.at: $(AT_FILES)
( echo "dnl DO NOT EDIT: GENERATED BY MAKEFILE.AM"; \
- $(GREP) -l '^SB_CHECK' $(AT_FILES) | LC_ALL=C sort | \
+ $(GREP) -l -e '^SB_CHECK' -e '^AT_CHECK' $(AT_FILES) | LC_ALL=C sort | \
$(SED) -e 's:^[.]/:sb_inc([:' -e 's:[.]at$$:]):' ) > $@
diff --git a/tests/sb_printf.at b/tests/sb_printf.at
index b632b96..4a2b628 100644
--- a/tests/sb_printf.at
+++ b/tests/sb_printf.at
@@ -16,7 +16,7 @@ sb_printf_tst | ${AWK} 'BEGIN { ret = 0 }
# not so easy -- we format sandbox printf() the way we like
# %x -- we prefix output with 0x
- if ($1 ~ /%[[xX]]/)
+ if ($1 ~ /%[[luz#]]*[[xX]]/)
gsub(/\<0x/, "")
# %p -- we zero pad the output
diff --git a/tests/sb_printf_tst.c b/tests/sb_printf_tst.c
index 1db7c33..867f782 100644
--- a/tests/sb_printf_tst.c
+++ b/tests/sb_printf_tst.c
@@ -20,9 +20,15 @@ int main(int argc, char *argv[])
T("%i", argc);
T("%i", -argc);
+ T("%li", (long)argc);
+ T("%li", (long)-argc);
T("%d", 123);
T("%d", -123);
+ T("%lld", (long long)123);
+ T("%lld", (long long)-123);
T("%u", 1000);
+ T("%lu", (unsigned long)1234);
+ T("%llu", (unsigned long long)5679);
T("%zi", (ssize_t)argc);
T("%zi", (ssize_t)-argc);
T("%zd", (ssize_t)123);
@@ -31,6 +37,14 @@ int main(int argc, char *argv[])
T("%x", argc);
T("%x", 0xabcdef);
+ T("%#x", argc);
+ T("%#x", 0xabcdef);
+ T("%lx", (unsigned long)argc);
+ T("%lx", (unsigned long)0xabcdef);
+ T("%llx", (unsigned long long)argc);
+ T("%llx", (unsigned long long)0xabcdef);
+ T("%zx", (size_t)argc);
+ T("%zx", (size_t)0xabcdef);
T("%X", argc);
T("%X", 0xabcdef);