#!/bin/sh # tests for printf %i$ indexed format processing # Copyright (C) 2024-2025 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 . . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src print_ver_ printf getlimits_ prog='env printf' printf_check() { cat < exp || framework_failure_ $1 EOF shift $prog "$@" > out || fail=1 compare exp out || fail=1 } printf_check_err() { cat < 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