changeset 707:cc06815e5504

Add some tests about the behaviour of FreeBSD's /bin/sh builtin getopts(). It also has the "silent" option -- but it is undocumented.
author Franz Glasner <fzglas.hg@dom66.de>
date Wed, 02 Oct 2024 19:50:37 +0200
parents 45051412d0b8
children f19ae639e7ff
files tests/builtin_getopts/builtin_getopts.t tests/builtin_getopts/testsetup.sh
diffstat 2 files changed, 271 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/builtin_getopts/builtin_getopts.t	Wed Oct 02 19:50:37 2024 +0200
@@ -0,0 +1,173 @@
+Tests for the behaviour of the Shell's `getopts`
+
+Shell is /bin/sh.
+
+Setup
+=====
+
+  $ set -u
+  $ . "${TESTDIR}/testsetup.sh"
+
+
+Standard
+========
+
+  $ test_standard_1 -a -b bbb1
+  OPTION: a with arg: `'
+  OPTION: b with arg: `bbb1'
+  OPTIND: 4
+
+The variable will be set to ``?`` after the last option when getopts returns 1:
+
+  $ reset_getopts
+  $ test_standard_1 -a -b bbb1
+  OPTION: a with arg: `'
+  OPTION: b with arg: `bbb1'
+  OPTIND: 4
+  $ test "$opt" = '?'
+
+No option:
+
+  $ reset_getopts
+  $ test_standard_1 arg1 arg2 args
+  OPTIND: 1
+  $ test "$opt" = '?'
+
+OPTARG is **unset** at every invocation of `getopts` first:
+
+  $ reset_getopts
+  $ test_standard_1 -a -b bbb1 -a
+  OPTION: a with arg: `'
+  OPTION: b with arg: `bbb1'
+  OPTION: a with arg: `'
+  OPTIND: 5
+
+Option arguments are not checked for another option syntax:
+
+  $ reset_getopts
+  $ test_standard_1 -a -b -a
+  OPTION: a with arg: `'
+  OPTION: b with arg: `-a'
+  OPTIND: 4
+
+
+Missing arguments:
+
+  $ reset_getopts
+  $ test_standard_1 -b
+  No arg for -b option
+  ERROR: unknown option
+  OPTIND: 2
+  $ test "$opt" = '?'
+
+No abort on errors:
+
+  $ reset_getopts
+  $ test_standard_1 -u -a
+  Illegal option -u
+  ERROR: unknown option
+  OPTION: a with arg: `'
+  OPTIND: 3
+  $ test "$opt" = '?'
+
+Abort processing with '--'
+
+  $ reset_getopts
+  $ test_standard_1 -a -b xxx -- -a -b yyy
+  OPTION: a with arg: `'
+  OPTION: b with arg: `xxx'
+  OPTIND: 5
+  $ test "$opt" = '?'
+
+'--' does not stop option processing when a required arg just before is missing
+
+  $ reset_getopts
+  $ test_standard_1 -a -b -- -a -b yyy
+  OPTION: a with arg: `'
+  OPTION: b with arg: `--'
+  OPTION: a with arg: `'
+  OPTION: b with arg: `yyy'
+  OPTIND: 7
+
+
+No Error Reports
+================
+
+This behaviour with a colon as the very first character in optstring is not
+documented. But it works similar to ksh93.
+
+  $ reset_getopts
+  $ test_noreport_1 -a -b bbb1
+  OPTION: a with arg: `'
+  OPTION: b with arg: `bbb1'
+  OPTIND: 4
+
+The variable will be set to ``?`` after the last option when getopts returns 1:
+
+  $ reset_getopts
+  $ test_standard_1 -a -b bbb1
+  OPTION: a with arg: `'
+  OPTION: b with arg: `bbb1'
+  OPTIND: 4
+  $ test "$opt" = '?'
+
+No option:
+
+  $ reset_getopts
+  $ test_noreport_1 arg1 arg2 args
+  OPTIND: 1
+  $ test "$opt" = '?'
+
+OPTARG is **unset** at every invocation of `getopts` first:
+
+  $ reset_getopts
+  $ test_noreport_1 -a -b bbb1 -a
+  OPTION: a with arg: `'
+  OPTION: b with arg: `bbb1'
+  OPTION: a with arg: `'
+  OPTIND: 5
+
+Option arguments are not checked for another option syntax:
+
+  $ reset_getopts
+  $ test_noreport_1 -a -b -a
+  OPTION: a with arg: `'
+  OPTION: b with arg: `-a'
+  OPTIND: 4
+
+Here FreeBSD's `/bin/sh` behaves like `ksh93`
+
+Missing arguments are reported via ':' here:
+
+  $ reset_getopts
+  $ test_noreport_1 -b
+  ERROR: unknown option (colon): b
+  OPTIND: 2
+  $ test "$opt" = '?'
+
+No abort on errors -- unknown options are reported via '?' here:
+
+  $ reset_getopts
+  $ test_noreport_1 -u -a
+  ERROR: unknown option: u
+  OPTION: a with arg: `'
+  OPTIND: 3
+  $ test "$opt" = '?'
+
+Abort processing with '--'
+
+  $ reset_getopts
+  $ test_noreport_1 -a -b xxx -- -a -b yyy
+  OPTION: a with arg: `'
+  OPTION: b with arg: `xxx'
+  OPTIND: 5
+
+'--' does not stop option processing when a required arg just before is missing
+
+  $ reset_getopts
+  $ test_noreport_1 -a -b -- -a -b yyy
+  OPTION: a with arg: `'
+  OPTION: b with arg: `--'
+  OPTION: a with arg: `'
+  OPTION: b with arg: `yyy'
+  OPTIND: 7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/builtin_getopts/testsetup.sh	Wed Oct 02 19:50:37 2024 +0200
@@ -0,0 +1,98 @@
+#!/bin/sh
+#
+# Test the behaviour of the shell's builtin `getopts`
+#
+
+#:
+#: Reset all the global variables thar are used by `getopts`
+#:
+#: Output (Globals):
+#:   OPTIND (int):
+#:   OPTARG:
+#:
+reset_getopts() {
+    OPTIND=1
+    OPTARG=
+    # XXX FIXME: Is this used in FreeBSD's /bin/sh
+    # OPTERR=
+
+    # The test variable
+    opt=''
+    
+    return 0
+}
+
+
+test_standard_1() {
+    while getopts 'ab:' opt; do
+        case "$opt" in
+            a)
+                echo "OPTION: a with arg: \`${OPTARG+SET}'"
+                ;;
+            b)
+                echo "OPTION: b with arg: \`${OPTARG}'"
+                ;;
+            \?)
+		# All errors are reported here
+                if [ -n "${OPTARG+SET}" ] ; then
+                    echo "ERROR: unknown option: ${OPTARG}" >&2
+                else
+		    echo "ERROR: unknown option" >&2
+		fi
+                ;;
+	    :)
+		# Never landing here
+                if [ -n "${OPTARG+SET}" ] ; then
+                    echo "ERROR: unknown option (colon): ${OPTARG}" >&2
+                else
+		    echo "ERROR: unknown option (colon)" >&2
+		fi
+                ;;
+            *)
+                echo "ERROR: option handling" >&2
+                ;;
+        esac
+    done
+    echo "OPTIND: ${OPTIND}"
+}
+
+
+#:
+#: Silent mode with a colon ``:`` as the first character in optstring.
+#:
+#: This is undocumented in current FreeBSD's :command:`/bin/sh`.
+#: But it works as in :command:`/usr/local/bin/ksh93`.
+#:
+test_noreport_1() {
+    # Note: The first char in optstring is a colon!
+    while getopts ':ab:' opt; do
+        case "$opt" in
+            a)
+                echo "OPTION: a with arg: \`${OPTARG+SET}'"
+                ;;
+            b)
+                echo "OPTION: b with arg: \`${OPTARG}'"
+                ;;
+            \?)
+		# An invalid option is reported here
+                if [ -n "${OPTARG+SET}" ] ; then
+                    echo "ERROR: unknown option: ${OPTARG}" >&2
+                else
+		    echo "ERROR: unknown option" >&2
+		fi
+                ;;
+	    :)
+		# A missing required parameter is reported here
+                if [ -n "${OPTARG+SET}" ] ; then
+                    echo "ERROR: unknown option (colon): ${OPTARG}" >&2
+                else
+		    echo "ERROR: unknown option (colon)" >&2
+		fi
+                ;;
+            *)
+                echo "ERROR: option handling" >&2
+                ;;
+        esac
+    done
+    echo "OPTIND: ${OPTIND}"    
+}