util-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/11] tests: copy test-suite from Frodo Looijaard's getopt
@ 2014-12-07 10:13 Sami Kerola
  2014-12-07 10:13 ` [PATCH 02/11] tests: add more getopt tests Sami Kerola
                   ` (10 more replies)
  0 siblings, 11 replies; 14+ messages in thread
From: Sami Kerola @ 2014-12-07 10:13 UTC (permalink / raw)
  To: util-linux; +Cc: Sami Kerola, Frodo Looijaard

The test cases and their names are the same, but the surrounding testing
facility with Frodo's svn and util-linux are pretty different so this is
not exactly 1:1 copy.

Reference: svn://svn.frodo.looijaard.name/public/getopt/trunk/tests
CC: Frodo Looijaard <frodo@frodo.looijaard.name>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 tests/expected/misc/getopt2                        |  19 +++
 .../expected/misc/getopt2-alternative_option_clash |   2 +
 .../expected/misc/getopt2-alternative_option_long  |   2 +
 .../expected/misc/getopt2-alternative_option_short |   2 +
 tests/expected/misc/getopt2-invalid_getopt_option  |   3 +
 tests/expected/misc/getopt2-invocation_model_one   |   2 +
 .../misc/getopt2-invocation_model_three_as_one     |   2 +
 .../misc/getopt2-invocation_model_two_as_one       |   2 +
 .../misc/getopt2-invocation_without_parameters     |   3 +
 .../expected/misc/getopt2-long_option_ambiguous_1  |   3 +
 tests/expected/misc/getopt2-longopts               |   2 +
 tests/expected/misc/getopt2-name_option_long       |   4 +
 tests/expected/misc/getopt2-name_option_short      |   4 +
 tests/expected/misc/getopt2-quiet_option_long      |   2 +
 tests/expected/misc/getopt2-quiet_option_short     |   2 +
 .../expected/misc/getopt2-quiet_output_option_long |   5 +
 .../misc/getopt2-quiet_output_option_short         |   5 +
 .../expected/misc/getopt2-same_long_short_options  |   2 +
 .../expected/misc/getopt2-test_for_enhanced_getopt |   1 +
 tests/expected/misc/getopt2-unknown_options        |   4 +
 tests/expected/misc/getopt2-unquoted_option_bash   |   5 +
 tests/expected/misc/getopt2-unquoted_option_tcsh   |   5 +
 tests/expected/misc/getopt2-weird_quoting_bash     |   5 +
 tests/expected/misc/getopt2-weird_quoting_tcsh     |   2 +
 tests/ts/misc/getopt2                              | 176 +++++++++++++++++++++
 25 files changed, 264 insertions(+)
 create mode 100644 tests/expected/misc/getopt2
 create mode 100644 tests/expected/misc/getopt2-alternative_option_clash
 create mode 100644 tests/expected/misc/getopt2-alternative_option_long
 create mode 100644 tests/expected/misc/getopt2-alternative_option_short
 create mode 100644 tests/expected/misc/getopt2-invalid_getopt_option
 create mode 100644 tests/expected/misc/getopt2-invocation_model_one
 create mode 100644 tests/expected/misc/getopt2-invocation_model_three_as_one
 create mode 100644 tests/expected/misc/getopt2-invocation_model_two_as_one
 create mode 100644 tests/expected/misc/getopt2-invocation_without_parameters
 create mode 100644 tests/expected/misc/getopt2-long_option_ambiguous_1
 create mode 100644 tests/expected/misc/getopt2-longopts
 create mode 100644 tests/expected/misc/getopt2-name_option_long
 create mode 100644 tests/expected/misc/getopt2-name_option_short
 create mode 100644 tests/expected/misc/getopt2-quiet_option_long
 create mode 100644 tests/expected/misc/getopt2-quiet_option_short
 create mode 100644 tests/expected/misc/getopt2-quiet_output_option_long
 create mode 100644 tests/expected/misc/getopt2-quiet_output_option_short
 create mode 100644 tests/expected/misc/getopt2-same_long_short_options
 create mode 100644 tests/expected/misc/getopt2-test_for_enhanced_getopt
 create mode 100644 tests/expected/misc/getopt2-unknown_options
 create mode 100644 tests/expected/misc/getopt2-unquoted_option_bash
 create mode 100644 tests/expected/misc/getopt2-unquoted_option_tcsh
 create mode 100644 tests/expected/misc/getopt2-weird_quoting_bash
 create mode 100644 tests/expected/misc/getopt2-weird_quoting_tcsh
 create mode 100755 tests/ts/misc/getopt2

