aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/printf.test22
-rw-r--r--toys/pending/printf.c13
2 files changed, 23 insertions, 12 deletions
diff --git a/tests/printf.test b/tests/printf.test
index 96789bd0..ebf536ff 100644
--- a/tests/printf.test
+++ b/tests/printf.test
@@ -6,12 +6,24 @@
[ -f testing.sh ] && . testing.sh
#testing "name" "command" "result" "infile" "stdin"
-#set -x
-testing "printf TEXT" "printf toyTestText" "toyTestText" "" ""
-testing "printf MULTILINE_TEXT" \
- "printf 'Testing\nmultiline\ntext\nfrom\ntoybox\tcommand.\b'" \
- "Testing\nmultiline\ntext\nfrom\ntoybox\tcommand.\b" "" ""
+testing "" "printf TEXT" "TEXT" "" ""
+testing "printf escapes" "printf 'one\ntwo\n\v\t\r\f\e\b\athree'" \
+ "one\ntwo\n\v\t\r\f\e\b\athree" "" ""
+testing "printf %b escapes" "printf %b 'one\ntwo\n\v\t\r\f\e\b\athree'" \
+ "one\ntwo\n\v\t\r\f\e\b\athree" "" ""
+testing "printf null" "printf 'x\0y' | od -An -tx1" ' 78 00 79\n' "" ""
+testing "printf trailing slash" "printf 'abc\'" 'abc\' "" ""
+testing "printf octal" "printf ' \1\002\429\045x'" ' \001\002"9%x' "" ""
+testing "printf not octal" "printf '\9'" '\9' "" ""
+testing "printf hex" "printf 'A\x1b\x2B\x3Q\xa' | od -An -tx1" \
+ ' 41 1b 2b 03 51 0a\n' "" ""
+testing "" "printf '%x\\n' 0x2a" "2a\n" "" ""
+
+testing "" "printf %d 42" "42" "" ""
+testing "" "printf %d 0x2a" "42" "" ""
+testing "" "printf %d 052" "42" "" ""
+
testing "printf '%5d%4d' 1 21 321 4321 54321" \
"printf '%5d%4d' 1 21 321 4321 54321" " 1 21 321432154321 0" "" ""
testing "printf '%c %c' 78 79" "printf '%c %c' 78 79" "7 7" "" ""
diff --git a/toys/pending/printf.c b/toys/pending/printf.c
index b683128f..3d1a73f2 100644
--- a/toys/pending/printf.c
+++ b/toys/pending/printf.c
@@ -14,8 +14,7 @@ config PRINTF
usage: printf FORMAT [ARGUMENT...]
Format and print ARGUMENT(s) according to FORMAT, using C printf syntax
- (percent escapes for cdeEfgGiosuxX, slash escapes for \abefnrtv0 or
- \0OCT or 0xHEX).
+ (% escapes for cdeEfgGiosuxX, \ escapes for abefnrtv0 or \OCTAL or \xHEX).
*/
#define FOR_printf
@@ -50,9 +49,9 @@ static char *get_format(char *f)
}
// Print arguments with corresponding conversion and width and precision.
-static void print(char *fmt, int w, int p)
+static void print(char *fmt, int w, int p, char *arg)
{
- char *ptr = fmt, *ep = 0, *format = 0, *arg = *toys.optargs;
+ char *ptr = fmt, *ep = 0, *format = 0;
errno = 0;
if (strchr("diouxX", *ptr)) {
@@ -145,7 +144,7 @@ void printf_main(void)
for (f = format; *f; f++) {
if (eat(&f, '\\')) putchar(handle_slash(&f));
- else if (*f != '%' || *++f == '%') xputc(*f);
+ else if (!eat(&f, '%') || *f == '%') putchar(*f);
else if (*f == 'b')
for (p = *arg ? *(arg++) : ""; *p; p++)
putchar(eat(&p, '\\') ? handle_slash(&p) : *p);
@@ -163,7 +162,7 @@ void printf_main(void)
if (!eat(&f, '.')) break;
}
if (!(p = strchr("diouxXfeEgGcs", *f)))
- perror_exit("bad format@%ld", f-format);
+ error_exit("bad format@%ld", f-format);
else {
int len = f-start;
@@ -172,7 +171,7 @@ void printf_main(void)
//pitfall: handle diff b/w * and .*
if ((TT.hv_w-1) == TT.hv_p) TT.hv_w = NULL;
memcpy((p = xzalloc(len+1)), start, len);
- print(p+len-1, wp[0], wp[1]);
+ print(p+len-1, wp[0], wp[1], *arg);
if (*arg) arg++;
free(p);
p = NULL;