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