1#!/bin/sh
2# Verify that all options mentioned in usage are recognized by getopt.
3
4# Copyright (C) 2017-2023 Free Software Foundation, Inc.
5
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15
16# You should have received a copy of the GNU General Public License
17# along with this program.  If not, see <https://www.gnu.org/licenses/>.
18
19. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
20
21checkprg () {
22  prg="$1"
23
24  # Get stderr output for unrecognized options for later use as a pattern.
25  # Also consider the expected exit status of each program.
26  rcexp=1
27  case "$prg" in
28    dir | ls | printenv | sort | tty | vdir ) rcexp=2 ;;
29    env | chroot | nice | nohup | runcon | stdbuf | timeout ) rcexp=125 ;;
30  esac
31  # Write the pattern for a long, unknown option into a pattern file.
32  o='thisoptiondoesnotexist'
33  returns_ $rcexp $prg --$o >/dev/null 2> err || fail=1
34  grep -F "$o" err || framework_failure_
35  sed -n "1s/--$o/OPT/p" < err > pat || framework_failure_
36
37  # Append the pattern for a short unknown option.
38  returns_ $rcexp $prg -/ >/dev/null 2> err || fail=1
39  grep " '*/'*" err || framework_failure_
40  # The following only handles the common case that has single quotes,
41  # as it simplifies to identify missing options only on common systems.
42  sed -n "1s/'\/'/'OPT'/p" < err >> pat || framework_failure_
43
44  # Get output for --help.
45  $prg --help > help || fail=1
46
47  # Extract all options mention in the above --help output.
48  nl="
49  "
50  sed -n -e '/--version/q' \
51    -e 's/^ \{2,6\}-/-/; s/  .*//; s/[=[].*//; s/, /\'"$nl"'/g; s/^-/-/p' help \
52    > opts || framework_failure_
53  cat opts  # for debugging purposes
54
55  # Test all options mentioned in usage (but --version).
56  while read opt; do
57    test "x$opt" = 'x--help' \
58      && continue
59    # Append --help to be on the safe side: the option under test either
60    # requires a further argument, or --help triggers usage(); so $prg should
61    # exit without performing its regular operation.
62    # Add a 2nd --help for the 'env -u --help' case.
63    $prg "$opt" --help --help </dev/null >out 2>err1
64    rc=$?
65    # In the --help case, i.e., when the option under test has been accepted,
66    # the exit code should be Zero.
67    if [ $rc = 0 ]; then
68      compare help out || fail=1
69    else
70      # Else $prg should have complained about a missing argument.
71      # Catch false positives.
72      case "$prg/$opt" in
73        'pr/-COLUMN') continue;;
74      esac
75      # Replace $opt in stderr output by the neutral placeholder.
76      # Handle both long and short option error messages.
77      sed -e "s/$opt/OPT/" -e "s/'.'/'OPT'/" < err1 > err || framework_failure_
78      # Fail if the stderr output matches the above provoked error.
79      grep -Ff pat err && { fail=1; cat err1; }
80    fi
81  done < opts
82}
83
84for prg in $built_programs; do
85  case "$prg" in
86    # Skip utilities entirely which have special option parsing.
87    '[' | expr | stty )
88      continue;;
89    # Wrap some utilities known by the shell by env.
90    echo | false | kill | printf | pwd | sleep | test | true )
91      prg="env $prg";;
92  esac
93  checkprg $prg
94done
95
96Exit $fail
97