]>
Commit | Line | Data |
---|---|---|
ea6c96fb SK |
1 | #!/bin/bash |
2 | # | |
3 | # Find all man pages, and check they do not have groff syntax errors | |
4 | # or warnings. | |
5 | # | |
6 | # Sami Kerola <kerolasa@iki.fi> | |
7 | ||
8 | set -e # exit on errors | |
9 | set -o pipefail # exit if pipe writer fails | |
10 | set -u # disallow usage of unset variables | |
11 | set -C # disallow redirection file overwriting | |
12 | SCRIPT_INVOCATION_SHORT_NAME=$(basename ${0}) | |
13 | trap 'echo "${SCRIPT_INVOCATION_SHORT_NAME}: exit on error"; exit 1' ERR | |
14 | ||
15 | usage() { | |
12cc556b SK |
16 | echo "Usage: ${0} [-vVh]" |
17 | echo " -v verbose messaging" | |
18 | echo " -V print version and exit" | |
19 | echo " -h print this help and exit" | |
ea6c96fb SK |
20 | } |
21 | ||
12cc556b SK |
22 | VERBOSE='false' |
23 | while getopts vVh OPTIONS; do | |
ea6c96fb | 24 | case ${OPTIONS} in |
12cc556b SK |
25 | v) |
26 | VERBOSE='true' | |
27 | ;; | |
28 | V) | |
29 | echo "util-linux: ${SCRIPT_INVOCATION_SHORT_NAME}: 2" | |
30 | exit 0 | |
ea6c96fb SK |
31 | ;; |
32 | h) | |
33 | usage | |
34 | exit 0 | |
35 | ;; | |
36 | *) | |
37 | usage | |
38 | exit 1 | |
39 | esac | |
40 | done | |
41 | ||
42 | ERROR_FILE=$(mktemp ${SCRIPT_INVOCATION_SHORT_NAME}.XXXXXXXXXX) | |
43 | # remove tmp file at exit | |
44 | trap "rm -f ${ERROR_FILE}" 0 | |
45 | ||
eb706969 SK |
46 | # Try to find missing manuals matching build targets with manual files. |
47 | declare -A MAN_LIST BIN_LIST | |
48 | ||
12cc556b SK |
49 | COUNT_ERRORS=0 |
50 | declare -a REPEATS | |
51 | declare -A KNOWN_REPEATS | |
52 | KNOWN_REPEATS[mount.8]='foo' | |
53 | KNOWN_REPEATS[sfdisk.8]="0 <c,h,s>" | |
54 | KNOWN_REPEATS[flock.1]='"$0"' | |
55 | KNOWN_REPEATS[switch_root.8]='$DIR' | |
56 | ||
57 | remove_repeats() | |
58 | { | |
59 | set +u | |
60 | for KN in ${KNOWN_REPEATS[${I##*/}]}; do | |
61 | if [ "${KN}" = "${REPEATS[$1]}" ]; then | |
62 | if $VERBOSE; then | |
63 | echo "info: ${I} removing repeat: ${REPEATS[$1]}" | |
64 | fi | |
65 | unset REPEATS[$1] | |
66 | fi | |
67 | done | |
68 | set -u | |
69 | } | |
70 | ||
ea6c96fb SK |
71 | for I in $( |
72 | find $(git rev-parse --show-toplevel) -name '*.[1-8]' | | |
4cf02b65 | 73 | egrep -v '(Documentation|.git|/.libs/|autom4te.cache)' |
ea6c96fb | 74 | ); do |
eb706969 SK |
75 | MAN_FILE=${I##*/} |
76 | MAN_LIST[${MAN_FILE%%.[0-9]}]=1 | |
12cc556b SK |
77 | if awk '{if (1 < NR) {exit 1}; if ($1 ~ /^.so$/) {exit 0}}' ${I}; then |
78 | # Some manuals, such as x86_64, call inclusion and they | |
79 | # should not be tested any further. | |
80 | if ${VERBOSE}; then | |
eb706969 | 81 | printf "skipping: ${I##*util-linux/}: includes " |
12cc556b | 82 | awk '{print $2}' ${I} |
ea6c96fb SK |
83 | fi |
84 | continue | |
85 | fi | |
12cc556b SK |
86 | I_ERR=0 |
87 | if ${VERBOSE}; then | |
ea6c96fb | 88 | echo "testing: ${I}" |
ea6c96fb | 89 | fi |
12cc556b SK |
90 | MANWIDTH=80 man --warnings=all ${I} >/dev/null 2>| ${ERROR_FILE} |
91 | if [ -s ${ERROR_FILE} ]; then | |
eb706969 | 92 | echo "error: run: man --warnings=all ${I##*util-linux/} >/dev/null" >&2 |
12cc556b SK |
93 | I_ERR=1 |
94 | fi | |
95 | if ! lexgrog ${I} >/dev/null; then | |
eb706969 | 96 | echo "error: run: lexgrog ${I##*util-linux/}" >&2 |
12cc556b SK |
97 | I_ERR=1 |
98 | fi | |
99 | REPEATS=( $(MANWIDTH=2000 man -l ${I} | | |
100 | col -b | | |
101 | sed -e 's/\s\+/\n/g; /^$/d' | | |
102 | awk 'BEGIN { p="" } { if (0 < length($0)) { if (p == $0) { print } } p = $0 }') ) | |
103 | if [ 0 -lt "${#REPEATS[@]}" ]; then | |
104 | ITER=${#REPEATS[@]} | |
105 | while [ -1 -lt ${ITER} ]; do | |
106 | remove_repeats ${ITER} | |
107 | # The 'let' may cause exit on error. | |
108 | # When ITER == 0 -> let returns 1, bash bug? | |
109 | let ITER=${ITER}-1 || true | |
110 | done | |
111 | if [ 0 -lt "${#REPEATS[@]}" ]; then | |
eb706969 | 112 | echo "warning: ${I##*util-linux/} has repeating words: ${REPEATS[@]}" |
12cc556b SK |
113 | fi |
114 | fi | |
115 | # The 'let' may cause exit on error. | |
116 | # COUNT_ERRORS=0; let COUNT_ERRORS=$COUNT_ERRORS+0; echo $? | |
117 | # Is this a bash bug? | |
118 | let COUNT_ERRORS=$COUNT_ERRORS+$I_ERR || true | |
ea6c96fb SK |
119 | done |
120 | ||
eb706969 SK |
121 | # Create a list of build targets. |
122 | for I in $(find $(git rev-parse --show-toplevel) -name 'Make*.am' | xargs awk ' | |
123 | $1 ~ /_SOURCES/ { | |
124 | if ($1 ~ /^test/ || | |
125 | $1 ~ /^no(inst|dist)/ || | |
126 | $1 ~ /^sample/ || | |
127 | $1 ~ /^BUILT/) { | |
128 | next | |
129 | } | |
130 | sub(/_SOURCES/, "") | |
131 | if ($1 ~ /^lib.*_la/) { | |
132 | next | |
133 | } | |
134 | sub(/_static/, "") | |
135 | gsub(/_/, ".") | |
136 | sub(/switch.root/, "switch_root") | |
137 | sub(/pivot.root/, "pivot_root") | |
138 | print $1 | |
139 | }'); do | |
140 | BIN_LIST[$I]=1 | |
141 | done | |
142 | ||
143 | # Find if build target does not have manual. | |
144 | set +u | |
145 | for I in ${!BIN_LIST[@]}; do | |
146 | if [ -v ${MAN_LIST[$I]} ]; then | |
147 | echo "warning: ${I} does not have man page" | |
148 | fi | |
149 | done | |
150 | set -u | |
151 | ||
ea6c96fb | 152 | if [ ${COUNT_ERRORS} -ne 0 ]; then |
12cc556b | 153 | echo "error: ${SCRIPT_INVOCATION_SHORT_NAME}: ${COUNT_ERRORS} manuals failed" >&2 |
ea6c96fb SK |
154 | exit 1 |
155 | fi | |
156 | ||
12cc556b | 157 | if ! ${VERBOSE}; then |
ea6c96fb SK |
158 | echo "${SCRIPT_INVOCATION_SHORT_NAME}: success" |
159 | fi | |
12cc556b | 160 | |
ea6c96fb | 161 | exit 0 |