1252995Sdteske#!/bin/sh 2252995Sdteske#- 3252995Sdteske# Copyright (c) 2012-2013 Devin Teske 4252995Sdteske# All rights reserved. 5252995Sdteske# 6252995Sdteske# Redistribution and use in source and binary forms, with or without 7252995Sdteske# modification, are permitted provided that the following conditions 8252995Sdteske# are met: 9252995Sdteske# 1. Redistributions of source code must retain the above copyright 10252995Sdteske# notice, this list of conditions and the following disclaimer. 11252995Sdteske# 2. Redistributions in binary form must reproduce the above copyright 12252995Sdteske# notice, this list of conditions and the following disclaimer in the 13252995Sdteske# documentation and/or other materials provided with the distribution. 14252995Sdteske# 15252995Sdteske# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16252995Sdteske# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17252995Sdteske# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18252995Sdteske# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19252995Sdteske# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20252995Sdteske# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21252995Sdteske# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22252995Sdteske# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23252995Sdteske# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24252995Sdteske# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25252995Sdteske# SUCH DAMAGE. 26252995Sdteske# 27252995Sdteske# $FreeBSD$ 28252995Sdteske# 29252995Sdteske############################################################ INCLUDES 30252995Sdteske 31252995Sdteske# Prevent common.subr from auto initializing debugging (this is not an inter- 32266292Sdteske# active utility so does not require debugging; also `-d' has been repurposed). 33252995Sdteske# 34252995SdteskeDEBUG_SELF_INITIALIZE=NO 35252995Sdteske 36252995SdteskeBSDCFG_SHARE="/usr/share/bsdconfig" 37252995Sdteske. $BSDCFG_SHARE/common.subr || exit 1 38252995Sdteskef_dprintf "%s: loading includes..." "$0" 39252995Sdteske 40252995SdteskeBSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="dot" 41252995Sdteskef_include_lang $BSDCFG_LIBE/include/messages.subr 42252995Sdteskef_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr 43252995Sdteske 44263791Sdteskef_index_menusel_keyword $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" ipgm && 45263791Sdteske pgm="${ipgm:-$pgm}" 46252995Sdteske 47252995Sdteske############################################################ CONFIGURATION 48252995Sdteske 49252995Sdteske# 50252995Sdteske# Location of bsdconfig(8) 51252995Sdteske# 52252995SdteskeBSDCONFIG=/usr/sbin/bsdconfig 53252995Sdteske 54252995Sdteske############################################################ GLOBALS 55252995Sdteske 56252995Sdteske# 57252995Sdteske# Options 58252995Sdteske# 59252995SdteskeSHOW_GRAPH_LABEL_DATE=1 60252995SdteskeSHOW_INCLUDES=1 61252995SdteskeSHOW_CMDLINE=1 62252995Sdteske 63252995Sdteske############################################################ FUNCTIONS 64252995Sdteske 65252995Sdteske# begin_nodelist $shape $color $fillcolor $style 66252995Sdteske# 67252995Sdteske# Create a new multi-node list rendering nodes in a specific style described by 68252995Sdteske# the arguments passed. 69252995Sdteske# 70252995Sdteskebegin_nodelist() 71252995Sdteske{ 72252995Sdteske local shape="$1" color="$2" fillcolor="$3" style="$4" 73252995Sdteske 74252995Sdteske printf "\tnode [\n" 75252995Sdteske [ "$shape" ] && 76252995Sdteske printf '\t\tshape = "%s",\n' "$shape" 77252995Sdteske [ "$color" ] && 78252995Sdteske printf '\t\tcolor = "%s",\n' "$color" 79252995Sdteske [ "$fillcolor" ] && 80252995Sdteske printf '\t\tfillcolor = "%s",\n' "$fillcolor" 81252995Sdteske [ "$style" ] && 82252995Sdteske printf '\t\tstyle = "%s",\n' "$style" 83252995Sdteske printf "\t] {\n" 84252995Sdteske} 85252995Sdteske 86252995Sdteske# print_node $node [$attributes ...] 87252995Sdteske# 88252995Sdteske# Print a node within a multi-node list. 89252995Sdteske# 90252995Sdteskeprint_node() 91252995Sdteske{ 92252995Sdteske local node="$1" 93252995Sdteske 94252995Sdteske shift 1 # node 95252995Sdteske 96252995Sdteske case "$node" in 97252995Sdteske edge) printf '\t\t%s' "$node" ;; 98252995Sdteske *) printf '\t\t"%s"' "$node" ;; 99252995Sdteske esac 100252995Sdteske 101252995Sdteske if [ $# -gt 0 ]; then 102252995Sdteske echo -n ' [' 103252995Sdteske while [ $# -gt 0 ]; do 104252995Sdteske printf " %s" "$1" 105252995Sdteske shift 1 106252995Sdteske [ $# -gt 0 ] && echo -n "," 107252995Sdteske done 108252995Sdteske echo -n " ]" 109252995Sdteske fi 110252995Sdteske 111252995Sdteske echo ";" 112252995Sdteske} 113252995Sdteske 114252995Sdteske# print_node2 $node $node [$attributes ...] 115252995Sdteske# 116252995Sdteske# Print a directed node-node connection within a multi-node list. 117252995Sdteske# 118252995Sdteskeprint_node2() 119252995Sdteske{ 120252995Sdteske local node1="$1" node2="$2" 121252995Sdteske 122252995Sdteske shift 2 # node1 node2 123252995Sdteske 124252995Sdteske printf '\t\t"%s" -> "%s"' "$node1" "$node2" 125252995Sdteske 126252995Sdteske if [ $# -gt 0 ]; then 127252995Sdteske echo -n ' [' 128252995Sdteske while [ $# -gt 0 ]; do 129252995Sdteske printf " %s" "$1" 130252995Sdteske shift 1 131252995Sdteske [ $# -gt 0 ] && echo -n "," 132252995Sdteske done 133252995Sdteske echo -n " ]" 134252995Sdteske fi 135252995Sdteske 136252995Sdteske echo ";" 137252995Sdteske} 138252995Sdteske 139252995Sdteske# end_nodelist 140252995Sdteske# 141252995Sdteske# Close a multi-node list. 142252995Sdteske# 143252995Sdteskeend_nodelist() 144252995Sdteske{ 145252995Sdteske printf "\t};\n" 146252995Sdteske} 147252995Sdteske 148252995Sdteske############################################################ MAIN 149252995Sdteske 150252995Sdteske# Incorporate rc-file if it exists 151252995Sdteske[ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc" 152252995Sdteske 153252995Sdteske# 154252995Sdteske# Process command-line arguments 155252995Sdteske# 156252995Sdteskewhile getopts cdhi flag; do 157252995Sdteske case "$flag" in 158252995Sdteske i) SHOW_INCLUDES= ;; 159252995Sdteske d) SHOW_GRAPH_LABEL_DATE= ;; 160252995Sdteske c) SHOW_CMDLINE= ;; 161252995Sdteske h|\?) f_usage $BSDCFG_LIBE/$APP_DIR/USAGE "PROGRAM_NAME" "$pgm" ;; 162252995Sdteske esac 163252995Sdteskedone 164252995Sdteskeshift $(( $OPTIND - 1 )) 165252995Sdteske 166263791Sdteskecd $BSDCFG_LIBE || f_die # Pedantic 167252995Sdteske 168252995Sdteske# 169252995Sdteske# Get a list of menu programs 170252995Sdteske# 171252995Sdteskemenu_program_list= 172252995Sdteskefor file in [0-9][0-9][0-9].*/INDEX; do 173252995Sdteske menu_program_list="$menu_program_list $( 174252995Sdteske tail -r "$file" | awk -v item="${file%%/*}" ' 175252995Sdteske /^[[:space:]]*menu_program="/ { 176252995Sdteske sub(/^.*="/, "") 177252995Sdteske sub(/"$/, "") 178252995Sdteske if ( ! $0 ) next 179252995Sdteske if ( $0 !~ "^/" ) sub(/^/, item "/") 180252995Sdteske print; exit 181252995Sdteske }' 182252995Sdteske )" 183252995Sdteskedone 184252995Sdteske 185252995Sdteske# 186252995Sdteske# Get a list of submenu programs 187252995Sdteske# 188252995Sdteskesubmenu_program_list= 189252995Sdteskefor menu_program in $menu_program_list; do 190252995Sdteske case "$menu_program" in 191252995Sdteske [0-9][0-9][0-9].*/*) : fall-through ;; 192252995Sdteske *) continue # No sub-menus we can process 193252995Sdteske esac 194252995Sdteske 195252995Sdteske submenu_program_list="$submenu_program_list $( 196252995Sdteske awk -v menu_program="$menu_program" \ 197252995Sdteske -v item="${menu_program%%/*}" \ 198252995Sdteske ' 199252995Sdteske /^menu_selection="/ { 200252995Sdteske sub(/.*\|/, "") 201252995Sdteske sub(/"$/, "") 202252995Sdteske if ( ! $0 ) next 203252995Sdteske if ( $0 !~ "^/" ) 204252995Sdteske sub(/^/, item "/") 205252995Sdteske if ( $0 == menu_program ) next 206252995Sdteske print 207252995Sdteske } 208252995Sdteske ' "${menu_program%%/*}/INDEX" 209252995Sdteske )" 210252995Sdteskedone 211252995Sdteske 212252995Sdteske# 213252995Sdteske# Get a list of command-line programs 214252995Sdteske# 215252995Sdteskecmd_program_list= 216252995Sdteskefor file in */INDEX; do 217252995Sdteske cmd_program_list="$cmd_program_list $( 218252995Sdteske awk -v item="${file%%/*}" ' 219252995Sdteske /^menu_selection="/ { 220252995Sdteske sub(/.*\|/, "") 221252995Sdteske sub(/"$/, "") 222252995Sdteske 223252995Sdteske if ( ! $0 ) next 224252995Sdteske 225252995Sdteske if ( $0 !~ "^/" ) 226252995Sdteske sub(/^/, item "/") 227252995Sdteske 228252995Sdteske print 229252995Sdteske } 230252995Sdteske ' $file 231252995Sdteske )" 232252995Sdteskedone 233252995Sdteske 234252995Sdteske# 235252995Sdteske# [Optionally] Calculate list of include files 236252995Sdteske# 237252995Sdteskeif [ "$SHOW_INCLUDES" ]; then 238252995Sdteske print_includes_awk=' 239252995Sdteske BEGIN { regex = "^f_include \\$BSDCFG_SHARE/" } 240252995Sdteske ( $0 ~ regex ) { sub(regex, ""); print } 241252995Sdteske ' # END-QUOTE 242252995Sdteske 243252995Sdteske # 244252995Sdteske # Build list of files in which to search for includes 245252995Sdteske # 246252995Sdteske file_list=$( 247252995Sdteske for file in \ 248252995Sdteske $BSDCONFIG \ 249252995Sdteske $menu_program_list \ 250252995Sdteske $submenu_program_list \ 251252995Sdteske $cmd_program_list \ 252252995Sdteske ; do 253252995Sdteske [ -e "$file" ] && echo $file 254252995Sdteske done | sort -u 255252995Sdteske ) 256252995Sdteske 257252995Sdteske # 258252995Sdteske # Build list of includes used by the above files 259252995Sdteske # 260252995Sdteske include_file_list= 261252995Sdteske for file in $file_list; do 262252995Sdteske include_file_list="$include_file_list $( 263252995Sdteske awk "$print_includes_awk" $file 264252995Sdteske )" 265252995Sdteske done 266252995Sdteske 267252995Sdteske # 268252995Sdteske # Sort the list of includes and remove duplicate entries 269252995Sdteske # 270252995Sdteske include_file_list=$( 271252995Sdteske for include_file in $include_file_list; do 272252995Sdteske echo "$include_file" 273252995Sdteske done | sort -u 274252995Sdteske ) 275252995Sdteske 276252995Sdteske # 277252995Sdteske # Search previously-discovered include files for further includes 278252995Sdteske # 279252995Sdteske before="$include_file_list" 280252995Sdteske while :; do 281252995Sdteske for file in $include_file_list; do 282252995Sdteske include_file_list="$include_file_list $( 283252995Sdteske awk "$print_includes_awk" $BSDCFG_SHARE/$file 284252995Sdteske )" 285252995Sdteske done 286252995Sdteske 287252995Sdteske # 288252995Sdteske # Sort list of includes and remove duplicate entries [again] 289252995Sdteske # 290252995Sdteske include_file_list=$( 291252995Sdteske for include_file in $include_file_list; do 292252995Sdteske echo "$include_file" 293252995Sdteske done | sort -u 294252995Sdteske ) 295252995Sdteske 296252995Sdteske [ "$include_file_list" = "$before" ] && break 297252995Sdteske before="$include_file_list" 298252995Sdteske done 299252995Sdteskefi 300252995Sdteske 301252995Sdteske# 302252995Sdteske# Add script.subr to includes if it exists 303252995Sdteske# 304252995Sdteske[ -f $BSDCFG_SHARE/script.subr ] && 305252995Sdteske include_file_list="$include_file_list script.subr" 306252995Sdteske 307252995Sdteske# 308252995Sdteske# Start the directional-graph (digraph) output 309252995Sdteske# 310252995Sdteskeprintf 'strict digraph "" { // Empty name to prevent SVG Auto-Tooltip\n' 311252995Sdteskelabel_format="$msg_graph_label_with_command" 312252995Sdteske[ "$SHOW_GRAPH_LABEL_DATE" ] && 313252995Sdteske label_format="$msg_graph_label_with_command_and_date" 314252995Sdteskelang="${LANG:-$LC_ALL}" 315252995Sdteskeprintf "\n\tlabel = \"$label_format\"\n" \ 316252995Sdteske "${lang:+LANG=${lang%%[$IFS]*} }bsdconfig $pgm${ARGV:+ $ARGV}" \ 317252995Sdteske "$( date +"%c %Z" )" 318252995Sdteske 319252995Sdteske# 320252995Sdteske# Print graph-specific properties 321252995Sdteske# 322252995Sdteskeprintf '\n\t/*\n\t * Graph setup and orientation\n\t */\n' 323252995Sdteskeprintf '\tlabelloc = top;\t\t// display above label at top of graph\n' 324252995Sdteskeprintf '\trankdir = LR;\t\t// create ranks left-to-right\n' 325252995Sdteskeprintf '\torientation = portrait;\t// default\n' 326252995Sdteskeprintf '\tratio = fill;\t\t// approximate aspect ratio\n' 327252995Sdteskeprintf '\tcenter = 1;\t\t// center drawing on page\n' 328252995Sdteske 329252995Sdteske# 330252995Sdteske# Perform edge-concentration when displaying a lot of information 331252995Sdteske# 332252995Sdteske# NOTE: This is disabled because dot(1) version 2.28.0 (current) and older have 333252995Sdteske# a bug that causes a crash when rankdir = LR and concentrate = true 334252995Sdteske# 335252995Sdteske# NOTE: Do not re-enable until said bug is fixed in some future revision. 336252995Sdteske# 337252995Sdteske#[ "$SHOW_INCLUDES" -a "$SHOW_CMDLINE" ] && 338252995Sdteske# printf '\tconcentrate = true;\t// enable edge concentrators\n' 339252995Sdteske 340252995Sdteske# 341252995Sdteske# Print font details for graph/cluster label(s) 342252995Sdteske# 343252995Sdteskeprintf '\n\t/*\n\t * Font details for graph/cluster label(s)\n\t */\n' 344252995Sdteskeprintf '\tfontname = "Times-Italic";\n' 345252995Sdteskeprintf '\tfontsize = 14;\n' 346252995Sdteske 347252995Sdteske# 348252995Sdteske# Print default node attributes 349252995Sdteske# 350252995Sdteskeprintf '\n\t/*\n\t * Default node attributes\n\t */\n' 351252995Sdteskeprintf '\tnode [\n' 352252995Sdteskeprintf '\t\tfontname = "Times-Roman",\n' 353252995Sdteskeprintf '\t\tfontsize = 12,\n' 354252995Sdteskeprintf '\t\twidth = 2.5, // arbitrary minimum width for all nodes\n' 355252995Sdteskeprintf '\t\tfixedsize, // turn minimum width into exact width\n' 356252995Sdteskeprintf '\t];\n' 357252995Sdteske 358252995Sdteske# 359252995Sdteske# Print top-level item(s) 360252995Sdteske# 361252995Sdteskeprintf '\n\t/*\n\t * bsdconfig(8)\n\t */\n' 362252995Sdteskeshape=circle color=black fillcolor=yellow style=filled 363252995Sdteskebegin_nodelist "$shape" "$color" "$fillcolor" "$style" 364252995Sdteskeprint_node "bsdconfig" "fontname = \"Times-Bold\"" "fontsize = 16" 365252995Sdteskeend_nodelist 366252995Sdteske 367252995Sdteske# 368252995Sdteske# Print menus 369252995Sdteske# 370252995Sdteskeprintf '\n\t/*\n\t * Menu items\n\t */\n' 371252995Sdteskeshape=box color=black fillcolor=lightblue style=filled 372252995Sdteskebegin_nodelist "$shape" "$color" "$fillcolor" "$style" 373252995Sdteskefor menu_program in $menu_program_list; do 374252995Sdteske print_node "$menu_program" "label = \"${menu_program#*/}\"" 375252995Sdteskedone 376252995Sdteskeend_nodelist 377252995Sdteske 378252995Sdteske# 379252995Sdteske# Print sub-menus 380252995Sdteske# 381252995Sdteskeprintf '\n\t/*\n\t * Sub-menu items\n\t */\n' 382252995Sdteskeshape=box color=black fillcolor=lightblue style=filled 383252995Sdteskebegin_nodelist "$shape" "$color" "$fillcolor" "$style" 384252995Sdteskefor submenu_program in $submenu_program_list; do 385252995Sdteske print_node "$submenu_program" "label = \"${submenu_program#*/}\"" 386252995Sdteskedone 387252995Sdteskeend_nodelist 388252995Sdteske 389252995Sdteske# 390252995Sdteske# Print menu relationships 391252995Sdteske# 392252995Sdteskeprintf '\n\t/*\n\t * Menu item relationships\n\t */\n' 393252995Sdteskeshape=box color=black fillcolor=lightblue style=filled edge_color=blue 394252995Sdteskebegin_nodelist "$shape" "$color" "$fillcolor" "$style" 395252995Sdteskeprint_node edge "penwidth = 5.0" "style = bold" "color = $edge_color" 396252995Sdteskefor menu_program in $menu_program_list; do 397252995Sdteske print_node2 "bsdconfig" "$menu_program" 398252995Sdteskedone 399252995Sdteskeend_nodelist 400252995Sdteske 401252995Sdteske# 402252995Sdteske# Print sub-menu relationships 403252995Sdteske# 404252995Sdteskeprintf '\n\t/*\n\t * Sub-menu item relationships\n\t */\n' 405252995Sdteskeshape=box color=black fillcolor=lightblue style=filled edge_color=blue 406252995Sdteskebegin_nodelist "$shape" "$color" "$fillcolor" "$style" 407252995Sdteske# Lock sub-menu headport to the West (unless `-c' was passed) 408252995Sdteske[ "$SHOW_CMDLINE" -o ! "$SHOW_INCLUDES" ] && print_node edge "headport = w" 409252995Sdteskeprint_node edge "style = bold" "color = $edge_color" 410252995Sdteskefor submenu_program in $submenu_program_list; do 411252995Sdteske for menu_program in $menu_program_list; do 412252995Sdteske case "$menu_program" in 413252995Sdteske [0-9][0-9][0-9].*/*) : fall-through ;; 414252995Sdteske *) continue # Not a menu item 415252995Sdteske esac 416252995Sdteske 417252995Sdteske # Continue if program directories do not match 418252995Sdteske [ "${menu_program%%/*}" = "${submenu_program%%/*}" ] || 419252995Sdteske continue 420252995Sdteske 421252995Sdteske print_node2 "$menu_program" "$submenu_program" 422252995Sdteske break 423252995Sdteske done 424252995Sdteskedone 425252995Sdteskeend_nodelist 426252995Sdteske 427252995Sdteske# 428252995Sdteske# [Optionally] Print include files 429252995Sdteske# 430252995Sdteskeif [ "$SHOW_INCLUDES" ]; then 431252995Sdteske printf '\n\t/*\n\t * Include files\n\t */\n' 432252995Sdteske shape=oval color=black fillcolor=white style=filled 433252995Sdteske begin_nodelist "$shape" "$color" "$fillcolor" "$style" 434252995Sdteske printf '\t\tconstraint = false;\n' 435252995Sdteske for include_file in $include_file_list; do 436252995Sdteske print_node "$include_file" \ 437252995Sdteske "label = \"${include_file##*/}\"" 438252995Sdteske done 439252995Sdteske end_nodelist 440252995Sdteskefi 441252995Sdteske 442252995Sdteske# 443252995Sdteske# [Optionally] Print f_include() usage/relationships 444252995Sdteske# 445252995Sdteskeif [ "$SHOW_INCLUDES" ]; then 446252995Sdteske printf '\n\t/*\n\t * Include usage\n\t */\n' 447252995Sdteske shape=oval color=black fillcolor=white style=filled edge_color=grey 448252995Sdteske begin_nodelist "$shape" "$color" "$fillcolor" "$style" 449252995Sdteske print_node edge "style = dashed" "color = $edge_color" 450252995Sdteske #print_node edge "label = \"\\T\"" "fontsize = 9" 451252995Sdteske # NOTE: Edge labels are buggy on large graphs 452252995Sdteske file_list=$( 453252995Sdteske for file in \ 454252995Sdteske $BSDCONFIG \ 455252995Sdteske $menu_program_list \ 456252995Sdteske $submenu_program_list \ 457252995Sdteske $cmd_program_list \ 458252995Sdteske $include_file_list \ 459252995Sdteske ; do 460252995Sdteske [ -f "$BSDCFG_SHARE/$file" ] && 461252995Sdteske echo $BSDCFG_SHARE/$file 462252995Sdteske [ -e "$file" ] && echo $file 463252995Sdteske done | sort -u 464252995Sdteske ) 465252995Sdteske for file in $file_list; do 466252995Sdteske # Skip binary files and text files that don't use f_include() 467252995Sdteske grep -qlI f_include $file || continue 468252995Sdteske 469252995Sdteske awk \ 470252995Sdteske -v file="${file#$BSDCFG_SHARE/}" \ 471252995Sdteske -v bsdconfig="$BSDCONFIG" \ 472252995Sdteske ' 473252995Sdteske BEGIN { regex = "^f_include \\$BSDCFG_SHARE/" } 474252995Sdteske ( $0 ~ regex ) { 475252995Sdteske sub(regex, "") 476252995Sdteske if ( file == bsdconfig ) sub(".*/", "", file) 477252995Sdteske printf "\t\t\"%s\" -> \"%s\";\n", $0, file 478252995Sdteske } 479252995Sdteske ' $file 480252995Sdteske done | sort 481252995Sdteske end_nodelist 482252995Sdteskefi 483252995Sdteske 484252995Sdteske# 485252995Sdteske# Print command-line shortcuts 486252995Sdteske# 487252995Sdteskeif [ "$SHOW_CMDLINE" ]; then 488252995Sdteske printf '\n\t/*\n\t * Command-line shortcuts\n\t */\n' 489252995Sdteske shape=parallelogram color=black fillcolor=lightseagreen style=filled 490252995Sdteske begin_nodelist "$shape" "$color" "$fillcolor" "$style" 491252995Sdteske for file in */INDEX; do 492252995Sdteske awk -v item="${file%%/*}" ' 493252995Sdteske /^menu_selection="/ { 494252995Sdteske sub(/^.*="/, "") 495252995Sdteske sub(/\|.*/, "") 496252995Sdteske printf "\t\t\"bsdconfig %s\"", $0 497252995Sdteske printf " [ label = \"%s\" ];\n", $0 498252995Sdteske } 499252995Sdteske ' $file 500252995Sdteske done 501252995Sdteske end_nodelist 502252995Sdteskefi 503252995Sdteske 504252995Sdteske# 505252995Sdteske# Print command-line shortcut relationships 506252995Sdteske# 507252995Sdteskeif [ "$SHOW_CMDLINE" ]; then 508252995Sdteske printf '\n\t/*\n\t * Command-line shortcut relationships\n\t */\n' 509252995Sdteske shape=box color=black fillcolor=lightseagreen style=filled 510252995Sdteske begin_nodelist "$shape" "$color" "$fillcolor" "$style" 511252995Sdteske print_node edge "headport = w" "weight = 100.0" 512252995Sdteske print_node edge "style = bold" "color = $fillcolor" 513252995Sdteske for file in */INDEX; do 514252995Sdteske awk -v item="${file%%/*}" \ 515252995Sdteske -v node_fillcolor="$node_fillcolor" \ 516252995Sdteske -v edge_color="$edge_color" \ 517252995Sdteske ' 518252995Sdteske /^menu_selection="/ { 519252995Sdteske sub(/^.*="/, "") 520252995Sdteske sub(/"$/, "") 521252995Sdteske 522252995Sdteske if ( ! $0 ) next 523252995Sdteske 524252995Sdteske split($0, menusel, "|") 525252995Sdteske if ( menusel[2] !~ "^/" ) 526252995Sdteske sub(/^/, item "/", menusel[2]) 527252995Sdteske 528252995Sdteske printf "\t\t\"bsdconfig %s\" -> \"%s\";\n", 529252995Sdteske menusel[1], menusel[2] 530252995Sdteske } 531252995Sdteske ' $file 532252995Sdteske done 533252995Sdteske end_nodelist 534252995Sdteskefi 535252995Sdteske 536252995Sdteske# 537252995Sdteske# Print clusters 538252995Sdteske# 539252995Sdteskebgcolor_bsdconfig="lightyellow" 540252995Sdteskebgcolor_includes="gray98" 541252995Sdteskebgcolor_menuitem="aliceblue" 542252995Sdteskebgcolor_shortcuts="honeydew" 543252995Sdteskeprintf '\n\t/*\n\t * Clusters\n\t */\n' 544252995Sdteskeprintf '\tsubgraph "cluster_bsdconfig" {\n' 545252995Sdteskeprintf '\t\tbgcolor = "%s";\n' "$bgcolor_bsdconfig" 546252995Sdteskeprintf '\t\tlabel = "bsdconfig(8)";\n' 547252995Sdteskeprintf '\t\ttooltip = "bsdconfig(8)";\n' 548252995Sdteskeprint_node "bsdconfig" 549252995Sdteskeif [ "$SHOW_INCLUDES" ]; then 550252995Sdteske printf '\t\tsubgraph "cluster_includes" {\n' 551252995Sdteske printf '\t\t\tbgcolor = "%s";\n' "$bgcolor_includes" 552252995Sdteske printf '\t\t\tlabel = "%s";\n' "$msg_includes" 553252995Sdteske 554252995Sdteske for include_file in $include_file_list; do 555252995Sdteske echo $include_file 556252995Sdteske done | awk -v bgcolor="$bgcolor_bsdconfig" ' 557252995Sdteske BEGIN { created = 0 } 558252995Sdteske function end_subgraph() { printf "\t\t\t};\n" } 559252995Sdteske ( $0 !~ "/" ) { 560252995Sdteske if ( ! created ) 561252995Sdteske { 562252995Sdteske printf "\t\t\tsubgraph \"%s\" {\n", 563252995Sdteske "cluster_bsdconfig_includes" 564252995Sdteske printf "\t\t\t\tbgcolor = \"%s\";\n", bgcolor 565252995Sdteske printf "\t\t\t\tlabel = \"bsdconfig\";\n" 566252995Sdteske created++ 567252995Sdteske } 568252995Sdteske printf "\t\t\t\t\"%s\";\n", $1 569252995Sdteske } 570252995Sdteske END { created && end_subgraph() }' 571252995Sdteske 572252995Sdteske for include_file in $include_file_list; do 573252995Sdteske echo $include_file 574252995Sdteske done | awk ' 575252995Sdteske BEGIN { created = 0 } 576252995Sdteske function end_subgraph() { printf "\t\t\t};\n" } 577252995Sdteske ( $0 ~ "/" ) { 578252995Sdteske include_dir_tmp = $1 579252995Sdteske sub("/[^/]*$", "", include_dir_tmp) 580252995Sdteske gsub(/[^[:alnum:]_]/, "_", include_dir_tmp) 581252995Sdteske 582252995Sdteske if ( created && include_dir != include_dir_tmp ) 583252995Sdteske { 584252995Sdteske end_subgraph() 585252995Sdteske created = 0 586252995Sdteske } 587252995Sdteske 588252995Sdteske if ( ! created ) 589252995Sdteske { 590252995Sdteske include_dir = include_dir_tmp 591252995Sdteske printf "\t\t\tsubgraph \"cluster_%s_includes\" {\n", 592252995Sdteske include_dir 593252995Sdteske printf "\t\t\t\tbgcolor = \"white\";\n" 594252995Sdteske printf "\t\t\t\tlabel = \"%s\";\n", include_dir 595252995Sdteske created++ 596252995Sdteske } 597252995Sdteske 598252995Sdteske printf "\t\t\t\t\"%s\";\n", $1 599252995Sdteske } 600252995Sdteske END { created && end_subgraph() }' 601252995Sdteske 602252995Sdteske printf '\t\t};\n' 603252995Sdteskefi 604252995Sdteskeend_nodelist 605252995Sdteskefor INDEX in */INDEX; do 606252995Sdteske menu_title= 607252995Sdteske menu_help= 608252995Sdteske f_include_lang "$INDEX" 609252995Sdteske 610252995Sdteske item="${INDEX%%/*}" 611252995Sdteske printf '\tsubgraph "cluster_%s" {\n' "$item" 612252995Sdteske 613252995Sdteske case "$item" in 614252995Sdteske [0-9][0-9][0-9].*) bgcolor="$bgcolor_menuitem" ;; 615252995Sdteske *) bgcolor="$bgcolor_shortcuts" 616252995Sdteske esac 617252995Sdteske printf '\t\tbgcolor = "%s";\n' "$bgcolor" 618252995Sdteske if [ "$menu_title" ]; then 619252995Sdteske printf '\t\tlabel = "%s\\n\\"%s\\"";\n' "$item" "$menu_title" 620252995Sdteske else 621252995Sdteske printf '\t\tlabel = "%s";\n' "$item" 622252995Sdteske fi 623252995Sdteske printf '\t\ttooltip = "%s";\n' "${menu_help:-$item}" 624252995Sdteske 625252995Sdteske program_list=$( 626252995Sdteske for program in \ 627252995Sdteske $menu_program_list \ 628252995Sdteske $submenu_program_list \ 629252995Sdteske $cmd_program_list \ 630252995Sdteske ; do 631252995Sdteske echo "$program" 632252995Sdteske done | sort -u 633252995Sdteske ) 634252995Sdteske for program in $program_list; do 635252995Sdteske case "$program" in "$item"/*) 636252995Sdteske print_node "$program" "label = \"${program#*/}\"" 637252995Sdteske esac 638252995Sdteske done 639252995Sdteske 640252995Sdteske if [ "$SHOW_INCLUDES" ]; then 641252995Sdteske item_include_list= 642252995Sdteske [ -d "$item/include" ] && 643252995Sdteske item_include_list=$( find "$item/include" -type f ) 644252995Sdteske item_include_list=$( 645252995Sdteske for item_include in $item_include_list; do 646252995Sdteske for include_file in $include_file_list; do 647252995Sdteske [ "$item_include" = "$include_file" ] || 648252995Sdteske continue 649252995Sdteske echo "$item_include"; break 650252995Sdteske done 651252995Sdteske done 652252995Sdteske ) 653252995Sdteske if [ "$item_include_list" ]; then 654252995Sdteske printf '\t\tsubgraph "cluster_%s_includes" {\n' "$item" 655252995Sdteske printf '\t\t\tbgcolor = "%s";\n' "$bgcolor_includes" 656252995Sdteske printf '\t\t\tlabel = "%s";\n' "$msg_includes" 657252995Sdteske fi 658252995Sdteske for item_include in $item_include_list; do 659252995Sdteske printf '\t\t\t"%s";\n' "$item_include" 660252995Sdteske done 661252995Sdteske [ "$item_include_list" ] && printf '\t\t};\n' 662252995Sdteske fi 663252995Sdteske 664252995Sdteske if [ "$SHOW_CMDLINE" ]; then 665252995Sdteske printf '\t\tsubgraph "cluster_%s_shortcuts" {\n' "$item" 666252995Sdteske printf '\t\t\tbgcolor = "%s";\n' "$bgcolor_shortcuts" 667252995Sdteske printf '\t\t\tlabel = "%s";\n' "$msg_shortcuts" 668252995Sdteske awk '/^menu_selection="/ { 669252995Sdteske sub(/^.*="/, "") 670252995Sdteske sub(/\|.*/, "") 671252995Sdteske printf "\t\t\t\"bsdconfig %s\";\n", $0 672252995Sdteske }' "$INDEX" 673252995Sdteske printf '\t\t};\n' 674252995Sdteske fi 675252995Sdteske 676252995Sdteske end_nodelist 677252995Sdteskedone 678252995Sdteske 679252995Sdteskeprintf '\n};\n' 680252995Sdteske 681252995Sdteske################################################################################ 682252995Sdteske# END 683252995Sdteske################################################################################ 684