1#!/bin/sh
2#-
3# Copyright (c) 2013 Devin Teske
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
27#
28############################################################ INCLUDES
29
30# Prevent common.subr from auto initializing debugging (this is not an inter-
31# active utility that requires debugging; also `-d' has been repurposed).
32#
33DEBUG_SELF_INITIALIZE=NO
34
35BSDCFG_SHARE="/usr/share/bsdconfig"
36. $BSDCFG_SHARE/common.subr || exit 1
37f_dprintf "%s: loading includes..." "$0"
38
39BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="includes"
40f_include_lang $BSDCFG_LIBE/include/messages.subr
41f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
42
43f_index_menusel_keyword $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" ipgm &&
44	pgm="${ipgm:-$pgm}"
45
46############################################################ GLOBALS
47
48#
49# Options
50#
51USE_COLOR=1
52SHOW_DESC=
53SHOW_FUNCS=
54FUNC_PATTERN=
55
56############################################################ FUNCTIONS
57
58# show_functions $file
59#
60# Show the functions in the given include file.
61#
62show_include()
63{
64	local file="${1#./}"
65
66	local pattern="${FUNC_PATTERN:-.*}"
67	output=$( awk \
68		-v use_color=${USE_COLOR:-0} \
69		-v re="$pattern" \
70		-v show_desc=${SHOW_DESC:-0} '
71        function _asorti(src, dest)
72        {
73		k = nitems = 0;
74
75		# Copy src indices to dest and calculate array length
76		for (i in src) dest[++nitems] = i
77
78		# Sort the array of indices (dest) using insertion sort method
79		for (i = 1; i <= nitems; k = i++)
80		{
81			idx = dest[i]
82			while ((k > 0) && (dest[k] > idx))
83			{
84				dest[k+1] = dest[k]
85				k--
86			}
87			dest[k+1] = idx
88		}
89
90		return nitems
91        }
92	/^$/,/^#/ {
93		if ($0 ~ /^# f_/) {
94			if (!match($2, re)) next
95			fn = $2
96			if (use_color)
97				syntax[fn] = sprintf("+%s%s%s\n",
98				       substr($0, 2, RSTART),
99				       substr($0, 2 + RSTART, RLENGTH),
100				       substr($0, 2 + RSTART + RLENGTH))
101			else
102				syntax[fn] = "+" substr($0, 2) "\n"
103			if (show_desc)
104				print_more = 1
105			else
106				print_more = substr($0, length($0)) == "\\"
107		}
108		if (show_desc && print_more) {
109			getline
110			while ($0 ~ /^#/) {
111				syntax[fn] = syntax[fn] " " substr($0, 2) "\n"
112				getline
113			}
114			print_more = 0
115		} else while (print_more) {
116			getline
117			syntax[fn] = syntax[fn] " " substr($0, 2) "\n"
118			print_more = substr($0, length($0)) == "\\"
119		}
120	}
121	END {
122		n = _asorti(syntax, sorted_indices)
123		for (i = 1; i <= n; i++)
124			printf "%s", syntax[sorted_indices[i]]
125	}' "$file" )
126	if [ "$output" ]; then
127		if [ ! "$SHOW_FUNCS" ]; then
128			echo "$file"
129			return $SUCCESS
130		fi
131		if [ "$FUNC_PATTERN" ]; then
132			printf ">>> $msg_functions_in_matching\n" \
133			       "$file" "$FUNC_PATTERN"
134		else
135			printf ">>> $msg_functions_in\n" "$file"
136		fi
137		echo "$output"
138		echo # blank line to simplify awk(1)-based reparse
139	fi
140}
141
142############################################################ MAIN
143
144# Incorporate rc-file if it exists
145[ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc"
146
147# Are we in a terminal?
148[ -t 1 ] || USE_COLOR=
149
150#
151# Process command-line arguments
152#
153while getopts adfF:hn flag; do
154	case "$flag" in
155	a) USE_COLOR=1 ;;
156	d) SHOW_DESC=1 SHOW_FUNCS=1 ;;
157	f) SHOW_FUNCS=1 ;;
158	F) FUNC_PATTERN="$OPTARG" ;;
159	n) USE_COLOR= ;;
160	h|\?) f_usage $BSDCFG_LIBE/$APP_DIR/USAGE "PROGRAM_NAME" "$pgm" ;;
161	esac
162done
163shift $(( $OPTIND - 1 ))
164
165# cd(1) to `share' dir so relative paths work for find and positional args
166cd $BSDCFG_SHARE || f_die # Pedantic
167
168#
169# If given an argument, operate on it specifically (implied `-f') and exit
170#
171[ $# -gt 0 ] && SHOW_FUNCS=1
172for include in "$@"; do
173	# See if they've just omitted the `*.subr' suffix
174	[ -f "$include.subr" -a ! -f "$include" ] && include="$include.subr"
175	if [ ! -f "$include" ]; then
176		printf "$msg_no_such_file_or_directory\n" "$0" "$include"
177		exit $FAILURE
178	elif [ ! -r "$include" ]; then
179		printf "$msg_permission_denied\n" "$0" "$include"
180		exit $FAILURE
181	fi
182	show_include "$include" || f_die
183done
184
185# Exit if we processed some include arguments
186[ $# -gt 0 ] && exit $SUCCESS
187
188#
189# Operate an all known include files
190# NB: If we get this far, we had no include arguments
191#
192find -s . -type f -and -iname '*.subr' | while read file; do
193	if [ "$SHOW_FUNCS" -o "$FUNC_PATTERN" ]; then
194		show_include "$file"
195	else
196		echo "${file#./}"
197	fi
198done
199
200exit $SUCCESS
201
202################################################################################
203# END
204################################################################################
205