blob: 49d798ce7ba76220b7f50c5f08c3a25890feba15 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
#!/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.
#
# Copyright (C) 2025 Christian Goeschel Ndjomouo <cgoesc2@wgu.edu>
TOP_SRCDIR=${TOP_SRCDIR:-../}
# Directories that contain relevant source files for util-linux programs.
src_file_paths="$(grep -rE --include="*.c" --exclude="*test_*" \
--exclude-dir="lib*" \
--exclude-dir="po*" \
--exclude-dir="tests" \
--exclude-dir="tools" \
--exclude-dir="bash-completion" \
--exclude-dir=".[a-z]*" \
--exclude-dir="man-common" \
--exclude-dir="Documentation" \
--exclude-dir="build*" \
-l "getopt_long(_only)?\s*\(" \
)"
# We skip these programs because they do not make use of 'struct option longopts[]'
# which is passed to getopt(3) for command line argument parsing.
unsupported_programs='blockdev|fsck|mkfs\.cramfs|pg|renice|whereis'
# In general a program's source file name will be '<program_name>.c', however
# some tools have differing file names. To handle these special cases we build
# a hash table with the program name as the key and the actual source file name
# as the value, the latter will ultimately be passed to find_prog_src().
typeset -A canonical_src_prefix
canonical_src_prefix=( \
[su]="su-common"
)
function find_prog_src() {
local prog
prog="$1"
for p in ${src_file_paths}; do
if [[ "${p##*/}" =~ ^"${prog}".c$ ]]; then
echo "${TOP_SRCDIR}/${p}"
break
fi
done
}
function extract_long_opts() {
local src_path
src_path="$1"
awk -F ',' 'BEGIN { x = 0 }; \
/struct[[:space:]]*option[[:space:]]*.*[[:space:]]*\[\][[:space:]]*=[[:space:]]*(\{)?/ { x = 1 } \
x && ! /.*\/\*.*(deprecated|COMPLETION:no).*\*\/.*/ { print $1 } \
/\};/ { x = 0 }' "${src_path}" \
| grep -Eo '".*"' \
| tr -d '"' \
| sort \
| awk '{ printf "--%s\n", $0 }' \
| grep -v '^--_.*$'
}
function main() {
local progname
progname="$1"
if [[ "$progname" =~ $unsupported_programs ]]; then
echo "ENOTSUP"
return 0
fi
# Handle special programs that have unusual source file names
if [ -n "${canonical_src_prefix[$progname]+exists}" ]; then
progname="${canonical_src_prefix[$progname]}"
fi
src_path="$(find_prog_src "$progname")"
if [ -z "$src_path" ]; then
return 1
fi
extract_long_opts "$src_path"
return 0
}
main "$@"
|