wmaker: replace and be replaced (ICCCM protocol)
[wmaker-crm.git] / script / check-cmdline-options-doc.sh
blobff4a4be9f1e0c15558d37735fad7afbd810ed3b0
1 #!/bin/sh
2 ###########################################################################
4 # Window Maker window manager
6 # Copyright (c) 2015 Christophe CURIS
7 # Copyright (c) 2015 Window Maker Team
9 # This program is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 2 of the License, or
12 # (at your option) any later version.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License along
20 # with this program; if not, write to the Free Software Foundation, Inc.,
21 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 ###########################################################################
25 # check-cmdline-options-doc.sh:
26 # Compare the options listed in a program's --help text against its
27 # documentation, check that all options are described and that there are
28 # not deprecated options in the doc.
30 # A know limitation is that it assumes the help text from the program is
31 # in line with what the program actually supports, because it would be too
32 # complicated to actually check also in the sources the supported options.
34 ###########################################################################
36 # For portability, we stick to the same sh+sed constraint as Autotools to
37 # limit problems, see for example:
38 # http://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Portable-Shell.html
40 ###########################################################################
42 # Report an error on stderr and exit with status 2 to tell make that we could
43 # not do what we were asked
44 arg_error() {
45 echo "`basename $0`: $@" >&2
46 exit 2
49 # print help and exit with success status
50 print_help() {
51 echo "$0: check program's list of options against its documentation"
52 echo "Usage: $0 options..."
53 echo "valid options are:"
54 echo " --ignore-prg arg : ignore option '--arg' from program's output"
55 echo " (syntax: 'arg1,arg2,... # reason', args without leading '--')"
56 echo " --man-page file : program's documentation file, in man format"
57 echo " --program name : name of the program to run with '--help'"
58 echo " --text-doc file : program's documentation file, in plain text format"
59 exit 0
62 # Extract command line arguments
63 while [ $# -gt 0 ]; do
64 case $1 in
65 --ignore-prg)
66 shift
67 echo "$1" | grep '#' > /dev/null || echo "Warning: no reason provided for --ignore-prg on \"$1\"" >&2
68 for arg in `echo "$1" | sed -e 's/#.*$// ; s/,/ /g' `
70 ignore_arg_program="$ignore_arg_program
71 --$arg"
72 done
75 --man-page)
76 shift
77 [ -z "$man_page$text_doc" ] || arg_error "only 1 documentation file can be used (option: --man-page)"
78 man_page="$1"
81 --program)
82 shift
83 [ -z "$prog_name" ] || arg_error "only 1 program can be used (option: --program)"
84 prog_name="$1"
87 --text-doc)
88 shift
89 [ -z "$man_page$text_doc" ] || arg_error "only 1 documentation file can be used (option: --text-doc)"
90 text_doc="$1"
93 -h|-help|--help) print_help ;;
94 -*) arg_error "unknow option '$1'" ;;
97 arg_error "argument '$1' is not understood"
99 esac
100 shift
101 done
103 # Check consistency of command-line
104 [ -z "$prog_name" ] && arg_error "no program given (option: --program)"
105 [ -z "$man_page$text_doc" ] && arg_error "no documentation given"
107 [ -z "$man_page" ] || [ -r "$man_page" ] || arg_error "man page file '$man_page' is not readable (option: --man-page)"
108 [ -z "$text_doc" ] || [ -r "$text_doc" ] || arg_error "text file '$text_doc' is not readable (option: --text-doc)"
110 # Make sure the program will not be searched in $PATH
111 if ! echo "$prog_name" | grep '/' > /dev/null ; then
112 prog_name="./$prog_name"
115 [ -x "$prog_name" ] || arg_error "program '$prog_name' does not exist or is not executable"
117 # Get the list of options that the program claims it supports
118 # -----------------------------------------------------------
119 # We suppose (it is common practice) that the options are listed one per line
120 # with no other text at the beginning of the line
121 # If the line contains both a short option followed by a long option, we keep only the long
122 # option because it is better to check for it
123 prog_options=`$prog_name --help | sed -n '/^[ \t]*-/ { s/^[ \t]*// ; s/^-[^-],[ \t]*--/--/ ; s/[^-A-Z_a-z0-9].*$// ; p }' `
125 [ "x$prog_options" = "x" ] && arg_error "program '$prog_name --help' did not return any option"
127 # We filter options that user wants us to, but we warn if the user asked to filter an option that is
128 # not actually present, to make sure his command line invocation stays up to date
129 for filter in $ignore_arg_program
131 if echo "$prog_options" | grep "^$filter\$" > /dev/null ; then
132 prog_options=`echo "$prog_options" | grep -v "^$filter\$" `
133 else
134 echo "Warning: program's option does not contain \"$filter\", specified in \"--ignore-prg\""
136 done
139 if [ -n "$man_page" ]; then
140 # In the man page format, the options must be grouped in the section "OPTIONS"
141 # The name of the option is on the first line after the '.TP' command
142 # The format requires the use of a backslash before the dash ('\-')
143 sed_script='/^\.SH[ \t]*"*OPTIONS"*/,/^\.SH/ {
144 /^\.TP/ {
146 s/^\.[A-Z]*//
147 s/^[ \t]*//
148 s/^\([^ \t]*\)[ \t].*$/\1/
149 s/\\-/-/g
153 doc_options=`sed -n "$sed_script" "$man_page" `
156 # If no problem is found, we will exit with status OK
157 exit_status=0
160 if [ -n "$text_doc" ]; then
161 # In the plain-text format, there is no specific identification for the options,
162 # as they may be described anywhere in the document. So we first try to get
163 # everything that looks like a long option:
164 sed_script=':restart
165 /^\(.*[^-A-Za-z_0-9]\)*--[A-Za-z0-9]/ {
167 s/^.*--/--/
168 s/[^-A-Z_a-z0-9].*$//
172 s/^\(.*\)--[A-Za-z0-9][-A-Z_a-z0-9]*/\1/
173 b restart
175 doc_options=`sed -n "$sed_script" "$text_doc" `
177 # then we also explicitely search for the short options we got from the program
178 for opt in `echo "$prog_options" | grep '^-[^-]' `
180 if grep "^\\(.*[^-A-Za-z_0-9]\\)*$opt\\([^-A-Za-z_0-9].*\\)\$" "$text_doc" > /dev/null ; then
181 doc_options="$doc_options
182 $opt"
184 done
188 # Check that all program options are documented
189 for opt in $prog_options
191 if ! echo "$doc_options" | grep "^$opt\$" > /dev/null ; then
192 echo "Error: program option '$opt' is not in the documentation '$man_page$text_doc'"
193 exit_status=1
195 done
197 # Check that all documentation options are listed by the program
198 for opt in $doc_options
200 if ! echo "$prog_options" | grep "^$opt\$" > /dev/null ; then
201 echo "Error: option '$opt' is documented, but not in '$prog_name --help'"
202 exit_status=1
204 done
206 # It is recommended to list options in alphabetical order because it is then
207 # easier to search for one
208 if [ -n "$man_page" ]; then
209 if ! echo "$doc_options" | sed -e 's/^-*//' | sort -c ; then
210 echo "Error: options are not sorted alphabetically in '$man_page'"
211 exit_status=1
215 # exit with appropriate return code, wether discrepancies were found or not
216 exit $exit_status