1238438Sdteske#!/bin/sh 2238438Sdteske#- 3249746Sdteske# Copyright (c) 2012-2013 Devin Teske 4252980Sdteske# All rights reserved. 5238438Sdteske# 6238438Sdteske# Redistribution and use in source and binary forms, with or without 7238438Sdteske# modification, are permitted provided that the following conditions 8238438Sdteske# are met: 9238438Sdteske# 1. Redistributions of source code must retain the above copyright 10238438Sdteske# notice, this list of conditions and the following disclaimer. 11238438Sdteske# 2. Redistributions in binary form must reproduce the above copyright 12238438Sdteske# notice, this list of conditions and the following disclaimer in the 13238438Sdteske# documentation and/or other materials provided with the distribution. 14238438Sdteske# 15238438Sdteske# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16252987Sdteske# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17238438Sdteske# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18238438Sdteske# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19238438Sdteske# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20252987Sdteske# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21238438Sdteske# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22238438Sdteske# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23238438Sdteske# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24238438Sdteske# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25238438Sdteske# SUCH DAMAGE. 26238438Sdteske# 27238438Sdteske# $FreeBSD$ 28238438Sdteske# 29238438Sdteske############################################################ INCLUDES 30238438Sdteske 31249746Sdteske# Prevent common.subr from auto initializing debugging (this is not an inter- 32266290Sdteske# active utility so does not require debugging; also `-d' has been repurposed). 33249746Sdteske# 34249746SdteskeDEBUG_SELF_INITIALIZE=NO 35249746Sdteske 36240684SdteskeBSDCFG_SHARE="/usr/share/bsdconfig" 37240684Sdteske. $BSDCFG_SHARE/common.subr || exit 1 38244675Sdteskef_dprintf "%s: loading includes..." "$0" 39240684Sdteske 40240684SdteskeBSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="dot" 41238438Sdteskef_include_lang $BSDCFG_LIBE/include/messages.subr 42238438Sdteskef_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr 43238438Sdteske 44260678Sdteskef_index_menusel_keyword $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" ipgm && 45260678Sdteske pgm="${ipgm:-$pgm}" 46238438Sdteske 47238438Sdteske############################################################ CONFIGURATION 48238438Sdteske 49238438Sdteske# 50251909Sdteske# Location of bsdconfig(8) 51238438Sdteske# 52238438SdteskeBSDCONFIG=/usr/sbin/bsdconfig 53238438Sdteske 54238438Sdteske############################################################ GLOBALS 55238438Sdteske 56238438Sdteske# 57238438Sdteske# Options 58238438Sdteske# 59238438SdteskeSHOW_GRAPH_LABEL_DATE=1 60238438SdteskeSHOW_INCLUDES=1 61238438SdteskeSHOW_CMDLINE=1 62238438Sdteske 63238438Sdteske############################################################ FUNCTIONS 64238438Sdteske 65238438Sdteske# begin_nodelist $shape $color $fillcolor $style 66238438Sdteske# 67238438Sdteske# Create a new multi-node list rendering nodes in a specific style described by 68238438Sdteske# the arguments passed. 69238438Sdteske# 70238438Sdteskebegin_nodelist() 71238438Sdteske{ 72238438Sdteske local shape="$1" color="$2" fillcolor="$3" style="$4" 73238438Sdteske 74238438Sdteske printf "\tnode [\n" 75238438Sdteske [ "$shape" ] && 76238438Sdteske printf '\t\tshape = "%s",\n' "$shape" 77238438Sdteske [ "$color" ] && 78238438Sdteske printf '\t\tcolor = "%s",\n' "$color" 79238438Sdteske [ "$fillcolor" ] && 80238438Sdteske printf '\t\tfillcolor = "%s",\n' "$fillcolor" 81238438Sdteske [ "$style" ] && 82238438Sdteske printf '\t\tstyle = "%s",\n' "$style" 83238438Sdteske printf "\t] {\n" 84238438Sdteske} 85238438Sdteske 86238438Sdteske# print_node $node [$attributes ...] 87238438Sdteske# 88238438Sdteske# Print a node within a multi-node list. 89238438Sdteske# 90238438Sdteskeprint_node() 91238438Sdteske{ 92238438Sdteske local node="$1" 93238438Sdteske 94238438Sdteske shift 1 # node 95238438Sdteske 96238438Sdteske case "$node" in 97252178Sdteske edge) printf '\t\t%s' "$node" ;; 98252178Sdteske *) printf '\t\t"%s"' "$node" ;; 99238438Sdteske esac 100238438Sdteske 101238438Sdteske if [ $# -gt 0 ]; then 102238438Sdteske echo -n ' [' 103238438Sdteske while [ $# -gt 0 ]; do 104238438Sdteske printf " %s" "$1" 105238438Sdteske shift 1 106238438Sdteske [ $# -gt 0 ] && echo -n "," 107238438Sdteske done 108238438Sdteske echo -n " ]" 109238438Sdteske fi 110238438Sdteske 111238438Sdteske echo ";" 112238438Sdteske} 113238438Sdteske 114238438Sdteske# print_node2 $node $node [$attributes ...] 115238438Sdteske# 116238438Sdteske# Print a directed node-node connection within a multi-node list. 117238438Sdteske# 118238438Sdteskeprint_node2() 119238438Sdteske{ 120238438Sdteske local node1="$1" node2="$2" 121238438Sdteske 122238438Sdteske shift 2 # node1 node2 123238438Sdteske 124238438Sdteske printf '\t\t"%s" -> "%s"' "$node1" "$node2" 125238438Sdteske 126238438Sdteske if [ $# -gt 0 ]; then 127238438Sdteske echo -n ' [' 128238438Sdteske while [ $# -gt 0 ]; do 129238438Sdteske printf " %s" "$1" 130238438Sdteske shift 1 131238438Sdteske [ $# -gt 0 ] && echo -n "," 132238438Sdteske done 133238438Sdteske echo -n " ]" 134238438Sdteske fi 135238438Sdteske 136238438Sdteske echo ";" 137238438Sdteske} 138238438Sdteske 139238438Sdteske# end_nodelist 140238438Sdteske# 141238438Sdteske# Close a multi-node list. 142238438Sdteske# 143238438Sdteskeend_nodelist() 144238438Sdteske{ 145238438Sdteske printf "\t};\n" 146238438Sdteske} 147238438Sdteske 148238438Sdteske############################################################ MAIN 149238438Sdteske 150238438Sdteske# Incorporate rc-file if it exists 151238438Sdteske[ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc" 152238438Sdteske 153238438Sdteske# 154238438Sdteske# Process command-line arguments 155238438Sdteske# 156238438Sdteskewhile getopts cdhi flag; do 157238438Sdteske case "$flag" in 158252178Sdteske i) SHOW_INCLUDES= ;; 159252178Sdteske d) SHOW_GRAPH_LABEL_DATE= ;; 160252178Sdteske c) SHOW_CMDLINE= ;; 161252178Sdteske h|\?) f_usage $BSDCFG_LIBE/$APP_DIR/USAGE "PROGRAM_NAME" "$pgm" ;; 162238438Sdteske esac 163238438Sdteskedone 164238438Sdteskeshift $(( $OPTIND - 1 )) 165238438Sdteske 166260675Sdteskecd $BSDCFG_LIBE || f_die # Pedantic 167238438Sdteske 168238438Sdteske# 169238438Sdteske# Get a list of menu programs 170238438Sdteske# 171238438Sdteskemenu_program_list= 172238438Sdteskefor file in [0-9][0-9][0-9].*/INDEX; do 173238438Sdteske menu_program_list="$menu_program_list $( 174238438Sdteske tail -r "$file" | awk -v item="${file%%/*}" ' 175238438Sdteske /^[[:space:]]*menu_program="/ { 176238438Sdteske sub(/^.*="/, "") 177238438Sdteske sub(/"$/, "") 178238438Sdteske if ( ! $0 ) next 179238438Sdteske if ( $0 !~ "^/" ) sub(/^/, item "/") 180238438Sdteske print; exit 181238438Sdteske }' 182238438Sdteske )" 183238438Sdteskedone 184238438Sdteske 185238438Sdteske# 186238438Sdteske# Get a list of submenu programs 187238438Sdteske# 188238438Sdteskesubmenu_program_list= 189238438Sdteskefor menu_program in $menu_program_list; do 190238438Sdteske case "$menu_program" in 191238438Sdteske [0-9][0-9][0-9].*/*) : fall-through ;; 192238438Sdteske *) continue # No sub-menus we can process 193238438Sdteske esac 194238438Sdteske 195238438Sdteske submenu_program_list="$submenu_program_list $( 196238438Sdteske awk -v menu_program="$menu_program" \ 197238438Sdteske -v item="${menu_program%%/*}" \ 198238438Sdteske ' 199238438Sdteske /^menu_selection="/ { 200238438Sdteske sub(/.*\|/, "") 201238438Sdteske sub(/"$/, "") 202238438Sdteske if ( ! $0 ) next 203238438Sdteske if ( $0 !~ "^/" ) 204238438Sdteske sub(/^/, item "/") 205238438Sdteske if ( $0 == menu_program ) next 206238438Sdteske print 207238438Sdteske } 208238438Sdteske ' "${menu_program%%/*}/INDEX" 209238438Sdteske )" 210238438Sdteskedone 211238438Sdteske 212238438Sdteske# 213238438Sdteske# Get a list of command-line programs 214238438Sdteske# 215238438Sdteskecmd_program_list= 216238438Sdteskefor file in */INDEX; do 217238438Sdteske cmd_program_list="$cmd_program_list $( 218238438Sdteske awk -v item="${file%%/*}" ' 219238438Sdteske /^menu_selection="/ { 220238438Sdteske sub(/.*\|/, "") 221238438Sdteske sub(/"$/, "") 222238438Sdteske 223238438Sdteske if ( ! $0 ) next 224238438Sdteske 225238438Sdteske if ( $0 !~ "^/" ) 226238438Sdteske sub(/^/, item "/") 227238438Sdteske 228238438Sdteske print 229238438Sdteske } 230238438Sdteske ' $file 231238438Sdteske )" 232238438Sdteskedone 233238438Sdteske 234238438Sdteske# 235238438Sdteske# [Optionally] Calculate list of include files 236238438Sdteske# 237238438Sdteskeif [ "$SHOW_INCLUDES" ]; then 238241499Sdteske print_includes_awk=' 239241499Sdteske BEGIN { regex = "^f_include \\$BSDCFG_SHARE/" } 240241499Sdteske ( $0 ~ regex ) { sub(regex, ""); print } 241241499Sdteske ' # END-QUOTE 242241499Sdteske 243238438Sdteske # 244238438Sdteske # Build list of files in which to search for includes 245238438Sdteske # 246238438Sdteske file_list=$( 247238438Sdteske for file in \ 248238438Sdteske $BSDCONFIG \ 249238438Sdteske $menu_program_list \ 250238438Sdteske $submenu_program_list \ 251238438Sdteske $cmd_program_list \ 252272230Sdteske $BSDCFG_SHARE/script.subr \ 253238438Sdteske ; do 254238438Sdteske [ -e "$file" ] && echo $file 255238438Sdteske done | sort -u 256238438Sdteske ) 257238438Sdteske 258238438Sdteske # 259238438Sdteske # Build list of includes used by the above files 260238438Sdteske # 261238438Sdteske include_file_list= 262238438Sdteske for file in $file_list; do 263238438Sdteske include_file_list="$include_file_list $( 264250320Sdteske awk "$print_includes_awk" $file 265238438Sdteske )" 266238438Sdteske done 267238438Sdteske 268238438Sdteske # 269238438Sdteske # Sort the list of includes and remove duplicate entries 270238438Sdteske # 271238438Sdteske include_file_list=$( 272238438Sdteske for include_file in $include_file_list; do 273238438Sdteske echo "$include_file" 274238438Sdteske done | sort -u 275238438Sdteske ) 276238438Sdteske 277238438Sdteske # 278238438Sdteske # Search previously-discovered include files for further includes 279238438Sdteske # 280250321Sdteske before="$include_file_list" 281250321Sdteske while :; do 282250321Sdteske for file in $include_file_list; do 283250321Sdteske include_file_list="$include_file_list $( 284250321Sdteske awk "$print_includes_awk" $BSDCFG_SHARE/$file 285250321Sdteske )" 286250321Sdteske done 287250321Sdteske 288250321Sdteske # 289250321Sdteske # Sort list of includes and remove duplicate entries [again] 290250321Sdteske # 291250321Sdteske include_file_list=$( 292250321Sdteske for include_file in $include_file_list; do 293250321Sdteske echo "$include_file" 294250321Sdteske done | sort -u 295250321Sdteske ) 296250321Sdteske 297250321Sdteske [ "$include_file_list" = "$before" ] && break 298250321Sdteske before="$include_file_list" 299238438Sdteske done 300238438Sdteskefi 301238438Sdteske 302238438Sdteske# 303238438Sdteske# Start the directional-graph (digraph) output 304238438Sdteske# 305238438Sdteskeprintf 'strict digraph "" { // Empty name to prevent SVG Auto-Tooltip\n' 306238438Sdteskelabel_format="$msg_graph_label_with_command" 307238438Sdteske[ "$SHOW_GRAPH_LABEL_DATE" ] && 308238438Sdteske label_format="$msg_graph_label_with_command_and_date" 309238438Sdteskelang="${LANG:-$LC_ALL}" 310238438Sdteskeprintf "\n\tlabel = \"$label_format\"\n" \ 311238438Sdteske "${lang:+LANG=${lang%%[$IFS]*} }bsdconfig $pgm${ARGV:+ $ARGV}" \ 312238438Sdteske "$( date +"%c %Z" )" 313238438Sdteske 314238438Sdteske# 315238438Sdteske# Print graph-specific properties 316238438Sdteske# 317238438Sdteskeprintf '\n\t/*\n\t * Graph setup and orientation\n\t */\n' 318238438Sdteskeprintf '\tlabelloc = top;\t\t// display above label at top of graph\n' 319238438Sdteskeprintf '\trankdir = LR;\t\t// create ranks left-to-right\n' 320238438Sdteskeprintf '\torientation = portrait;\t// default\n' 321238438Sdteskeprintf '\tratio = fill;\t\t// approximate aspect ratio\n' 322238438Sdteskeprintf '\tcenter = 1;\t\t// center drawing on page\n' 323238438Sdteske 324238438Sdteske# 325238438Sdteske# Perform edge-concentration when displaying a lot of information 326238438Sdteske# 327251910Sdteske# NOTE: This is disabled because dot(1) version 2.28.0 (current) and older have 328251910Sdteske# a bug that causes a crash when rankdir = LR and concentrate = true 329238438Sdteske# 330238438Sdteske# NOTE: Do not re-enable until said bug is fixed in some future revision. 331238438Sdteske# 332238438Sdteske#[ "$SHOW_INCLUDES" -a "$SHOW_CMDLINE" ] && 333238438Sdteske# printf '\tconcentrate = true;\t// enable edge concentrators\n' 334238438Sdteske 335238438Sdteske# 336238438Sdteske# Print font details for graph/cluster label(s) 337238438Sdteske# 338238438Sdteskeprintf '\n\t/*\n\t * Font details for graph/cluster label(s)\n\t */\n' 339238438Sdteskeprintf '\tfontname = "Times-Italic";\n' 340238438Sdteskeprintf '\tfontsize = 14;\n' 341238438Sdteske 342238438Sdteske# 343238438Sdteske# Print default node attributes 344238438Sdteske# 345238438Sdteskeprintf '\n\t/*\n\t * Default node attributes\n\t */\n' 346238438Sdteskeprintf '\tnode [\n' 347238438Sdteskeprintf '\t\tfontname = "Times-Roman",\n' 348238438Sdteskeprintf '\t\tfontsize = 12,\n' 349238438Sdteskeprintf '\t\twidth = 2.5, // arbitrary minimum width for all nodes\n' 350272230Sdteskeprintf '\t\tfixedsize = true, // turn minimum width into exact width\n' 351238438Sdteskeprintf '\t];\n' 352238438Sdteske 353238438Sdteske# 354238438Sdteske# Print top-level item(s) 355238438Sdteske# 356238438Sdteskeprintf '\n\t/*\n\t * bsdconfig(8)\n\t */\n' 357238438Sdteskeshape=circle color=black fillcolor=yellow style=filled 358238438Sdteskebegin_nodelist "$shape" "$color" "$fillcolor" "$style" 359238438Sdteskeprint_node "bsdconfig" "fontname = \"Times-Bold\"" "fontsize = 16" 360238438Sdteskeend_nodelist 361238438Sdteske 362238438Sdteske# 363238438Sdteske# Print menus 364238438Sdteske# 365238438Sdteskeprintf '\n\t/*\n\t * Menu items\n\t */\n' 366238438Sdteskeshape=box color=black fillcolor=lightblue style=filled 367238438Sdteskebegin_nodelist "$shape" "$color" "$fillcolor" "$style" 368238438Sdteskefor menu_program in $menu_program_list; do 369238438Sdteske print_node "$menu_program" "label = \"${menu_program#*/}\"" 370238438Sdteskedone 371238438Sdteskeend_nodelist 372238438Sdteske 373238438Sdteske# 374238438Sdteske# Print sub-menus 375238438Sdteske# 376238438Sdteskeprintf '\n\t/*\n\t * Sub-menu items\n\t */\n' 377238438Sdteskeshape=box color=black fillcolor=lightblue style=filled 378238438Sdteskebegin_nodelist "$shape" "$color" "$fillcolor" "$style" 379238438Sdteskefor submenu_program in $submenu_program_list; do 380238438Sdteske print_node "$submenu_program" "label = \"${submenu_program#*/}\"" 381238438Sdteskedone 382238438Sdteskeend_nodelist 383238438Sdteske 384238438Sdteske# 385238438Sdteske# Print menu relationships 386238438Sdteske# 387238438Sdteskeprintf '\n\t/*\n\t * Menu item relationships\n\t */\n' 388238438Sdteskeshape=box color=black fillcolor=lightblue style=filled edge_color=blue 389238438Sdteskebegin_nodelist "$shape" "$color" "$fillcolor" "$style" 390238438Sdteskeprint_node edge "penwidth = 5.0" "style = bold" "color = $edge_color" 391238438Sdteskefor menu_program in $menu_program_list; do 392238438Sdteske print_node2 "bsdconfig" "$menu_program" 393238438Sdteskedone 394238438Sdteskeend_nodelist 395238438Sdteske 396238438Sdteske# 397238438Sdteske# Print sub-menu relationships 398238438Sdteske# 399238438Sdteskeprintf '\n\t/*\n\t * Sub-menu item relationships\n\t */\n' 400238438Sdteskeshape=box color=black fillcolor=lightblue style=filled edge_color=blue 401238438Sdteskebegin_nodelist "$shape" "$color" "$fillcolor" "$style" 402238438Sdteske# Lock sub-menu headport to the West (unless `-c' was passed) 403238438Sdteske[ "$SHOW_CMDLINE" -o ! "$SHOW_INCLUDES" ] && print_node edge "headport = w" 404238438Sdteskeprint_node edge "style = bold" "color = $edge_color" 405238438Sdteskefor submenu_program in $submenu_program_list; do 406238438Sdteske for menu_program in $menu_program_list; do 407238438Sdteske case "$menu_program" in 408238438Sdteske [0-9][0-9][0-9].*/*) : fall-through ;; 409238438Sdteske *) continue # Not a menu item 410238438Sdteske esac 411238438Sdteske 412238438Sdteske # Continue if program directories do not match 413238438Sdteske [ "${menu_program%%/*}" = "${submenu_program%%/*}" ] || 414238438Sdteske continue 415238438Sdteske 416238438Sdteske print_node2 "$menu_program" "$submenu_program" 417238438Sdteske break 418238438Sdteske done 419238438Sdteskedone 420238438Sdteskeend_nodelist 421238438Sdteske 422238438Sdteske# 423238438Sdteske# [Optionally] Print include files 424238438Sdteske# 425238438Sdteskeif [ "$SHOW_INCLUDES" ]; then 426238438Sdteske printf '\n\t/*\n\t * Include files\n\t */\n' 427238438Sdteske shape=oval color=black fillcolor=white style=filled 428238438Sdteske begin_nodelist "$shape" "$color" "$fillcolor" "$style" 429238438Sdteske printf '\t\tconstraint = false;\n' 430238438Sdteske for include_file in $include_file_list; do 431238438Sdteske print_node "$include_file" \ 432241499Sdteske "label = \"${include_file##*/}\"" 433238438Sdteske done 434238438Sdteske end_nodelist 435238438Sdteskefi 436238438Sdteske 437238438Sdteske# 438238438Sdteske# [Optionally] Print f_include() usage/relationships 439238438Sdteske# 440238438Sdteskeif [ "$SHOW_INCLUDES" ]; then 441238438Sdteske printf '\n\t/*\n\t * Include usage\n\t */\n' 442238438Sdteske shape=oval color=black fillcolor=white style=filled edge_color=grey 443238438Sdteske begin_nodelist "$shape" "$color" "$fillcolor" "$style" 444238438Sdteske print_node edge "style = dashed" "color = $edge_color" 445250321Sdteske #print_node edge "label = \"\\T\"" "fontsize = 9" 446250321Sdteske # NOTE: Edge labels are buggy on large graphs 447238438Sdteske file_list=$( 448238438Sdteske for file in \ 449238438Sdteske $BSDCONFIG \ 450238438Sdteske $menu_program_list \ 451238438Sdteske $submenu_program_list \ 452238438Sdteske $cmd_program_list \ 453238438Sdteske $include_file_list \ 454238438Sdteske ; do 455241499Sdteske [ -f "$BSDCFG_SHARE/$file" ] && 456241499Sdteske echo $BSDCFG_SHARE/$file 457238438Sdteske [ -e "$file" ] && echo $file 458238438Sdteske done | sort -u 459238438Sdteske ) 460238438Sdteske for file in $file_list; do 461238438Sdteske # Skip binary files and text files that don't use f_include() 462238438Sdteske grep -qlI f_include $file || continue 463238438Sdteske 464238438Sdteske awk \ 465241499Sdteske -v file="${file#$BSDCFG_SHARE/}" \ 466238438Sdteske -v bsdconfig="$BSDCONFIG" \ 467238438Sdteske ' 468241499Sdteske BEGIN { regex = "^f_include \\$BSDCFG_SHARE/" } 469241499Sdteske ( $0 ~ regex ) { 470238438Sdteske sub(regex, "") 471238438Sdteske if ( file == bsdconfig ) sub(".*/", "", file) 472238438Sdteske printf "\t\t\"%s\" -> \"%s\";\n", $0, file 473238438Sdteske } 474238438Sdteske ' $file 475241499Sdteske done | sort 476238438Sdteske end_nodelist 477238438Sdteskefi 478238438Sdteske 479238438Sdteske# 480238438Sdteske# Print command-line shortcuts 481238438Sdteske# 482238438Sdteskeif [ "$SHOW_CMDLINE" ]; then 483238438Sdteske printf '\n\t/*\n\t * Command-line shortcuts\n\t */\n' 484238438Sdteske shape=parallelogram color=black fillcolor=lightseagreen style=filled 485238438Sdteske begin_nodelist "$shape" "$color" "$fillcolor" "$style" 486238438Sdteske for file in */INDEX; do 487238438Sdteske awk -v item="${file%%/*}" ' 488238438Sdteske /^menu_selection="/ { 489238438Sdteske sub(/^.*="/, "") 490238438Sdteske sub(/\|.*/, "") 491238438Sdteske printf "\t\t\"bsdconfig %s\"", $0 492238438Sdteske printf " [ label = \"%s\" ];\n", $0 493238438Sdteske } 494238438Sdteske ' $file 495238438Sdteske done 496238438Sdteske end_nodelist 497238438Sdteskefi 498238438Sdteske 499238438Sdteske# 500238438Sdteske# Print command-line shortcut relationships 501238438Sdteske# 502238438Sdteskeif [ "$SHOW_CMDLINE" ]; then 503238438Sdteske printf '\n\t/*\n\t * Command-line shortcut relationships\n\t */\n' 504238438Sdteske shape=box color=black fillcolor=lightseagreen style=filled 505238438Sdteske begin_nodelist "$shape" "$color" "$fillcolor" "$style" 506238438Sdteske print_node edge "headport = w" "weight = 100.0" 507238438Sdteske print_node edge "style = bold" "color = $fillcolor" 508238438Sdteske for file in */INDEX; do 509238438Sdteske awk -v item="${file%%/*}" \ 510238438Sdteske -v node_fillcolor="$node_fillcolor" \ 511238438Sdteske -v edge_color="$edge_color" \ 512238438Sdteske ' 513238438Sdteske /^menu_selection="/ { 514238438Sdteske sub(/^.*="/, "") 515238438Sdteske sub(/"$/, "") 516238438Sdteske 517238438Sdteske if ( ! $0 ) next 518238438Sdteske 519238438Sdteske split($0, menusel, "|") 520238438Sdteske if ( menusel[2] !~ "^/" ) 521238438Sdteske sub(/^/, item "/", menusel[2]) 522238438Sdteske 523238438Sdteske printf "\t\t\"bsdconfig %s\" -> \"%s\";\n", 524238438Sdteske menusel[1], menusel[2] 525238438Sdteske } 526238438Sdteske ' $file 527238438Sdteske done 528238438Sdteske end_nodelist 529238438Sdteskefi 530238438Sdteske 531238438Sdteske# 532238438Sdteske# Print clusters 533238438Sdteske# 534238438Sdteskebgcolor_bsdconfig="lightyellow" 535238438Sdteskebgcolor_includes="gray98" 536238438Sdteskebgcolor_menuitem="aliceblue" 537238438Sdteskebgcolor_shortcuts="honeydew" 538238438Sdteskeprintf '\n\t/*\n\t * Clusters\n\t */\n' 539238438Sdteskeprintf '\tsubgraph "cluster_bsdconfig" {\n' 540238438Sdteskeprintf '\t\tbgcolor = "%s";\n' "$bgcolor_bsdconfig" 541238438Sdteskeprintf '\t\tlabel = "bsdconfig(8)";\n' 542238438Sdteskeprintf '\t\ttooltip = "bsdconfig(8)";\n' 543238438Sdteskeprint_node "bsdconfig" 544272230Sdteskeend_nodelist 545238438Sdteskeif [ "$SHOW_INCLUDES" ]; then 546238438Sdteske for include_file in $include_file_list; do 547241499Sdteske echo $include_file 548272230Sdteske done | awk \ 549272230Sdteske -v bgcolor="$bgcolor_bsdconfig" \ 550272230Sdteske -v msg_subroutines="$msg_subroutines" \ 551272230Sdteske ' 552272230Sdteske BEGIN { created = 0 } 553272230Sdteske function end_subgraph() { printf "\t};\n" } 554272230Sdteske ( $0 !~ "/" ) { 555272230Sdteske if ( ! created ) 556272230Sdteske { 557272230Sdteske printf "\tsubgraph \"%s\" {\n", 558272230Sdteske "cluster_bsdconfig_includes" 559272230Sdteske printf "\t\tbgcolor = \"%s\";\n", bgcolor 560272230Sdteske printf "\t\tlabel = \"bsdconfig %s\";\n", 561272230Sdteske msg_subroutines 562272230Sdteske created++ 563272230Sdteske } 564272230Sdteske printf "\t\t\"%s\";\n", $1 565241499Sdteske } 566272230Sdteske END { created && end_subgraph() } 567272230Sdteske ' # END-QUOTE 568241499Sdteske 569241499Sdteske for include_file in $include_file_list; do 570241499Sdteske echo $include_file 571272230Sdteske done | awk -v msg_subroutines="$msg_subroutines" ' 572241499Sdteske BEGIN { created = 0 } 573272230Sdteske function end_subgraph() { printf "\t};\n" } 574241499Sdteske ( $0 ~ "/" ) { 575241499Sdteske include_dir_tmp = $1 576241499Sdteske sub("/[^/]*$", "", include_dir_tmp) 577241499Sdteske gsub(/[^[:alnum:]_]/, "_", include_dir_tmp) 578241499Sdteske 579241499Sdteske if ( created && include_dir != include_dir_tmp ) 580241499Sdteske { 581241499Sdteske end_subgraph() 582241499Sdteske created = 0 583241499Sdteske } 584241499Sdteske 585241499Sdteske if ( ! created ) 586241499Sdteske { 587241499Sdteske include_dir = include_dir_tmp 588272230Sdteske printf "\tsubgraph \"cluster_%s_includes\" {\n", 589241499Sdteske include_dir 590272230Sdteske printf "\t\tbgcolor = \"thistle\";\n" 591272230Sdteske printf "\t\tlabel = \"%s %s\";\n", include_dir, 592272230Sdteske msg_subroutines 593241499Sdteske created++ 594241499Sdteske } 595241499Sdteske 596272230Sdteske printf "\t\t\"%s\";\n", $1 597241499Sdteske } 598241499Sdteske END { created && end_subgraph() }' 599238438Sdteskefi 600238438Sdteskefor INDEX in */INDEX; do 601238438Sdteske menu_title= 602238438Sdteske menu_help= 603238438Sdteske f_include_lang "$INDEX" 604238438Sdteske 605238438Sdteske item="${INDEX%%/*}" 606238438Sdteske printf '\tsubgraph "cluster_%s" {\n' "$item" 607238438Sdteske 608238438Sdteske case "$item" in 609252178Sdteske [0-9][0-9][0-9].*) bgcolor="$bgcolor_menuitem" ;; 610238438Sdteske *) bgcolor="$bgcolor_shortcuts" 611238438Sdteske esac 612238438Sdteske printf '\t\tbgcolor = "%s";\n' "$bgcolor" 613238438Sdteske if [ "$menu_title" ]; then 614238438Sdteske printf '\t\tlabel = "%s\\n\\"%s\\"";\n' "$item" "$menu_title" 615238438Sdteske else 616238438Sdteske printf '\t\tlabel = "%s";\n' "$item" 617238438Sdteske fi 618238438Sdteske printf '\t\ttooltip = "%s";\n' "${menu_help:-$item}" 619238438Sdteske 620238438Sdteske program_list=$( 621238438Sdteske for program in \ 622238438Sdteske $menu_program_list \ 623238438Sdteske $submenu_program_list \ 624238438Sdteske $cmd_program_list \ 625238438Sdteske ; do 626238438Sdteske echo "$program" 627238438Sdteske done | sort -u 628238438Sdteske ) 629238438Sdteske for program in $program_list; do 630238438Sdteske case "$program" in "$item"/*) 631238438Sdteske print_node "$program" "label = \"${program#*/}\"" 632238438Sdteske esac 633238438Sdteske done 634238438Sdteske 635238438Sdteske if [ "$SHOW_INCLUDES" ]; then 636238438Sdteske item_include_list= 637238438Sdteske [ -d "$item/include" ] && 638238438Sdteske item_include_list=$( find "$item/include" -type f ) 639238438Sdteske item_include_list=$( 640238438Sdteske for item_include in $item_include_list; do 641238438Sdteske for include_file in $include_file_list; do 642238438Sdteske [ "$item_include" = "$include_file" ] || 643238438Sdteske continue 644238438Sdteske echo "$item_include"; break 645238438Sdteske done 646238438Sdteske done 647238438Sdteske ) 648238438Sdteske if [ "$item_include_list" ]; then 649238438Sdteske printf '\t\tsubgraph "cluster_%s_includes" {\n' "$item" 650238438Sdteske printf '\t\t\tbgcolor = "%s";\n' "$bgcolor_includes" 651238438Sdteske printf '\t\t\tlabel = "%s";\n' "$msg_includes" 652238438Sdteske fi 653238438Sdteske for item_include in $item_include_list; do 654238438Sdteske printf '\t\t\t"%s";\n' "$item_include" 655238438Sdteske done 656238438Sdteske [ "$item_include_list" ] && printf '\t\t};\n' 657238438Sdteske fi 658238438Sdteske 659238438Sdteske if [ "$SHOW_CMDLINE" ]; then 660238438Sdteske printf '\t\tsubgraph "cluster_%s_shortcuts" {\n' "$item" 661238438Sdteske printf '\t\t\tbgcolor = "%s";\n' "$bgcolor_shortcuts" 662238438Sdteske printf '\t\t\tlabel = "%s";\n' "$msg_shortcuts" 663238438Sdteske awk '/^menu_selection="/ { 664238438Sdteske sub(/^.*="/, "") 665238438Sdteske sub(/\|.*/, "") 666238438Sdteske printf "\t\t\t\"bsdconfig %s\";\n", $0 667238438Sdteske }' "$INDEX" 668238438Sdteske printf '\t\t};\n' 669238438Sdteske fi 670238438Sdteske 671238438Sdteske end_nodelist 672238438Sdteskedone 673238438Sdteske 674272230Sdteskeprintf '\n}\n' 675238438Sdteske 676238438Sdteske################################################################################ 677238438Sdteske# END 678238438Sdteske################################################################################ 679