aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2024-09-11 16:07:48 +0100
committerPádraig Brady <P@draigBrady.com>2024-09-13 17:29:02 +0100
commit5cecd703e57b2e1301767d82cbe5bb01cae88472 (patch)
treec672e2c034816a4afb447c5ba927f3818a50487e /tests
parentmaint: assume C89 escape sequences (diff)
downloadcoreutils-5cecd703e57b2e1301767d82cbe5bb01cae88472.tar.gz
coreutils-5cecd703e57b2e1301767d82cbe5bb01cae88472.zip
printf: add indexed argument support
* src/printf.c (print_formatted): Add support for %i$ indexed args. * tests/printf/printf-indexed.sh: Add a new file of test cases. * tests/local.mk: Reference the new test file. * doc/coreutils.texi (printf invocation): Mention how mixed processing of indexed and sequential references are supported, unlike the printf(2) library function. * NEWS: Mention the new (POSIX:2024) feature. Addresses https://bugs.gnu.org/73068
Diffstat (limited to 'tests')
-rw-r--r--tests/local.mk1
-rwxr-xr-xtests/printf/printf-indexed.sh103
2 files changed, 104 insertions, 0 deletions
diff --git a/tests/local.mk b/tests/local.mk
index fdbf36946..f72353862 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -353,6 +353,7 @@ all_tests = \
tests/printf/printf.sh \
tests/printf/printf-cov.pl \
tests/printf/printf-hex.sh \
+ tests/printf/printf-indexed.sh \
tests/printf/printf-mb.sh \
tests/printf/printf-surprise.sh \
tests/printf/printf-quote.sh \
diff --git a/tests/printf/printf-indexed.sh b/tests/printf/printf-indexed.sh
new file mode 100755
index 000000000..7a7744436
--- /dev/null
+++ b/tests/printf/printf-indexed.sh
@@ -0,0 +1,103 @@
+#!/bin/sh
+# tests for printf %i$ indexed format processing
+
+# Copyright (C) 2024 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ printf
+i
+getlimits_
+
+prog='env printf'
+
+printf_check() {
+ cat <<EOF > exp || framework_failure_
+$1
+EOF
+
+ shift
+
+ $prog "$@" > out || fail=1
+ compare exp out || fail=1
+}
+
+printf_check_err() {
+ cat <<EOF > exp || framework_failure_
+$1
+EOF
+
+ shift
+
+ returns_ 1 $prog "$@" 2> out || fail=1
+ compare exp out || fail=1
+}
+
+NL="
+"
+
+# Reordering
+printf_check '21' '%2$s%1$s\n' 1 2
+
+# Repetition
+printf_check "11${NL}22" '%1$s%1$s\n' 1 2
+
+# Multiple uses of format
+printf_check "A C B${NL}D " '%s %3$s %s\n' A B C D
+printf_check " 4${NL}1" '%1$*d\n' 4 1
+
+# Mixed indexed and sequential main arg
+printf_check "A B A" '%s %s %1$s\n' A B
+printf_check ' 0 1 ' '%100$*d %s %s %s\n' 4 1
+
+# indexed arg, width, and precision
+printf_check ' 01' '%1$*2$.*3$d\n' 1 3 2
+# indexed arg, sequential width, and precision
+printf_check ' 01' '%3$*.*d\n' 3 2 1
+# indexed arg, width, and sequential precision
+printf_check ' 01' '%3$*2$.*d\n' 2 3 1
+# indexed arg, precision, and sequential width
+printf_check ' 01' '%3$*.*2$d\n' 3 2 1
+# Indexed arg, width
+printf_check ' 1' '%2$*1$d\n' 4 1
+# Indexed arg, and sequential width
+printf_check ' 1' '%2$*d\n' 4 1
+
+# Flags come after $ (0 is not a flag here but allowed):
+printf_check ' 1' '%01$4d\n' 1
+# Flags come after $ (0 is a flag here):
+printf_check '0001' '%1$0*2$d\n' 1 4
+# Flags come after $ (-2 not taken as a valid index here):
+printf_check_err 'printf: %-2$: invalid conversion specification' \
+ '%-2$s %1$s\n' A B
+# Flags come after $ (' ' is not allowed as part of number here)
+printf_check_err 'printf: % 2$: invalid conversion specification' \
+ '% 2$s %1$s\n' A B
+
+# Ensure only base 10 numbers are accepted
+printf_check_err "printf: 'A': expected a numeric value" \
+ '%0x2$s %2$s\n' A B
+# Ensure empty numbers are rejected
+printf_check_err 'printf: %$: invalid conversion specification' \
+ '%$d\n' 1
+# Verify int limits are clamped appropriately (to INT_MAX)
+# (Large indexes are useful to ensure a single pass with the format arg)
+# Note you can't have more than INT_MAX - 2 args anyway as argc is an int,
+# and that also includes the command name and format at least.
+for i in 999 $INT_MAX $INT_OFLOW $INTMAX_MAX $INTMAX_OFLOW; do
+ printf_check 'empty' "empty%$i\$s\n" 'foo'
+done
+
+Exit $fail