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