diff --git a/tests/expected/misc/getopt2 b/tests/expected/misc/getopt2
new file mode 100644
index 0000000..59ec59b
--- /dev/null
+++ b/tests/expected/misc/getopt2
@@ -0,0 +1,19 @@
+exit value: 0
+exit value: 0
+exit value: 0
+exit value: 1
+exit value: 0
+exit value: 0
+exit value: 0
+exit value: 0
+exit value: 1
+exit value: 0
+exit value: 0
+exit value: 0
+exit value: 0
+exit value: 0
+exit value: 1
+exit value: 1
+exit value: 0
+exit value: 0
+exit value: 1
diff --git a/tests/expected/misc/getopt2-alternative_option_clash b/tests/expected/misc/getopt2-alternative_option_clash
new file mode 100644
index 0000000..04ae19d
--- /dev/null
+++ b/tests/expected/misc/getopt2-alternative_option_clash
@@ -0,0 +1,2 @@
+ -a --abcde --abcde -a -c --
+exit value: 0
diff --git a/tests/expected/misc/getopt2-alternative_option_long b/tests/expected/misc/getopt2-alternative_option_long
new file mode 100644
index 0000000..0f5fc19
--- /dev/null
+++ b/tests/expected/misc/getopt2-alternative_option_long
@@ -0,0 +1,2 @@
+ -a --one --two 'MANDATORY' --three 'OPTIONAL' --
+exit value: 0
diff --git a/tests/expected/misc/getopt2-alternative_option_short b/tests/expected/misc/getopt2-alternative_option_short
new file mode 100644
index 0000000..0f5fc19
--- /dev/null
+++ b/tests/expected/misc/getopt2-alternative_option_short
@@ -0,0 +1,2 @@
+ -a --one --two 'MANDATORY' --three 'OPTIONAL' --
+exit value: 0
diff --git a/tests/expected/misc/getopt2-invalid_getopt_option b/tests/expected/misc/getopt2-invalid_getopt_option
new file mode 100644
index 0000000..531cc98
--- /dev/null
+++ b/tests/expected/misc/getopt2-invalid_getopt_option
@@ -0,0 +1,3 @@
+getopt: invalid option -- 'b'
+Try `getopt --help' for more information.
+exit value: 2
diff --git a/tests/expected/misc/getopt2-invocation_model_one b/tests/expected/misc/getopt2-invocation_model_one
new file mode 100644
index 0000000..ca4ddca
--- /dev/null
+++ b/tests/expected/misc/getopt2-invocation_model_one
@@ -0,0 +1,2 @@
+ -b -d  -e OPTIONAL1 -f  -a -c -ISREQUIRED -g BECOMES THREE ARGUMENTS -- ARG0 ARG1 NOT_OPTIONAL ARG2 ARG3
+exit value: 0
diff --git a/tests/expected/misc/getopt2-invocation_model_three_as_one b/tests/expected/misc/getopt2-invocation_model_three_as_one
new file mode 100644
index 0000000..1d4701f
--- /dev/null
+++ b/tests/expected/misc/getopt2-invocation_model_three_as_one
@@ -0,0 +1,2 @@
+ -b -d '' -e 'OPTIONAL1' -f '' -a -c '-ISREQUIRED' -g 'BECOMES THREE ARGUMENTS' -- 'ARG0' 'ARG1' 'NOT_OPTIONAL' 'ARG2' 'ARG3'
+exit value: 0
diff --git a/tests/expected/misc/getopt2-invocation_model_two_as_one b/tests/expected/misc/getopt2-invocation_model_two_as_one
new file mode 100644
index 0000000..1d4701f
--- /dev/null
+++ b/tests/expected/misc/getopt2-invocation_model_two_as_one
@@ -0,0 +1,2 @@
+ -b -d '' -e 'OPTIONAL1' -f '' -a -c '-ISREQUIRED' -g 'BECOMES THREE ARGUMENTS' -- 'ARG0' 'ARG1' 'NOT_OPTIONAL' 'ARG2' 'ARG3'
+exit value: 0
diff --git a/tests/expected/misc/getopt2-invocation_without_parameters b/tests/expected/misc/getopt2-invocation_without_parameters
new file mode 100644
index 0000000..08b3ed5
--- /dev/null
+++ b/tests/expected/misc/getopt2-invocation_without_parameters
@@ -0,0 +1,3 @@
+getopt: missing optstring argument
+Try `getopt --help' for more information.
+exit value: 2
diff --git a/tests/expected/misc/getopt2-long_option_ambiguous_1 b/tests/expected/misc/getopt2-long_option_ambiguous_1
new file mode 100644
index 0000000..c8cfbb3
--- /dev/null
+++ b/tests/expected/misc/getopt2-long_option_ambiguous_1
@@ -0,0 +1,3 @@
+getopt: option '--long' is ambiguous; possibilities: '--long1' '--long2'
+ --
+exit value: 1
diff --git a/tests/expected/misc/getopt2-longopts b/tests/expected/misc/getopt2-longopts
new file mode 100644
index 0000000..379b5ab
--- /dev/null
+++ b/tests/expected/misc/getopt2-longopts
@@ -0,0 +1,2 @@
+ --long1 --thirdlong 'ARGUMENT' --secondlong 'ARG' --abbriviation 'ABBRARG' -a -- 'EXTRA1'
+exit value: 0
diff --git a/tests/expected/misc/getopt2-name_option_long b/tests/expected/misc/getopt2-name_option_long
new file mode 100644
index 0000000..60b9e6b
--- /dev/null
+++ b/tests/expected/misc/getopt2-name_option_long
@@ -0,0 +1,4 @@
+THIS_PROGRAM: invalid option -- 'b'
+THIS_PROGRAM: unrecognized option '--whatever'
+ --long -a --
+exit value: 1
diff --git a/tests/expected/misc/getopt2-name_option_short b/tests/expected/misc/getopt2-name_option_short
new file mode 100644
index 0000000..60b9e6b
--- /dev/null
+++ b/tests/expected/misc/getopt2-name_option_short
@@ -0,0 +1,4 @@
+THIS_PROGRAM: invalid option -- 'b'
+THIS_PROGRAM: unrecognized option '--whatever'
+ --long -a --
+exit value: 1
diff --git a/tests/expected/misc/getopt2-quiet_option_long b/tests/expected/misc/getopt2-quiet_option_long
new file mode 100644
index 0000000..3e1a967
--- /dev/null
+++ b/tests/expected/misc/getopt2-quiet_option_long
@@ -0,0 +1,2 @@
+ --
+exit value: 1
diff --git a/tests/expected/misc/getopt2-quiet_option_short b/tests/expected/misc/getopt2-quiet_option_short
new file mode 100644
index 0000000..3e1a967
--- /dev/null
+++ b/tests/expected/misc/getopt2-quiet_option_short
@@ -0,0 +1,2 @@
+ --
+exit value: 1
diff --git a/tests/expected/misc/getopt2-quiet_output_option_long b/tests/expected/misc/getopt2-quiet_output_option_long
new file mode 100644
index 0000000..3e05ca7
--- /dev/null
+++ b/tests/expected/misc/getopt2-quiet_output_option_long
@@ -0,0 +1,5 @@
+getopt: invalid option -- 'c'
+getopt: unrecognized option '--unknown'
+getopt: option '--long' is ambiguous; possibilities: '--long1' '--long2'
+getopt: option requires an argument -- 'b'
+exit value: 1
diff --git a/tests/expected/misc/getopt2-quiet_output_option_short b/tests/expected/misc/getopt2-quiet_output_option_short
new file mode 100644
index 0000000..3e05ca7
--- /dev/null
+++ b/tests/expected/misc/getopt2-quiet_output_option_short
@@ -0,0 +1,5 @@
+getopt: invalid option -- 'c'
+getopt: unrecognized option '--unknown'
+getopt: option '--long' is ambiguous; possibilities: '--long1' '--long2'
+getopt: option requires an argument -- 'b'
+exit value: 1
diff --git a/tests/expected/misc/getopt2-same_long_short_options b/tests/expected/misc/getopt2-same_long_short_options
new file mode 100644
index 0000000..919d227
--- /dev/null
+++ b/tests/expected/misc/getopt2-same_long_short_options
@@ -0,0 +1,2 @@
+ -a --a --
+exit value: 0
diff --git a/tests/expected/misc/getopt2-test_for_enhanced_getopt b/tests/expected/misc/getopt2-test_for_enhanced_getopt
new file mode 100644
index 0000000..539db06
--- /dev/null
+++ b/tests/expected/misc/getopt2-test_for_enhanced_getopt
@@ -0,0 +1 @@
+exit value: 4
diff --git a/tests/expected/misc/getopt2-unknown_options b/tests/expected/misc/getopt2-unknown_options
new file mode 100644
index 0000000..6edba2b
--- /dev/null
+++ b/tests/expected/misc/getopt2-unknown_options
@@ -0,0 +1,4 @@
+getopt: invalid option -- 'b'
+getopt: unrecognized option '--whatever'
+ --long -a --
+exit value: 1
diff --git a/tests/expected/misc/getopt2-unquoted_option_bash b/tests/expected/misc/getopt2-unquoted_option_bash
new file mode 100644
index 0000000..8da362f
--- /dev/null
+++ b/tests/expected/misc/getopt2-unquoted_option_bash
@@ -0,0 +1,5 @@
+ -a $?!*  --long1 "\' -- More
+ than
+one
+line
+exit value: 0
diff --git a/tests/expected/misc/getopt2-unquoted_option_tcsh b/tests/expected/misc/getopt2-unquoted_option_tcsh
new file mode 100644
index 0000000..8da362f
--- /dev/null
+++ b/tests/expected/misc/getopt2-unquoted_option_tcsh
@@ -0,0 +1,5 @@
+ -a $?!*  --long1 "\' -- More
+ than
+one
+line
+exit value: 0
diff --git a/tests/expected/misc/getopt2-weird_quoting_bash b/tests/expected/misc/getopt2-weird_quoting_bash
new file mode 100644
index 0000000..db871ce
--- /dev/null
+++ b/tests/expected/misc/getopt2-weird_quoting_bash
@@ -0,0 +1,5 @@
+ -a '$?!* ' --long1 '"\'\''' -- 'More
+ than
+one
+line'
+exit value: 0
diff --git a/tests/expected/misc/getopt2-weird_quoting_tcsh b/tests/expected/misc/getopt2-weird_quoting_tcsh
new file mode 100644
index 0000000..9e5b71d
--- /dev/null
+++ b/tests/expected/misc/getopt2-weird_quoting_tcsh
@@ -0,0 +1,2 @@
+ -a '$?'\!'*'\ '' --long1 '"\\'\''' -- 'More\n'\ 'than\none\nline'
+exit value: 0
diff --git a/tests/ts/misc/getopt2 b/tests/ts/misc/getopt2
new file mode 100755
index 0000000..14deb0d
--- /dev/null
+++ b/tests/ts/misc/getopt2
@@ -0,0 +1,176 @@
+#!/bin/bash
+
+# This file is part of util-linux.
+#
+# This file 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 2 of the License, or
+# (at your option) any later version.
+#
+# This file 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.
+
+TS_TOPDIR="${0%/*}/../.."
+TS_DESC="getopt2"
+
+. $TS_TOPDIR/functions.sh
+
+ts_init "$*"
+ts_check_test_command "$TS_CMD_GETOPT"
+
+export LANG=C
+
+ts_init_subtest alternative_option_clash
+$TS_CMD_GETOPT -a -o abcde -l abcde -- -a -ab -abc -ac >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest alternative_option_long
+$TS_CMD_GETOPT --alternative -o a -l one,two:,three::,four:: -- -a -one -two=MANDATORY -three=OPTIONAL >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest alternative_option_short
+$TS_CMD_GETOPT -a -o a -l one,two:,three::,four:: -- -a -one -two=MANDATORY -three=OPTIONAL >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest invalid_getopt_option
+$TS_CMD_GETOPT -b >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+sed -i '1,1s/.*\///' $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest invocation_model_one
+$TS_CMD_GETOPT abc:d::e::f::g: ARG0 -b ARG1 -d -eOPTIONAL1 -f NOT_OPTIONAL ARG2 -a -c -ISREQUIRED ARG3 -g "BECOMES THREE ARGUMENTS" >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest invocation_model_three_as_one
+$TS_CMD_GETOPT -o abc:d::e::f::g: -- ARG0 -b ARG1 -d -eOPTIONAL1 -f NOT_OPTIONAL ARG2 -a -c -ISREQUIRED ARG3 -g "BECOMES THREE ARGUMENTS" >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest invocation_model_two_as_one
+$TS_CMD_GETOPT -- abc:d::e::f::g: ARG0 -b ARG1 -d -eOPTIONAL1 -f NOT_OPTIONAL ARG2 -a -c -ISREQUIRED ARG3 -g "BECOMES THREE ARGUMENTS" >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest invocation_without_parameters
+$TS_CMD_GETOPT >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest long_option_ambiguous_1
+$TS_CMD_GETOPT -o a -l long1,long2 -- --long >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+sed -i '1,1s/.*\///' $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest longopts
+$TS_CMD_GETOPT -o a -l long1,secondlong:,thirdlong::,abbriviation: -- --long1 EXTRA1 --thirdlong=ARGUMENT --secondlong=ARG --abbr ABBRARG -a >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest name_option_long
+$TS_CMD_GETOPT -n THIS_PROGRAM -o a -l long -- -b --long --whatever -a >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest name_option_short
+$TS_CMD_GETOPT --name THIS_PROGRAM -o a -l long -- -b --long --whatever -a >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest quiet_option_long
+$TS_CMD_GETOPT --quiet -o a,b: -l long1,long2 -- -c --unknown --long -b >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest quiet_option_short
+$TS_CMD_GETOPT -q -o a,b: -l long1,long2 -- -c --unknown --long -b >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest quiet_output_option_long
+$TS_CMD_GETOPT --quiet-output -o a,b: -l long1,long2 -- -c --unknown --long -b >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+sed -i '1,4s/.*\///' $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest quiet_output_option_short
+$TS_CMD_GETOPT -Q -o a,b: -l long1,long2 -- -c --unknown --long -b >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+sed -i '1,4s/.*\///' $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest same_long_short_options
+$TS_CMD_GETOPT -o a -l a -- -a --a >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest test_for_enhanced_getopt
+$TS_CMD_GETOPT -T >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest unknown_options
+$TS_CMD_GETOPT -o a -l long -- -b --long --whatever -a >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+sed -i '1,2s/.*\///' $TS_OUTPUT
+ts_finalize_subtest
+
+echo "exit value: $?" >> $TS_OUTPUT
+ts_init_subtest unquoted_option_bash
+$TS_CMD_GETOPT -s bash -u -o a: -l long1: -- -a '$?!* ' --long \"\\\' 'More
+ than
+one
+line' >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+ts_init_subtest unquoted_option_tcsh
+$TS_CMD_GETOPT -s tcsh --unquoted -o a: -l long1: -- -a '$?!* ' --long \"\\\' 'More
+ than
+one
+line' >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+ts_init_subtest weird_quoting_bash
+$TS_CMD_GETOPT -s bash -o a: -l long1: -- -a '$?!* ' --long \"\\\' 'More
+ than
+one
+line' >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+ts_init_subtest weird_quoting_tcsh
+$TS_CMD_GETOPT --shell tcsh -o a: -l long1: -- -a '$?!* ' --long \"\\\' 'More
+ than
+one
+line' >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+ts_finalize
-- 
2.1.3


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 02/11] tests: add more getopt tests
  2014-12-07 10:13 [PATCH 01/11] tests: copy test-suite from Frodo Looijaard's getopt Sami Kerola
@ 2014-12-07 10:13 ` Sami Kerola
  2014-12-07 10:13 ` [PATCH 03/11] getopt: make nonoptions optstring comment correct Sami Kerola
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sami Kerola @ 2014-12-07 10:13 UTC (permalink / raw)
  To: util-linux; +Cc: Sami Kerola, Frodo Looijaard

After importing Frodo's tests I ran coverage to see if something had
remained unchecked, and there were couple tests that could be done.

CC: Frodo Looijaard <frodo@frodo.looijaard.name>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 tests/expected/misc/getopt3                 |  0
 tests/expected/misc/getopt3-compatible      |  5 +++
 tests/expected/misc/getopt3-csh             |  2 +
 tests/expected/misc/getopt3-no-arguments    |  3 ++
 tests/expected/misc/getopt3-non-option      |  4 ++
 tests/expected/misc/getopt3-posix_correctly |  4 ++
 tests/expected/misc/getopt3-sh              |  2 +
 tests/ts/misc/getopt3                       | 63 +++++++++++++++++++++++++++++
 8 files changed, 83 insertions(+)
 create mode 100644 tests/expected/misc/getopt3
 create mode 100644 tests/expected/misc/getopt3-compatible
 create mode 100644 tests/expected/misc/getopt3-csh
 create mode 100644 tests/expected/misc/getopt3-no-arguments
 create mode 100644 tests/expected/misc/getopt3-non-option
 create mode 100644 tests/expected/misc/getopt3-posix_correctly
 create mode 100644 tests/expected/misc/getopt3-sh
 create mode 100755 tests/ts/misc/getopt3

diff --git a/tests/expected/misc/getopt3 b/tests/expected/misc/getopt3
new file mode 100644
index 0000000..e69de29
diff --git a/tests/expected/misc/getopt3-compatible b/tests/expected/misc/getopt3-compatible
new file mode 100644
index 0000000..585de60
--- /dev/null
+++ b/tests/expected/misc/getopt3-compatible
@@ -0,0 +1,5 @@
+getopt: missing optstring argument
+Try `getopt --help' for more information.
+exit value: 2
+ --
+exit value: 0
diff --git a/tests/expected/misc/getopt3-csh b/tests/expected/misc/getopt3-csh
new file mode 100644
index 0000000..86e48f4
--- /dev/null
+++ b/tests/expected/misc/getopt3-csh
@@ -0,0 +1,2 @@
+ -a -b '1' -c '2' --a-long --b-long '3' --c-long '' -- 'foo' 'bar'
+exit value: 0
diff --git a/tests/expected/misc/getopt3-no-arguments b/tests/expected/misc/getopt3-no-arguments
new file mode 100644
index 0000000..08b3ed5
--- /dev/null
+++ b/tests/expected/misc/getopt3-no-arguments
@@ -0,0 +1,3 @@
+getopt: missing optstring argument
+Try `getopt --help' for more information.
+exit value: 2
diff --git a/tests/expected/misc/getopt3-non-option b/tests/expected/misc/getopt3-non-option
new file mode 100644
index 0000000..73f0b65
--- /dev/null
+++ b/tests/expected/misc/getopt3-non-option
@@ -0,0 +1,4 @@
+ -a 'x' -- 'y' '-b' 'z' 'w'
+ -a 'x' -b 'z' -- 'y' 'w'
+ -a 'x' 'y' -b 'z' 'w' --
+exit value: 0
diff --git a/tests/expected/misc/getopt3-posix_correctly b/tests/expected/misc/getopt3-posix_correctly
new file mode 100644
index 0000000..5b2bc33
--- /dev/null
+++ b/tests/expected/misc/getopt3-posix_correctly
@@ -0,0 +1,4 @@
+ -a -b '1' -c '2' --a-long --b-long '3' --c-long '' -- 'foo' 'bar' 'xyxxy' '--a-long'
+exit value: 0
+ -a -b '1' -c '2' --a-long --b-long '3' --c-long '' -- 'foo' 'bar' 'xyxxy' '--a-long'
+exit value: 0
diff --git a/tests/expected/misc/getopt3-sh b/tests/expected/misc/getopt3-sh
new file mode 100644
index 0000000..86e48f4
--- /dev/null
+++ b/tests/expected/misc/getopt3-sh
@@ -0,0 +1,2 @@
+ -a -b '1' -c '2' --a-long --b-long '3' --c-long '' -- 'foo' 'bar'
+exit value: 0
diff --git a/tests/ts/misc/getopt3 b/tests/ts/misc/getopt3
new file mode 100755
index 0000000..68dc069
--- /dev/null
+++ b/tests/ts/misc/getopt3
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+# This file is part of util-linux.
+#
+# This file 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 2 of the License, or
+# (at your option) any later version.
+#
+# This file 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.
+
+TS_TOPDIR="${0%/*}/../.."
+TS_DESC="getopt3"
+
+. $TS_TOPDIR/functions.sh
+
+ts_init "$*"
+ts_check_test_command "$TS_CMD_GETOPT"
+
+export LANG=C
+
+ts_init_subtest compatible
+$TS_CMD_GETOPT >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+GETOPT_COMPATIBLE='' $TS_CMD_GETOPT >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+sed -i '1,1s/.*\///' $TS_OUTPUT
+ts_finalize_subtest
+
+ts_init_subtest sh
+$TS_CMD_GETOPT --shell=sh -o ab:c:: --long a-long,b-long:,c-long:: -n 'example.sh' -- -a -b 1 -c2  --a-long --b-long 3 --c-long foo bar >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+ts_init_subtest csh
+$TS_CMD_GETOPT --shell=csh -o ab:c:: --long a-long,b-long:,c-long:: -n 'example.csh' -- -a -b 1 -c2  --a-long --b-long 3 --c-long foo bar >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+ts_init_subtest no-arguments
+$TS_CMD_GETOPT >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+sed -i '1,1s/.*\///' $TS_OUTPUT
+ts_finalize_subtest
+
+ts_init_subtest posix_correctly
+$TS_CMD_GETOPT -o +ab:c:: --long a-long,b-long:,c-long:: -n 'example' -- -a -b 1 -c2  --a-long --b-long 3 --c-long foo bar xyxxy --a-long >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+POSIXLY_CORRECT='' $TS_CMD_GETOPT -o ab:c:: --long a-long,b-long:,c-long:: -n 'example' -- -a -b 1 -c2  --a-long --b-long 3 --c-long foo bar xyxxy --a-long >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+ts_init_subtest non-option
+$TS_CMD_GETOPT -o +a:b: -- -a x y -b z w >> $TS_OUTPUT 2>&1
+$TS_CMD_GETOPT -o  a:b: -- -a x y -b z w >> $TS_OUTPUT 2>&1
+$TS_CMD_GETOPT -o -a:b: -- -a x y -b z w >> $TS_OUTPUT 2>&1
+echo "exit value: $?" >> $TS_OUTPUT
+ts_finalize_subtest
+
+ts_finalize
-- 
2.1.3


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 03/11] getopt: make nonoptions optstring comment correct
  2014-12-07 10:13 [PATCH 01/11] tests: copy test-suite from Frodo Looijaard's getopt Sami Kerola
  2014-12-07 10:13 ` [PATCH 02/11] tests: add more getopt tests Sami Kerola
@ 2014-12-07 10:13 ` Sami Kerola
  2014-12-07 10:13 ` [PATCH 04/11] getopt: remove function prototypes Sami Kerola
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sami Kerola @ 2014-12-07 10:13 UTC (permalink / raw)
  To: util-linux; +Cc: Sami Kerola, Frodo Looijaard

>From manual page: 'If the first character of optstring is '-', then each
nonoption argv-element is handled as if it were the argument of an option
with character code 1.'

Reference: http://man7.org/linux/man-pages/man3/getopt.3.html
CC: Frodo Looijaard <frodo@frodo.looijaard.name>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 misc-utils/getopt.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/misc-utils/getopt.c b/misc-utils/getopt.c
index c087e4a..d7918b1 100644
--- a/misc-utils/getopt.c
+++ b/misc-utils/getopt.c
@@ -67,8 +67,8 @@
 #include "nls.h"
 #include "xalloc.h"
 
-/* NON_OPT is the code that is returned when a non-option is found in '+'
- * mode */
+/* NON_OPT is the code that is returned getopt(3) when a non-option is
+ * found in 'char optstring[]="-abc...";', e.g., it begins by '-' */
 #define NON_OPT 1
 /* LONG_OPT is the code that is returned when a long option is found. */
 #define LONG_OPT 0
-- 
2.1.3


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 04/11] getopt: remove function prototypes
  2014-12-07 10:13 [PATCH 01/11] tests: copy test-suite from Frodo Looijaard's getopt Sami Kerola
  2014-12-07 10:13 ` [PATCH 02/11] tests: add more getopt tests Sami Kerola
  2014-12-07 10:13 ` [PATCH 03/11] getopt: make nonoptions optstring comment correct Sami Kerola
@ 2014-12-07 10:13 ` Sami Kerola
  2014-12-07 10:13 ` [PATCH 05/11] getopt: add struct getopt_control and remove global variables Sami Kerola
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sami Kerola @ 2014-12-07 10:13 UTC (permalink / raw)
  To: util-linux; +Cc: Sami Kerola, Frodo Looijaard

Functions are in right order so they do not need prototypes, with effect
of not needing to keep function argument changes in sync in two locations.

CC: Frodo Looijaard <frodo@frodo.looijaard.name>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 misc-utils/getopt.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/misc-utils/getopt.c b/misc-utils/getopt.c
index d7918b1..383bbd1 100644
--- a/misc-utils/getopt.c
+++ b/misc-utils/getopt.c
@@ -87,16 +87,6 @@ static int quote = 1;		/* 1 is do quote. */
 int (*getopt_long_fp) (int argc, char *const *argv, const char *optstr,
 		       const struct option * longopts, int *longindex);
 
-/* Function prototypes */
-static const char *normalize(const char *arg);
-static int generate_output(char *argv[], int argc, const char *optstr,
-			   const struct option *longopts);
-static void parse_error(const char *message);
-static void add_long_options(char *options);
-static void add_longopt(const char *name, int has_arg);
-static void print_help(void);
-static void set_shell(const char *new_shell);
-
 /*
  * This function 'normalizes' a single argument: it puts single quotes
  * around it and escapes other special characters. If quote is false, it
-- 
2.1.3


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 05/11] getopt: add struct getopt_control and remove global variables
  2014-12-07 10:13 [PATCH 01/11] tests: copy test-suite from Frodo Looijaard's getopt Sami Kerola
                   ` (2 preceding siblings ...)
  2014-12-07 10:13 ` [PATCH 04/11] getopt: remove function prototypes Sami Kerola
@ 2014-12-07 10:13 ` Sami Kerola
  2014-12-07 10:13 ` [PATCH 06/11] getopt: use xstrdup rather than malloc + strcpy Sami Kerola
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sami Kerola @ 2014-12-07 10:13 UTC (permalink / raw)
  To: util-linux; +Cc: Sami Kerola, Frodo Looijaard

CC: Frodo Looijaard <frodo@frodo.looijaard.name>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 misc-utils/getopt.c | 164 ++++++++++++++++++++++++++--------------------------
 1 file changed, 83 insertions(+), 81 deletions(-)

diff --git a/misc-utils/getopt.c b/misc-utils/getopt.c
index 383bbd1..fcc016c 100644
--- a/misc-utils/getopt.c
+++ b/misc-utils/getopt.c
@@ -76,12 +76,20 @@
 /* The shells recognized. */
 typedef enum { BASH, TCSH } shell_t;
 
-
-/* Some global variables that tells us how to parse. */
-static shell_t shell = BASH;	/* The shell we generate output for. */
-static int quiet_errors = 0;	/* 0 is not quiet. */
-static int quiet_output = 0;	/* 0 is not quiet. */
-static int quote = 1;		/* 1 is do quote. */
+struct getopt_control {
+	shell_t shell;			/* the shell we generate output for */
+	char *optstr;			/* getopt(3) optstring */
+	struct option *long_options;	/* long options */
+	int long_options_length;	/* length of options array */
+	int long_options_nr;		/* number of used elements in array */
+	unsigned int
+		compatible:1,		/* compatibility mode for 'difficult' programs */
+		quiet_errors:1,		/* print errors */
+		quiet_output:1,		/* print output */
+		quote:1;		/* quote output */
+};
+
+enum { REALLOC_INCREMENT = 8 };
 
 /* Allow changing which getopt is in use with function pointer */
 int (*getopt_long_fp) (int argc, char *const *argv, const char *optstr,
@@ -96,7 +104,7 @@ int (*getopt_long_fp) (int argc, char *const *argv, const char *optstr,
  * exclamation marks within single quotes, and nukes whitespace. This
  * function returns a pointer to a buffer that is overwritten by each call.
  */
-static const char *normalize(const char *arg)
+static const char *normalize(const struct getopt_control *ctl, const char *arg)
 {
 	static char *BUFFER = NULL;
 	const char *argptr = arg;
@@ -104,7 +112,7 @@ static const char *normalize(const char *arg)
 
 	free(BUFFER);
 
-	if (!quote) {
+	if (!ctl->quote) {
 		/* Just copy arg */
 		BUFFER = xmalloc(strlen(arg) + 1);
 		strcpy(BUFFER, arg);
@@ -129,21 +137,21 @@ static const char *normalize(const char *arg)
 			*bufptr++ = '\\';
 			*bufptr++ = '\'';
 			*bufptr++ = '\'';
-		} else if (shell == TCSH && *argptr == '\\') {
+		} else if (ctl->shell == TCSH && *argptr == '\\') {
 			/* Backslash: replace it with: '\\' */
 			*bufptr++ = '\\';
 			*bufptr++ = '\\';
-		} else if (shell == TCSH && *argptr == '!') {
+		} else if (ctl->shell == TCSH && *argptr == '!') {
 			/* Exclamation mark: replace it with: \! */
 			*bufptr++ = '\'';
 			*bufptr++ = '\\';
 			*bufptr++ = '!';
 			*bufptr++ = '\'';
-		} else if (shell == TCSH && *argptr == '\n') {
+		} else if (ctl->shell == TCSH && *argptr == '\n') {
 			/* Newline: replace it with: \n */
 			*bufptr++ = '\\';
 			*bufptr++ = 'n';
-		} else if (shell == TCSH && isspace(*argptr)) {
+		} else if (ctl->shell == TCSH && isspace(*argptr)) {
 			/* Non-newline whitespace: replace it with \<ws> */
 			*bufptr++ = '\'';
 			*bufptr++ = '\\';
@@ -166,44 +174,43 @@ static const char *normalize(const char *arg)
  * optstr must contain the short options, and longopts the long options.
  * Other settings are found in global variables.
  */
-static int generate_output(char *argv[], int argc, const char *optstr,
-			   const struct option *longopts)
+static int generate_output(const struct getopt_control *ctl, char *argv[], int argc)
 {
 	int exit_code = EXIT_SUCCESS;	/* Assume everything will be OK */
 	int opt;
 	int longindex;
 	const char *charptr;
 
-	if (quiet_errors)
+	if (ctl->quiet_errors)
 		/* No error reporting from getopt(3) */
 		opterr = 0;
 	/* Reset getopt(3) */
 	optind = 0;
 
 	while ((opt =
-		(getopt_long_fp(argc, argv, optstr, longopts, &longindex)))
+		(getopt_long_fp(argc, argv, ctl->optstr, ctl->long_options, &longindex)))
 	       != EOF)
 		if (opt == '?' || opt == ':')
 			exit_code = GETOPT_EXIT_CODE;
-		else if (!quiet_output) {
+		else if (!ctl->quiet_output) {
 			if (opt == LONG_OPT) {
-				printf(" --%s", longopts[longindex].name);
-				if (longopts[longindex].has_arg)
-					printf(" %s", normalize(optarg ? optarg : ""));
+				printf(" --%s", ctl->long_options[longindex].name);
+				if (ctl->long_options[longindex].has_arg)
+					printf(" %s", normalize(ctl, optarg ? optarg : ""));
 			} else if (opt == NON_OPT)
-				printf(" %s", normalize(optarg ? optarg : ""));
+				printf(" %s", normalize(ctl, optarg ? optarg : ""));
 			else {
 				printf(" -%c", opt);
-				charptr = strchr(optstr, opt);
+				charptr = strchr(ctl->optstr, opt);
 				if (charptr != NULL && *++charptr == ':')
-					printf(" %s", normalize(optarg ? optarg : ""));
+					printf(" %s", normalize(ctl, optarg ? optarg : ""));
 			}
 		}
 
-	if (!quiet_output) {
+	if (!ctl->quiet_output) {
 		printf(" --");
 		while (optind < argc)
-			printf(" %s", normalize(argv[optind++]));
+			printf(" %s", normalize(ctl, argv[optind++]));
 		printf("\n");
 	}
 	return exit_code;
@@ -222,48 +229,43 @@ static void __attribute__ ((__noreturn__)) parse_error(const char *message)
 	exit(PARAMETER_EXIT_CODE);
 }
 
-static struct option *long_options = NULL;
-static int long_options_length = 0;	/* Length of array */
-static int long_options_nr = 0;		/* Nr of used elements in array */
-#define LONG_OPTIONS_INCR 10
-#define init_longopt() add_longopt(NULL,0)
 
 /* Register a long option. The contents of name is copied. */
-static void add_longopt(const char *name, int has_arg)
+static void add_longopt(struct getopt_control *ctl, const char *name, int has_arg)
 {
 	char *tmp;
 	static int flag;
 
 	if (!name) {
 		/* init */
-		free(long_options);
-		long_options = NULL;
-		long_options_length = 0;
-		long_options_nr = 0;
+		free(ctl->long_options);
+		ctl->long_options = NULL;
+		ctl->long_options_length = 0;
+		ctl->long_options_nr = 0;
 	}
 
-	if (long_options_nr == long_options_length) {
-		long_options_length += LONG_OPTIONS_INCR;
-		long_options = xrealloc(long_options,
-					sizeof(struct option) *
-					long_options_length);
+	if (ctl->long_options_nr == ctl->long_options_length) {
+		ctl->long_options_length += REALLOC_INCREMENT;
+		ctl->long_options = xrealloc(ctl->long_options,
+					     sizeof(struct option) *
+					     ctl->long_options_length);
 	}
 
-	long_options[long_options_nr].name = NULL;
-	long_options[long_options_nr].has_arg = 0;
-	long_options[long_options_nr].flag = NULL;
-	long_options[long_options_nr].val = 0;
+	ctl->long_options[ctl->long_options_nr].name = NULL;
+	ctl->long_options[ctl->long_options_nr].has_arg = 0;
+	ctl->long_options[ctl->long_options_nr].flag = NULL;
+	ctl->long_options[ctl->long_options_nr].val = 0;
 
-	if (long_options_nr && name) {
+	if (ctl->long_options_nr && name) {
 		/* Not for init! */
-		long_options[long_options_nr - 1].has_arg = has_arg;
-		long_options[long_options_nr - 1].flag = &flag;
-		long_options[long_options_nr - 1].val = long_options_nr;
+		ctl->long_options[ctl->long_options_nr - 1].has_arg = has_arg;
+		ctl->long_options[ctl->long_options_nr - 1].flag = &flag;
+		ctl->long_options[ctl->long_options_nr - 1].val = ctl->long_options_nr;
 		tmp = xmalloc(strlen(name) + 1);
 		strcpy(tmp, name);
-		long_options[long_options_nr - 1].name = tmp;
+		ctl->long_options[ctl->long_options_nr - 1].name = tmp;
 	}
-	long_options_nr++;
+	ctl->long_options_nr++;
 }
 
 
@@ -271,7 +273,7 @@ static void add_longopt(const char *name, int has_arg)
  * Register several long options. options is a string of long options,
  * separated by commas or whitespace. This nukes options!
  */
-static void add_long_options(char *options)
+static void add_long_options(struct getopt_control *ctl, char *options)
 {
 	int arg_opt;
 	char *tokptr = strtok(options, ", \t\n");
@@ -291,22 +293,22 @@ static void add_long_options(char *options)
 						    ("empty long option after "
 						     "-l or --long argument"));
 			}
-			add_longopt(tokptr, arg_opt);
+			add_longopt(ctl, tokptr, arg_opt);
 		}
 		tokptr = strtok(NULL, ", \t\n");
 	}
 }
 
-static void set_shell(const char *new_shell)
+static void set_shell(struct getopt_control *ctl, const char *new_shell)
 {
 	if (!strcmp(new_shell, "bash"))
-		shell = BASH;
+		ctl->shell = BASH;
 	else if (!strcmp(new_shell, "tcsh"))
-		shell = TCSH;
+		ctl->shell = TCSH;
 	else if (!strcmp(new_shell, "sh"))
-		shell = BASH;
+		ctl->shell = BASH;
 	else if (!strcmp(new_shell, "csh"))
-		shell = TCSH;
+		ctl->shell = TCSH;
 	else
 		parse_error(_
 			    ("unknown shell after -s or --shell argument"));
@@ -340,10 +342,12 @@ static void __attribute__ ((__noreturn__)) print_help(void)
 
 int main(int argc, char *argv[])
 {
-	char *optstr = NULL;
+	struct getopt_control ctl = {
+		.shell = BASH,
+		.quote = 1
+	};
 	char *name = NULL;
 	int opt;
-	int compatible = 0;
 
 	/* Stop scanning as soon as a non-option argument is found! */
 	static const char *shortopts = "+ao:l:n:qQs:TuhV";
@@ -367,14 +371,14 @@ int main(int argc, char *argv[])
 	textdomain(PACKAGE);
 	atexit(close_stdout);
 
-	init_longopt();
+	add_longopt(&ctl, NULL, 0);	/* init */
 	getopt_long_fp = getopt_long;
 
 	if (getenv("GETOPT_COMPATIBLE"))
-		compatible = 1;
+		ctl.compatible = 1;
 
 	if (argc == 1) {
-		if (compatible) {
+		if (ctl.compatible) {
 			/*
 			 * For some reason, the original getopt gave no
 			 * error when there were no arguments.
@@ -385,13 +389,12 @@ int main(int argc, char *argv[])
 			parse_error(_("missing optstring argument"));
 	}
 
-	if (argv[1][0] != '-' || compatible) {
-		quote = 0;
-		optstr = xmalloc(strlen(argv[1]) + 1);
-		strcpy(optstr, argv[1] + strspn(argv[1], "-+"));
+	if (argv[1][0] != '-' || ctl.compatible) {
+		ctl.quote = 0;
+		ctl.optstr = xmalloc(strlen(argv[1]) + 1);
+		strcpy(ctl.optstr, argv[1] + strspn(argv[1], "-+"));
 		argv[1] = argv[0];
-		return generate_output(argv + 1, argc - 1, optstr,
-				       long_options);
+		return generate_output(&ctl, argv + 1, argc - 1);
 	}
 
 	while ((opt =
@@ -403,12 +406,12 @@ int main(int argc, char *argv[])
 		case 'h':
 			print_help();
 		case 'o':
-			free(optstr);
-			optstr = xmalloc(strlen(optarg) + 1);
-			strcpy(optstr, optarg);
+			free(ctl.optstr);
+			ctl.optstr = xmalloc(strlen(optarg) + 1);
+			strcpy(ctl.optstr, optarg);
 			break;
 		case 'l':
-			add_long_options(optarg);
+			add_long_options(&ctl, optarg);
 			break;
 		case 'n':
 			free(name);
@@ -416,18 +419,18 @@ int main(int argc, char *argv[])
 			strcpy(name, optarg);
 			break;
 		case 'q':
-			quiet_errors = 1;
+			ctl.quiet_errors = 1;
 			break;
 		case 'Q':
-			quiet_output = 1;
+			ctl.quiet_output = 1;
 			break;
 		case 's':
-			set_shell(optarg);
+			set_shell(&ctl, optarg);
 			break;
 		case 'T':
 			return TEST_EXIT_CODE;
 		case 'u':
-			quote = 0;
+			ctl.quote = 0;
 			break;
 		case 'V':
 			printf(UTIL_LINUX_VERSION);
@@ -439,12 +442,12 @@ int main(int argc, char *argv[])
 			parse_error(_("internal error, contact the author."));
 		}
 
-	if (!optstr) {
+	if (!ctl.optstr) {
 		if (optind >= argc)
 			parse_error(_("missing optstring argument"));
 		else {
-			optstr = xmalloc(strlen(argv[optind]) + 1);
-			strcpy(optstr, argv[optind]);
+			ctl.optstr = xmalloc(strlen(argv[optind]) + 1);
+			strcpy(ctl.optstr, argv[optind]);
 			optind++;
 		}
 	}
@@ -453,6 +456,5 @@ int main(int argc, char *argv[])
 	else
 		argv[optind - 1] = argv[0];
 
-	return generate_output(argv + optind - 1, argc-optind + 1,
-			       optstr, long_options);
+	return generate_output(&ctl, argv + optind - 1, argc - optind + 1);
 }
-- 
2.1.3


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 06/11] getopt: use xstrdup rather than malloc + strcpy
  2014-12-07 10:13 [PATCH 01/11] tests: copy test-suite from Frodo Looijaard's getopt Sami Kerola
                   ` (3 preceding siblings ...)
  2014-12-07 10:13 ` [PATCH 05/11] getopt: add struct getopt_control and remove global variables Sami Kerola
@ 2014-12-07 10:13 ` Sami Kerola
  2014-12-07 10:13 ` [PATCH 07/11] getopt: make normalize() print strings Sami Kerola
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sami Kerola @ 2014-12-07 10:13 UTC (permalink / raw)
  To: util-linux; +Cc: Sami Kerola, Frodo Looijaard

CC: Frodo Looijaard <frodo@frodo.looijaard.name>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 misc-utils/getopt.c | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/misc-utils/getopt.c b/misc-utils/getopt.c
index fcc016c..4c92e30 100644
--- a/misc-utils/getopt.c
+++ b/misc-utils/getopt.c
@@ -114,8 +114,7 @@ static const char *normalize(const struct getopt_control *ctl, const char *arg)
 
 	if (!ctl->quote) {
 		/* Just copy arg */
-		BUFFER = xmalloc(strlen(arg) + 1);
-		strcpy(BUFFER, arg);
+		BUFFER = xstrdup(arg);
 		return BUFFER;
 	}
 
@@ -233,7 +232,6 @@ static void __attribute__ ((__noreturn__)) parse_error(const char *message)
 /* Register a long option. The contents of name is copied. */
 static void add_longopt(struct getopt_control *ctl, const char *name, int has_arg)
 {
-	char *tmp;
 	static int flag;
 
 	if (!name) {
@@ -261,9 +259,7 @@ static void add_longopt(struct getopt_control *ctl, const char *name, int has_ar
 		ctl->long_options[ctl->long_options_nr - 1].has_arg = has_arg;
 		ctl->long_options[ctl->long_options_nr - 1].flag = &flag;
 		ctl->long_options[ctl->long_options_nr - 1].val = ctl->long_options_nr;
-		tmp = xmalloc(strlen(name) + 1);
-		strcpy(tmp, name);
-		ctl->long_options[ctl->long_options_nr - 1].name = tmp;
+		ctl->long_options[ctl->long_options_nr - 1].name = xstrdup(name);
 	}
 	ctl->long_options_nr++;
 }
@@ -407,16 +403,14 @@ int main(int argc, char *argv[])
 			print_help();
 		case 'o':
 			free(ctl.optstr);
-			ctl.optstr = xmalloc(strlen(optarg) + 1);
-			strcpy(ctl.optstr, optarg);
+			ctl.optstr = xstrdup(optarg);
 			break;
 		case 'l':
 			add_long_options(&ctl, optarg);
 			break;
 		case 'n':
 			free(name);
-			name = xmalloc(strlen(optarg) + 1);
-			strcpy(name, optarg);
+			name = xstrdup(optarg);
 			break;
 		case 'q':
 			ctl.quiet_errors = 1;
@@ -446,8 +440,7 @@ int main(int argc, char *argv[])
 		if (optind >= argc)
 			parse_error(_("missing optstring argument"));
 		else {
-			ctl.optstr = xmalloc(strlen(argv[optind]) + 1);
-			strcpy(ctl.optstr, argv[optind]);
+			ctl.optstr = xstrdup(argv[optind]);
 			optind++;
 		}
 	}
-- 
2.1.3


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 07/11] getopt: make normalize() print strings
  2014-12-07 10:13 [PATCH 01/11] tests: copy test-suite from Frodo Looijaard's getopt Sami Kerola
                   ` (4 preceding siblings ...)
  2014-12-07 10:13 ` [PATCH 06/11] getopt: use xstrdup rather than malloc + strcpy Sami Kerola
@ 2014-12-07 10:13 ` Sami Kerola
  2014-12-07 10:13 ` [PATCH 08/11] getopt: remove unnecessary code Sami Kerola
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sami Kerola @ 2014-12-07 10:13 UTC (permalink / raw)
  To: util-linux; +Cc: Sami Kerola, Frodo Looijaard

A change towards less indirection, and a change to free allocated memory.

CC: Frodo Looijaard <frodo@frodo.looijaard.name>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 misc-utils/getopt.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/misc-utils/getopt.c b/misc-utils/getopt.c
index 4c92e30..696e87a 100644
--- a/misc-utils/getopt.c
+++ b/misc-utils/getopt.c
@@ -104,18 +104,15 @@ int (*getopt_long_fp) (int argc, char *const *argv, const char *optstr,
  * exclamation marks within single quotes, and nukes whitespace. This
  * function returns a pointer to a buffer that is overwritten by each call.
  */
-static const char *normalize(const struct getopt_control *ctl, const char *arg)
+static void normalize(const struct getopt_control *ctl, const char *arg)
 {
-	static char *BUFFER = NULL;
+	char *buf;
 	const char *argptr = arg;
 	char *bufptr;
 
-	free(BUFFER);
-
 	if (!ctl->quote) {
-		/* Just copy arg */
-		BUFFER = xstrdup(arg);
-		return BUFFER;
+		printf(" %s", arg);
+		return;
 	}
 
 	/*
@@ -124,9 +121,9 @@ static const char *normalize(const struct getopt_control *ctl, const char *arg)
 	 * and an opening quote! We need also the global opening and closing
 	 * quote, and one extra character for '\0'.
 	 */
-	BUFFER = xmalloc(strlen(arg) * 4 + 3);
+	buf = xmalloc(strlen(arg) * 4 + 3);
 
-	bufptr = BUFFER;
+	bufptr = buf;
 	*bufptr++ = '\'';
 
 	while (*argptr) {
@@ -163,7 +160,8 @@ static const char *normalize(const struct getopt_control *ctl, const char *arg)
 	}
 	*bufptr++ = '\'';
 	*bufptr++ = '\0';
-	return BUFFER;
+	printf(" %s", buf);
+	free(buf);
 }
 
 /*
@@ -195,21 +193,21 @@ static int generate_output(const struct getopt_control *ctl, char *argv[], int a
 			if (opt == LONG_OPT) {
 				printf(" --%s", ctl->long_options[longindex].name);
 				if (ctl->long_options[longindex].has_arg)
-					printf(" %s", normalize(ctl, optarg ? optarg : ""));
+					normalize(ctl, optarg ? optarg : "");
 			} else if (opt == NON_OPT)
-				printf(" %s", normalize(ctl, optarg ? optarg : ""));
+				normalize(ctl, optarg ? optarg : "");
 			else {
 				printf(" -%c", opt);
 				charptr = strchr(ctl->optstr, opt);
 				if (charptr != NULL && *++charptr == ':')
-					printf(" %s", normalize(ctl, optarg ? optarg : ""));
+					normalize(ctl, optarg ? optarg : "");
 			}
 		}
 
 	if (!ctl->quiet_output) {
 		printf(" --");
 		while (optind < argc)
-			printf(" %s", normalize(ctl, argv[optind++]));
+			normalize(ctl, argv[optind++]);
 		printf("\n");
 	}
 	return exit_code;
-- 
2.1.3


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 08/11] getopt: remove unnecessary code
  2014-12-07 10:13 [PATCH 01/11] tests: copy test-suite from Frodo Looijaard's getopt Sami Kerola
                   ` (5 preceding siblings ...)
  2014-12-07 10:13 ` [PATCH 07/11] getopt: make normalize() print strings Sami Kerola
@ 2014-12-07 10:13 ` Sami Kerola
  2014-12-07 10:13 ` [PATCH 09/11] getopt: prefer switch-case rather than long if statement Sami Kerola
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sami Kerola @ 2014-12-07 10:13 UTC (permalink / raw)
  To: util-linux; +Cc: Sami Kerola, Frodo Looijaard

The control structure is initialized in main().

CC: Frodo Looijaard <frodo@frodo.looijaard.name>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 misc-utils/getopt.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/misc-utils/getopt.c b/misc-utils/getopt.c
index 696e87a..67603b5 100644
--- a/misc-utils/getopt.c
+++ b/misc-utils/getopt.c
@@ -232,14 +232,6 @@ static void add_longopt(struct getopt_control *ctl, const char *name, int has_ar
 {
 	static int flag;
 
-	if (!name) {
-		/* init */
-		free(ctl->long_options);
-		ctl->long_options = NULL;
-		ctl->long_options_length = 0;
-		ctl->long_options_nr = 0;
-	}
-
 	if (ctl->long_options_nr == ctl->long_options_length) {
 		ctl->long_options_length += REALLOC_INCREMENT;
 		ctl->long_options = xrealloc(ctl->long_options,
@@ -252,7 +244,7 @@ static void add_longopt(struct getopt_control *ctl, const char *name, int has_ar
 	ctl->long_options[ctl->long_options_nr].flag = NULL;
 	ctl->long_options[ctl->long_options_nr].val = 0;
 
-	if (ctl->long_options_nr && name) {
+	if (name) {
 		/* Not for init! */
 		ctl->long_options[ctl->long_options_nr - 1].has_arg = has_arg;
 		ctl->long_options[ctl->long_options_nr - 1].flag = &flag;
-- 
2.1.3


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 09/11] getopt: prefer switch-case rather than long if statement
  2014-12-07 10:13 [PATCH 01/11] tests: copy test-suite from Frodo Looijaard's getopt Sami Kerola
                   ` (6 preceding siblings ...)
  2014-12-07 10:13 ` [PATCH 08/11] getopt: remove unnecessary code Sami Kerola
@ 2014-12-07 10:13 ` Sami Kerola
  2014-12-07 10:13 ` [PATCH 10/11] getopt: change --shell argument parsing function Sami Kerola
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sami Kerola @ 2014-12-07 10:13 UTC (permalink / raw)
  To: util-linux; +Cc: Sami Kerola, Frodo Looijaard

And avoid testing same thing time after time.

CC: Frodo Looijaard <frodo@frodo.looijaard.name>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 misc-utils/getopt.c | 64 +++++++++++++++++++++++++++++++----------------------
 1 file changed, 37 insertions(+), 27 deletions(-)

diff --git a/misc-utils/getopt.c b/misc-utils/getopt.c
index 67603b5..8134558 100644
--- a/misc-utils/getopt.c
+++ b/misc-utils/getopt.c
@@ -122,42 +122,49 @@ static void normalize(const struct getopt_control *ctl, const char *arg)
 	 * quote, and one extra character for '\0'.
 	 */
 	buf = xmalloc(strlen(arg) * 4 + 3);
-
 	bufptr = buf;
-	*bufptr++ = '\'';
 
-	while (*argptr) {
+	for (*bufptr++ = '\''; *argptr; argptr++) {
+		if (ctl->shell == TCSH) {
+			switch (*argptr) {
+			case '\\':
+				/* Backslash: replace it with: '\\' */
+				*bufptr++ = '\\';
+				*bufptr++ = '\\';
+				continue;
+			case '!':
+				/* Exclamation mark: replace it with: \! */
+				*bufptr++ = '\'';
+				*bufptr++ = '\\';
+				*bufptr++ = '!';
+				*bufptr++ = '\'';
+				continue;
+			case '\n':
+				/* Newline: replace it with: \n */
+				*bufptr++ = '\\';
+				*bufptr++ = 'n';
+				continue;
+			}
+			if (isspace(*argptr)) {
+				/* Non-newline whitespace: replace it with \<ws> */
+				*bufptr++ = '\'';
+				*bufptr++ = '\\';
+				*bufptr++ = *argptr;
+				*bufptr++ = '\'';
+				continue;
+			}
+		}
 		if (*argptr == '\'') {
 			/* Quote: replace it with: '\'' */
 			*bufptr++ = '\'';
 			*bufptr++ = '\\';
 			*bufptr++ = '\'';
 			*bufptr++ = '\'';
-		} else if (ctl->shell == TCSH && *argptr == '\\') {
-			/* Backslash: replace it with: '\\' */
-			*bufptr++ = '\\';
-			*bufptr++ = '\\';
-		} else if (ctl->shell == TCSH && *argptr == '!') {
-			/* Exclamation mark: replace it with: \! */
-			*bufptr++ = '\'';
-			*bufptr++ = '\\';
-			*bufptr++ = '!';
-			*bufptr++ = '\'';
-		} else if (ctl->shell == TCSH && *argptr == '\n') {
-			/* Newline: replace it with: \n */
-			*bufptr++ = '\\';
-			*bufptr++ = 'n';
-		} else if (ctl->shell == TCSH && isspace(*argptr)) {
-			/* Non-newline whitespace: replace it with \<ws> */
-			*bufptr++ = '\'';
-			*bufptr++ = '\\';
-			*bufptr++ = *argptr;
-			*bufptr++ = '\'';
 		} else
 			/* Just copy */
 			*bufptr++ = *argptr;
-		argptr++;
 	}
+
 	*bufptr++ = '\'';
 	*bufptr++ = '\0';
 	printf(" %s", buf);
@@ -190,13 +197,16 @@ static int generate_output(const struct getopt_control *ctl, char *argv[], int a
 		if (opt == '?' || opt == ':')
 			exit_code = GETOPT_EXIT_CODE;
 		else if (!ctl->quiet_output) {
-			if (opt == LONG_OPT) {
+			switch (opt) {
+			case LONG_OPT:
 				printf(" --%s", ctl->long_options[longindex].name);
 				if (ctl->long_options[longindex].has_arg)
 					normalize(ctl, optarg ? optarg : "");
-			} else if (opt == NON_OPT)
+				break;
+			case NON_OPT:
 				normalize(ctl, optarg ? optarg : "");
-			else {
+				break;
+			default:
 				printf(" -%c", opt);
 				charptr = strchr(ctl->optstr, opt);
 				if (charptr != NULL && *++charptr == ':')
-- 
2.1.3


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 10/11] getopt: change --shell argument parsing function
  2014-12-07 10:13 [PATCH 01/11] tests: copy test-suite from Frodo Looijaard's getopt Sami Kerola
                   ` (7 preceding siblings ...)
  2014-12-07 10:13 ` [PATCH 09/11] getopt: prefer switch-case rather than long if statement Sami Kerola
@ 2014-12-07 10:13 ` Sami Kerola
  2014-12-07 10:13 ` [PATCH 11/11] getopt: avoid re-terminating long_option list at every update Sami Kerola
  2014-12-09 11:09 ` [PATCH 01/11] tests: copy test-suite from Frodo Looijaard's getopt Karel Zak
  10 siblings, 0 replies; 14+ messages in thread
From: Sami Kerola @ 2014-12-07 10:13 UTC (permalink / raw)
  To: util-linux; +Cc: Sami Kerola, Frodo Looijaard

Avoid passing getopt_control stucture in when returning a value is enough.

CC: Frodo Looijaard <frodo@frodo.looijaard.name>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 misc-utils/getopt.c | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/misc-utils/getopt.c b/misc-utils/getopt.c
index 8134558..2940a7d 100644
--- a/misc-utils/getopt.c
+++ b/misc-utils/getopt.c
@@ -295,19 +295,17 @@ static void add_long_options(struct getopt_control *ctl, char *options)
 	}
 }
 
-static void set_shell(struct getopt_control *ctl, const char *new_shell)
+static shell_t shell_type(const char *new_shell)
 {
 	if (!strcmp(new_shell, "bash"))
-		ctl->shell = BASH;
-	else if (!strcmp(new_shell, "tcsh"))
-		ctl->shell = TCSH;
-	else if (!strcmp(new_shell, "sh"))
-		ctl->shell = BASH;
-	else if (!strcmp(new_shell, "csh"))
-		ctl->shell = TCSH;
-	else
-		parse_error(_
-			    ("unknown shell after -s or --shell argument"));
+		return BASH;
+	if (!strcmp(new_shell, "sh"))
+		return BASH;
+	if (!strcmp(new_shell, "tcsh"))
+		return TCSH;
+	if (!strcmp(new_shell, "csh"))
+		return TCSH;
+	parse_error(_("unknown shell after -s or --shell argument"));
 }
 
 static void __attribute__ ((__noreturn__)) print_help(void)
@@ -419,7 +417,7 @@ int main(int argc, char *argv[])
 			ctl.quiet_output = 1;
 			break;
 		case 's':
-			set_shell(&ctl, optarg);
+			ctl.shell = shell_type(optarg);
 			break;
 		case 'T':
 			return TEST_EXIT_CODE;
-- 
2.1.3


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 11/11] getopt: avoid re-terminating long_option list at every update
  2014-12-07 10:13 [PATCH 01/11] tests: copy test-suite from Frodo Looijaard's getopt Sami Kerola
                   ` (8 preceding siblings ...)
  2014-12-07 10:13 ` [PATCH 10/11] getopt: change --shell argument parsing function Sami Kerola
@ 2014-12-07 10:13 ` Sami Kerola
  2014-12-08 11:37   ` Sami Kerola
  2014-12-09 11:09 ` [PATCH 01/11] tests: copy test-suite from Frodo Looijaard's getopt Karel Zak
  10 siblings, 1 reply; 14+ messages in thread
From: Sami Kerola @ 2014-12-07 10:13 UTC (permalink / raw)
  To: util-linux; +Cc: Sami Kerola, Frodo Looijaard

Terminating the ctl->long_options list once when adding options is
completed is enough.  This also allows moving ctl->long_options_nr
increment to more appropriate location.

CC: Frodo Looijaard <frodo@frodo.looijaard.name>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 misc-utils/getopt.c | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/misc-utils/getopt.c b/misc-utils/getopt.c
index 2940a7d..c484ee6 100644
--- a/misc-utils/getopt.c
+++ b/misc-utils/getopt.c
@@ -248,20 +248,13 @@ static void add_longopt(struct getopt_control *ctl, const char *name, int has_ar
 					     sizeof(struct option) *
 					     ctl->long_options_length);
 	}
-
-	ctl->long_options[ctl->long_options_nr].name = NULL;
-	ctl->long_options[ctl->long_options_nr].has_arg = 0;
-	ctl->long_options[ctl->long_options_nr].flag = NULL;
-	ctl->long_options[ctl->long_options_nr].val = 0;
-
 	if (name) {
 		/* Not for init! */
-		ctl->long_options[ctl->long_options_nr - 1].has_arg = has_arg;
-		ctl->long_options[ctl->long_options_nr - 1].flag = &flag;
-		ctl->long_options[ctl->long_options_nr - 1].val = ctl->long_options_nr;
-		ctl->long_options[ctl->long_options_nr - 1].name = xstrdup(name);
+		ctl->long_options[ctl->long_options_nr].has_arg = has_arg;
+		ctl->long_options[ctl->long_options_nr].flag = &flag;
+		ctl->long_options[ctl->long_options_nr].val = ctl->long_options_nr;
+		ctl->long_options[ctl->long_options_nr].name = xstrdup(name);
 	}
-	ctl->long_options_nr++;
 }
 
 
@@ -290,9 +283,14 @@ static void add_long_options(struct getopt_control *ctl, char *options)
 						     "-l or --long argument"));
 			}
 			add_longopt(ctl, tokptr, arg_opt);
+			ctl->long_options_nr++;
 		}
 		tokptr = strtok(NULL, ", \t\n");
 	}
+	ctl->long_options[ctl->long_options_nr].name = NULL;
+	ctl->long_options[ctl->long_options_nr].has_arg = 0;
+	ctl->long_options[ctl->long_options_nr].flag = NULL;
+	ctl->long_options[ctl->long_options_nr].val = 0;
 }
 
 static shell_t shell_type(const char *new_shell)
-- 
2.1.3


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 11/11] getopt: avoid re-terminating long_option list at every update
  2014-12-07 10:13 ` [PATCH 11/11] getopt: avoid re-terminating long_option list at every update Sami Kerola
@ 2014-12-08 11:37   ` Sami Kerola
  2014-12-08 20:05     ` Sami Kerola
  0 siblings, 1 reply; 14+ messages in thread
From: Sami Kerola @ 2014-12-08 11:37 UTC (permalink / raw)
  To: util-linux; +Cc: Sami Kerola, Frodo Looijaard

On 7 December 2014 at 10:13, Sami Kerola <kerolasa@iki.fi> wrote:
[snip]
> diff --git a/misc-utils/getopt.c b/misc-utils/getopt.c
[snip]
> @@ -290,9 +283,14 @@ static void add_long_options(struct getopt_control *ctl, char *options)
>                                                      "-l or --long argument"));
>                         }
>                         add_longopt(ctl, tokptr, arg_opt);
> +                       ctl->long_options_nr++;
>                 }
>                 tokptr = strtok(NULL, ", \t\n");
>         }
> +       ctl->long_options[ctl->long_options_nr].name = NULL;
> +       ctl->long_options[ctl->long_options_nr].has_arg = 0;
> +       ctl->long_options[ctl->long_options_nr].flag = NULL;
> +       ctl->long_options[ctl->long_options_nr].val = 0;
>  }
>
>  static shell_t shell_type(const char *new_shell)
> --
> 2.1.3

Sorry Karel, the submission was incorrect. With the change I sent
add_long_options() could overflow. Here is fix to the issue.

@@ -290,9 +283,15 @@ static void add_long_options(struct
getopt_control *ctl, char *options)
                                                     "-l or --long argument"));
                        }
                        add_longopt(ctl, tokptr, arg_opt);
+                       ctl->long_options_nr++;
                }
                tokptr = strtok(NULL, ", \t\n");
        }
+       add_longopt(&ctl, NULL, 0);     /* ensure long_options[] is not full */
+       ctl->long_options[ctl->long_options_nr].name = NULL;
+       ctl->long_options[ctl->long_options_nr].has_arg = 0;
+       ctl->long_options[ctl->long_options_nr].flag = NULL;
+       ctl->long_options[ctl->long_options_nr].val = 0;
 }

Also available from:

https://github.com/kerolasa/lelux-utiliteetit/commit/9ddfa7e4a7e3e1936688596e14c1632a034b733e

or if you want I can re-submit the patch when I am not in office
network (that has 'lets make life impossible' firewall design).

-- 
Sami Kerola
http://www.iki.fi/kerolasa/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 11/11] getopt: avoid re-terminating long_option list at every update
  2014-12-08 11:37   ` Sami Kerola
@ 2014-12-08 20:05     ` Sami Kerola
  0 siblings, 0 replies; 14+ messages in thread
From: Sami Kerola @ 2014-12-08 20:05 UTC (permalink / raw)
  To: util-linux; +Cc: Frodo Looijaard

On Mon, 8 Dec 2014, Sami Kerola wrote:
> Sorry Karel, the submission was incorrect. With the change I sent 
> add_long_options() could overflow. Here is fix to the issue.
[snip]
> or if you want I can re-submit the patch when I am not in office

Here is the resubmission I promised.

--->8----
From: Sami Kerola <kerolasa@iki.fi>
Date: Sun, 7 Dec 2014 09:55:08 +0000
Subject: [PATCH] getopt: avoid re-terminating long_option list at every update

Terminating the ctl->long_options list once when adding options is
completed is enough.  This also allows moving ctl->long_options_nr
increment to more appropriate location.

CC: Frodo Looijaard <frodo@frodo.looijaard.name>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
  misc-utils/getopt.c | 21 ++++++++++-----------
  1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/misc-utils/getopt.c b/misc-utils/getopt.c
index 2940a7d..7f26792 100644
--- a/misc-utils/getopt.c
+++ b/misc-utils/getopt.c
@@ -248,20 +248,13 @@ static void add_longopt(struct getopt_control *ctl, const char *name, int has_ar
  					     sizeof(struct option) *
  					     ctl->long_options_length);
  	}
-
-	ctl->long_options[ctl->long_options_nr].name = NULL;
-	ctl->long_options[ctl->long_options_nr].has_arg = 0;
-	ctl->long_options[ctl->long_options_nr].flag = NULL;
-	ctl->long_options[ctl->long_options_nr].val = 0;
-
  	if (name) {
  		/* Not for init! */
-		ctl->long_options[ctl->long_options_nr - 1].has_arg = has_arg;
-		ctl->long_options[ctl->long_options_nr - 1].flag = &flag;
-		ctl->long_options[ctl->long_options_nr - 1].val = ctl->long_options_nr;
-		ctl->long_options[ctl->long_options_nr - 1].name = xstrdup(name);
+		ctl->long_options[ctl->long_options_nr].has_arg = has_arg;
+		ctl->long_options[ctl->long_options_nr].flag = &flag;
+		ctl->long_options[ctl->long_options_nr].val = ctl->long_options_nr;
+		ctl->long_options[ctl->long_options_nr].name = xstrdup(name);
  	}
-	ctl->long_options_nr++;
  }


@@ -290,9 +283,15 @@ static void add_long_options(struct getopt_control *ctl, char *options)
  						     "-l or --long argument"));
  			}
  			add_longopt(ctl, tokptr, arg_opt);
+			ctl->long_options_nr++;
  		}
  		tokptr = strtok(NULL, ", \t\n");
  	}
+	add_longopt(&ctl, NULL, 0);	/* ensure long_options[] is not full */
+	ctl->long_options[ctl->long_options_nr].name = NULL;
+	ctl->long_options[ctl->long_options_nr].has_arg = 0;
+	ctl->long_options[ctl->long_options_nr].flag = NULL;
+	ctl->long_options[ctl->long_options_nr].val = 0;
  }

  static shell_t shell_type(const char *new_shell)
-- 
2.1.3


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 01/11] tests: copy test-suite from Frodo Looijaard's getopt
  2014-12-07 10:13 [PATCH 01/11] tests: copy test-suite from Frodo Looijaard's getopt Sami Kerola
                   ` (9 preceding siblings ...)
  2014-12-07 10:13 ` [PATCH 11/11] getopt: avoid re-terminating long_option list at every update Sami Kerola
@ 2014-12-09 11:09 ` Karel Zak
  10 siblings, 0 replies; 14+ messages in thread
From: Karel Zak @ 2014-12-09 11:09 UTC (permalink / raw)
  To: Sami Kerola; +Cc: util-linux, Frodo Looijaard

On Sun, Dec 07, 2014 at 10:13:45AM +0000, Sami Kerola wrote:
> Reference: svn://svn.frodo.looijaard.name/public/getopt/trunk/tests
> CC: Frodo Looijaard <frodo@frodo.looijaard.name>
> Signed-off-by: Sami Kerola <kerolasa@iki.fi>

 All github patches from 2014wk48 merged, thanks!

    Karel

-- 
 Karel Zak  <kzak@redhat.com>
 http://karelzak.blogspot.com

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2014-12-09 11:09 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-07 10:13 [PATCH 01/11] tests: copy test-suite from Frodo Looijaard's getopt Sami Kerola
2014-12-07 10:13 ` [PATCH 02/11] tests: add more getopt tests Sami Kerola
2014-12-07 10:13 ` [PATCH 03/11] getopt: make nonoptions optstring comment correct Sami Kerola
2014-12-07 10:13 ` [PATCH 04/11] getopt: remove function prototypes Sami Kerola
2014-12-07 10:13 ` [PATCH 05/11] getopt: add struct getopt_control and remove global variables Sami Kerola
2014-12-07 10:13 ` [PATCH 06/11] getopt: use xstrdup rather than malloc + strcpy Sami Kerola
2014-12-07 10:13 ` [PATCH 07/11] getopt: make normalize() print strings Sami Kerola
2014-12-07 10:13 ` [PATCH 08/11] getopt: remove unnecessary code Sami Kerola
2014-12-07 10:13 ` [PATCH 09/11] getopt: prefer switch-case rather than long if statement Sami Kerola
2014-12-07 10:13 ` [PATCH 10/11] getopt: change --shell argument parsing function Sami Kerola
2014-12-07 10:13 ` [PATCH 11/11] getopt: avoid re-terminating long_option list at every update Sami Kerola
2014-12-08 11:37   ` Sami Kerola
2014-12-08 20:05     ` Sami Kerola
2014-12-09 11:09 ` [PATCH 01/11] tests: copy test-suite from Frodo Looijaard's getopt Karel Zak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).