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[1;31m%s[0m%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