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# $FreeBSD$ 28*ed74ab27SBryan Drewery# 29*ed74ab27SBryan Drewery############################################################ INCLUDES 30*ed74ab27SBryan Drewery 31*ed74ab27SBryan Drewery# Prevent common.subr from auto initializing debugging (this is not an inter- 32*ed74ab27SBryan Drewery# active utility that requires debugging; also `-d' has been repurposed). 33*ed74ab27SBryan Drewery# 34*ed74ab27SBryan DreweryDEBUG_SELF_INITIALIZE=NO 35*ed74ab27SBryan Drewery 36*ed74ab27SBryan DreweryBSDCFG_SHARE="/usr/share/bsdconfig" 37*ed74ab27SBryan Drewery. $BSDCFG_SHARE/common.subr || exit 1 38*ed74ab27SBryan Dreweryf_dprintf "%s: loading includes..." "$0" 39*ed74ab27SBryan Drewery 40*ed74ab27SBryan DreweryBSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="includes" 41*ed74ab27SBryan Dreweryf_include_lang $BSDCFG_LIBE/include/messages.subr 42*ed74ab27SBryan Dreweryf_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr 43*ed74ab27SBryan Drewery 44*ed74ab27SBryan Dreweryf_index_menusel_keyword $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" ipgm && 45*ed74ab27SBryan Drewery pgm="${ipgm:-$pgm}" 46*ed74ab27SBryan Drewery 47*ed74ab27SBryan Drewery############################################################ GLOBALS 48*ed74ab27SBryan Drewery 49*ed74ab27SBryan Drewery# 50*ed74ab27SBryan Drewery# Options 51*ed74ab27SBryan Drewery# 52*ed74ab27SBryan DreweryUSE_COLOR=1 53*ed74ab27SBryan DrewerySHOW_DESC= 54*ed74ab27SBryan DrewerySHOW_FUNCS= 55*ed74ab27SBryan DreweryFUNC_PATTERN= 56*ed74ab27SBryan Drewery 57*ed74ab27SBryan Drewery############################################################ FUNCTIONS 58*ed74ab27SBryan Drewery 59*ed74ab27SBryan Drewery# show_functions $file 60*ed74ab27SBryan Drewery# 61*ed74ab27SBryan Drewery# Show the functions in the given include file. 62*ed74ab27SBryan Drewery# 63*ed74ab27SBryan Dreweryshow_include() 64*ed74ab27SBryan Drewery{ 65*ed74ab27SBryan Drewery local file="${1#./}" 66*ed74ab27SBryan Drewery 67*ed74ab27SBryan Drewery local pattern="${FUNC_PATTERN:-.*}" 68*ed74ab27SBryan Drewery output=$( awk \ 69*ed74ab27SBryan Drewery -v use_color=${USE_COLOR:-0} \ 70*ed74ab27SBryan Drewery -v re="$pattern" \ 71*ed74ab27SBryan Drewery -v show_desc=${SHOW_DESC:-0} ' 72*ed74ab27SBryan Drewery function _asorti(src, dest) 73*ed74ab27SBryan Drewery { 74*ed74ab27SBryan Drewery k = nitems = 0; 75*ed74ab27SBryan Drewery 76*ed74ab27SBryan Drewery # Copy src indices to dest and calculate array length 77*ed74ab27SBryan Drewery for (i in src) dest[++nitems] = i 78*ed74ab27SBryan Drewery 79*ed74ab27SBryan Drewery # Sort the array of indices (dest) using insertion sort method 80*ed74ab27SBryan Drewery for (i = 1; i <= nitems; k = i++) 81*ed74ab27SBryan Drewery { 82*ed74ab27SBryan Drewery idx = dest[i] 83*ed74ab27SBryan Drewery while ((k > 0) && (dest[k] > idx)) 84*ed74ab27SBryan Drewery { 85*ed74ab27SBryan Drewery dest[k+1] = dest[k] 86*ed74ab27SBryan Drewery k-- 87*ed74ab27SBryan Drewery } 88*ed74ab27SBryan Drewery dest[k+1] = idx 89*ed74ab27SBryan Drewery } 90*ed74ab27SBryan Drewery 91*ed74ab27SBryan Drewery return nitems 92*ed74ab27SBryan Drewery } 93*ed74ab27SBryan Drewery /^$/,/^#/ { 94*ed74ab27SBryan Drewery if ($0 ~ /^# f_/) { 95*ed74ab27SBryan Drewery if (!match($2, re)) next 96*ed74ab27SBryan Drewery fn = $2 97*ed74ab27SBryan Drewery if (use_color) 98*ed74ab27SBryan Drewery syntax[fn] = sprintf("+%s[1;31m%s[0m%s\n", 99*ed74ab27SBryan Drewery substr($0, 2, RSTART), 100*ed74ab27SBryan Drewery substr($0, 2 + RSTART, RLENGTH), 101*ed74ab27SBryan Drewery substr($0, 2 + RSTART + RLENGTH)) 102*ed74ab27SBryan Drewery else 103*ed74ab27SBryan Drewery syntax[fn] = "+" substr($0, 2) "\n" 104*ed74ab27SBryan Drewery if (show_desc) 105*ed74ab27SBryan Drewery print_more = 1 106*ed74ab27SBryan Drewery else 107*ed74ab27SBryan Drewery print_more = substr($0, length($0)) == "\\" 108*ed74ab27SBryan Drewery } 109*ed74ab27SBryan Drewery if (show_desc && print_more) { 110*ed74ab27SBryan Drewery getline 111*ed74ab27SBryan Drewery while ($0 ~ /^#/) { 112*ed74ab27SBryan Drewery syntax[fn] = syntax[fn] " " substr($0, 2) "\n" 113*ed74ab27SBryan Drewery getline 114*ed74ab27SBryan Drewery } 115*ed74ab27SBryan Drewery print_more = 0 116*ed74ab27SBryan Drewery } else while (print_more) { 117*ed74ab27SBryan Drewery getline 118*ed74ab27SBryan Drewery syntax[fn] = syntax[fn] " " substr($0, 2) "\n" 119*ed74ab27SBryan Drewery print_more = substr($0, length($0)) == "\\" 120*ed74ab27SBryan Drewery } 121*ed74ab27SBryan Drewery } 122*ed74ab27SBryan Drewery END { 123*ed74ab27SBryan Drewery n = _asorti(syntax, sorted_indices) 124*ed74ab27SBryan Drewery for (i = 1; i <= n; i++) 125*ed74ab27SBryan Drewery printf "%s", syntax[sorted_indices[i]] 126*ed74ab27SBryan Drewery }' "$file" ) 127*ed74ab27SBryan Drewery if [ "$output" ]; then 128*ed74ab27SBryan Drewery if [ ! "$SHOW_FUNCS" ]; then 129*ed74ab27SBryan Drewery echo "$file" 130*ed74ab27SBryan Drewery return $SUCCESS 131*ed74ab27SBryan Drewery fi 132*ed74ab27SBryan Drewery if [ "$FUNC_PATTERN" ]; then 133*ed74ab27SBryan Drewery printf ">>> $msg_functions_in_matching\n" \ 134*ed74ab27SBryan Drewery "$file" "$FUNC_PATTERN" 135*ed74ab27SBryan Drewery else 136*ed74ab27SBryan Drewery printf ">>> $msg_functions_in\n" "$file" 137*ed74ab27SBryan Drewery fi 138*ed74ab27SBryan Drewery echo "$output" 139*ed74ab27SBryan Drewery echo # blank line to simplify awk(1)-based reparse 140*ed74ab27SBryan Drewery fi 141*ed74ab27SBryan Drewery} 142*ed74ab27SBryan Drewery 143*ed74ab27SBryan Drewery############################################################ MAIN 144*ed74ab27SBryan Drewery 145*ed74ab27SBryan Drewery# Incorporate rc-file if it exists 146*ed74ab27SBryan Drewery[ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc" 147*ed74ab27SBryan Drewery 148*ed74ab27SBryan Drewery# Are we in a terminal? 149*ed74ab27SBryan Drewery[ -t 1 ] || USE_COLOR= 150*ed74ab27SBryan Drewery 151*ed74ab27SBryan Drewery# 152*ed74ab27SBryan Drewery# Process command-line arguments 153*ed74ab27SBryan Drewery# 154*ed74ab27SBryan Drewerywhile getopts adfF:hn flag; do 155*ed74ab27SBryan Drewery case "$flag" in 156*ed74ab27SBryan Drewery a) USE_COLOR=1 ;; 157*ed74ab27SBryan Drewery d) SHOW_DESC=1 SHOW_FUNCS=1 ;; 158*ed74ab27SBryan Drewery f) SHOW_FUNCS=1 ;; 159*ed74ab27SBryan Drewery F) FUNC_PATTERN="$OPTARG" ;; 160*ed74ab27SBryan Drewery n) USE_COLOR= ;; 161*ed74ab27SBryan Drewery h|\?) f_usage $BSDCFG_LIBE/$APP_DIR/USAGE "PROGRAM_NAME" "$pgm" ;; 162*ed74ab27SBryan Drewery esac 163*ed74ab27SBryan Drewerydone 164*ed74ab27SBryan Dreweryshift $(( $OPTIND - 1 )) 165*ed74ab27SBryan Drewery 166*ed74ab27SBryan Drewery# cd(1) to `share' dir so relative paths work for find and positional args 167*ed74ab27SBryan Drewerycd $BSDCFG_SHARE || f_die # Pedantic 168*ed74ab27SBryan Drewery 169*ed74ab27SBryan Drewery# 170*ed74ab27SBryan Drewery# If given an argument, operate on it specifically (implied `-f') and exit 171*ed74ab27SBryan Drewery# 172*ed74ab27SBryan Drewery[ $# -gt 0 ] && SHOW_FUNCS=1 173*ed74ab27SBryan Dreweryfor include in "$@"; do 174*ed74ab27SBryan Drewery # See if they've just omitted the `*.subr' suffix 175*ed74ab27SBryan Drewery [ -f "$include.subr" -a ! -f "$include" ] && include="$include.subr" 176*ed74ab27SBryan Drewery if [ ! -f "$include" ]; then 177*ed74ab27SBryan Drewery printf "$msg_no_such_file_or_directory\n" "$0" "$include" 178*ed74ab27SBryan Drewery exit $FAILURE 179*ed74ab27SBryan Drewery elif [ ! -r "$include" ]; then 180*ed74ab27SBryan Drewery printf "$msg_permission_denied\n" "$0" "$include" 181*ed74ab27SBryan Drewery exit $FAILURE 182*ed74ab27SBryan Drewery fi 183*ed74ab27SBryan Drewery show_include "$include" || f_die 184*ed74ab27SBryan Drewerydone 185*ed74ab27SBryan Drewery 186*ed74ab27SBryan Drewery# Exit if we processed some include arguments 187*ed74ab27SBryan Drewery[ $# -gt 0 ] && exit $SUCCESS 188*ed74ab27SBryan Drewery 189*ed74ab27SBryan Drewery# 190*ed74ab27SBryan Drewery# Operate an all known include files 191*ed74ab27SBryan Drewery# NB: If we get this far, we had no include arguments 192*ed74ab27SBryan Drewery# 193*ed74ab27SBryan Dreweryfind -s . -type f -and -iname '*.subr' | while read file; do 194*ed74ab27SBryan Drewery if [ "$SHOW_FUNCS" -o "$FUNC_PATTERN" ]; then 195*ed74ab27SBryan Drewery show_include "$file" 196*ed74ab27SBryan Drewery else 197*ed74ab27SBryan Drewery echo "${file#./}" 198*ed74ab27SBryan Drewery fi 199*ed74ab27SBryan Drewerydone 200*ed74ab27SBryan Drewery 201*ed74ab27SBryan Dreweryexit $SUCCESS 202*ed74ab27SBryan Drewery 203*ed74ab27SBryan Drewery################################################################################ 204*ed74ab27SBryan Drewery# END 205*ed74ab27SBryan Drewery################################################################################ 206