mirror of
https://github.com/opnsense/src.git
synced 2026-03-01 04:40:53 -05:00
properly clustered. Change `fixedsize' to `fixedsize = true' to satisfy newer versions of dot(1) generating error "Warning: <stdin>: syntax error in line 27 near ','". Remove bounding cluster surrounding various include-groupings, allowing groups of include files to float freely to the greatest consumer (reducing the density of rendered diagrams). While here, change the bgcolor of include clusters from white to X11 color `thistle' (a light purple). Also, add the word "Subroutines" after include cluster labels. Do not terminate the digraph definition with a semi-colon [;] after the ending brace to satisfy newer versions of dot(1) generating error "Warning: <stdin>: syntax error in line 940 near ';'". MFC after: 3 days X-MFC-to: stable/10, stable/9
678 lines
17 KiB
Bash
Executable file
678 lines
17 KiB
Bash
Executable file
#!/bin/sh
|
|
#-
|
|
# Copyright (c) 2012-2013 Devin Teske
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions
|
|
# are met:
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
# SUCH DAMAGE.
|
|
#
|
|
# $FreeBSD$
|
|
#
|
|
############################################################ INCLUDES
|
|
|
|
# Prevent common.subr from auto initializing debugging (this is not an inter-
|
|
# active utility so does not require debugging; also `-d' has been repurposed).
|
|
#
|
|
DEBUG_SELF_INITIALIZE=NO
|
|
|
|
BSDCFG_SHARE="/usr/share/bsdconfig"
|
|
. $BSDCFG_SHARE/common.subr || exit 1
|
|
f_dprintf "%s: loading includes..." "$0"
|
|
|
|
BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="dot"
|
|
f_include_lang $BSDCFG_LIBE/include/messages.subr
|
|
f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
|
|
|
|
f_index_menusel_keyword $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" ipgm &&
|
|
pgm="${ipgm:-$pgm}"
|
|
|
|
############################################################ CONFIGURATION
|
|
|
|
#
|
|
# Location of bsdconfig(8)
|
|
#
|
|
BSDCONFIG=/usr/sbin/bsdconfig
|
|
|
|
############################################################ GLOBALS
|
|
|
|
#
|
|
# Options
|
|
#
|
|
SHOW_GRAPH_LABEL_DATE=1
|
|
SHOW_INCLUDES=1
|
|
SHOW_CMDLINE=1
|
|
|
|
############################################################ FUNCTIONS
|
|
|
|
# begin_nodelist $shape $color $fillcolor $style
|
|
#
|
|
# Create a new multi-node list rendering nodes in a specific style described by
|
|
# the arguments passed.
|
|
#
|
|
begin_nodelist()
|
|
{
|
|
local shape="$1" color="$2" fillcolor="$3" style="$4"
|
|
|
|
printf "\tnode [\n"
|
|
[ "$shape" ] &&
|
|
printf '\t\tshape = "%s",\n' "$shape"
|
|
[ "$color" ] &&
|
|
printf '\t\tcolor = "%s",\n' "$color"
|
|
[ "$fillcolor" ] &&
|
|
printf '\t\tfillcolor = "%s",\n' "$fillcolor"
|
|
[ "$style" ] &&
|
|
printf '\t\tstyle = "%s",\n' "$style"
|
|
printf "\t] {\n"
|
|
}
|
|
|
|
# print_node $node [$attributes ...]
|
|
#
|
|
# Print a node within a multi-node list.
|
|
#
|
|
print_node()
|
|
{
|
|
local node="$1"
|
|
|
|
shift 1 # node
|
|
|
|
case "$node" in
|
|
edge) printf '\t\t%s' "$node" ;;
|
|
*) printf '\t\t"%s"' "$node" ;;
|
|
esac
|
|
|
|
if [ $# -gt 0 ]; then
|
|
echo -n ' ['
|
|
while [ $# -gt 0 ]; do
|
|
printf " %s" "$1"
|
|
shift 1
|
|
[ $# -gt 0 ] && echo -n ","
|
|
done
|
|
echo -n " ]"
|
|
fi
|
|
|
|
echo ";"
|
|
}
|
|
|
|
# print_node2 $node $node [$attributes ...]
|
|
#
|
|
# Print a directed node-node connection within a multi-node list.
|
|
#
|
|
print_node2()
|
|
{
|
|
local node1="$1" node2="$2"
|
|
|
|
shift 2 # node1 node2
|
|
|
|
printf '\t\t"%s" -> "%s"' "$node1" "$node2"
|
|
|
|
if [ $# -gt 0 ]; then
|
|
echo -n ' ['
|
|
while [ $# -gt 0 ]; do
|
|
printf " %s" "$1"
|
|
shift 1
|
|
[ $# -gt 0 ] && echo -n ","
|
|
done
|
|
echo -n " ]"
|
|
fi
|
|
|
|
echo ";"
|
|
}
|
|
|
|
# end_nodelist
|
|
#
|
|
# Close a multi-node list.
|
|
#
|
|
end_nodelist()
|
|
{
|
|
printf "\t};\n"
|
|
}
|
|
|
|
############################################################ MAIN
|
|
|
|
# Incorporate rc-file if it exists
|
|
[ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc"
|
|
|
|
#
|
|
# Process command-line arguments
|
|
#
|
|
while getopts cdhi flag; do
|
|
case "$flag" in
|
|
i) SHOW_INCLUDES= ;;
|
|
d) SHOW_GRAPH_LABEL_DATE= ;;
|
|
c) SHOW_CMDLINE= ;;
|
|
h|\?) f_usage $BSDCFG_LIBE/$APP_DIR/USAGE "PROGRAM_NAME" "$pgm" ;;
|
|
esac
|
|
done
|
|
shift $(( $OPTIND - 1 ))
|
|
|
|
cd $BSDCFG_LIBE || f_die # Pedantic
|
|
|
|
#
|
|
# Get a list of menu programs
|
|
#
|
|
menu_program_list=
|
|
for file in [0-9][0-9][0-9].*/INDEX; do
|
|
menu_program_list="$menu_program_list $(
|
|
tail -r "$file" | awk -v item="${file%%/*}" '
|
|
/^[[:space:]]*menu_program="/ {
|
|
sub(/^.*="/, "")
|
|
sub(/"$/, "")
|
|
if ( ! $0 ) next
|
|
if ( $0 !~ "^/" ) sub(/^/, item "/")
|
|
print; exit
|
|
}'
|
|
)"
|
|
done
|
|
|
|
#
|
|
# Get a list of submenu programs
|
|
#
|
|
submenu_program_list=
|
|
for menu_program in $menu_program_list; do
|
|
case "$menu_program" in
|
|
[0-9][0-9][0-9].*/*) : fall-through ;;
|
|
*) continue # No sub-menus we can process
|
|
esac
|
|
|
|
submenu_program_list="$submenu_program_list $(
|
|
awk -v menu_program="$menu_program" \
|
|
-v item="${menu_program%%/*}" \
|
|
'
|
|
/^menu_selection="/ {
|
|
sub(/.*\|/, "")
|
|
sub(/"$/, "")
|
|
if ( ! $0 ) next
|
|
if ( $0 !~ "^/" )
|
|
sub(/^/, item "/")
|
|
if ( $0 == menu_program ) next
|
|
print
|
|
}
|
|
' "${menu_program%%/*}/INDEX"
|
|
)"
|
|
done
|
|
|
|
#
|
|
# Get a list of command-line programs
|
|
#
|
|
cmd_program_list=
|
|
for file in */INDEX; do
|
|
cmd_program_list="$cmd_program_list $(
|
|
awk -v item="${file%%/*}" '
|
|
/^menu_selection="/ {
|
|
sub(/.*\|/, "")
|
|
sub(/"$/, "")
|
|
|
|
if ( ! $0 ) next
|
|
|
|
if ( $0 !~ "^/" )
|
|
sub(/^/, item "/")
|
|
|
|
print
|
|
}
|
|
' $file
|
|
)"
|
|
done
|
|
|
|
#
|
|
# [Optionally] Calculate list of include files
|
|
#
|
|
if [ "$SHOW_INCLUDES" ]; then
|
|
print_includes_awk='
|
|
BEGIN { regex = "^f_include \\$BSDCFG_SHARE/" }
|
|
( $0 ~ regex ) { sub(regex, ""); print }
|
|
' # END-QUOTE
|
|
|
|
#
|
|
# Build list of files in which to search for includes
|
|
#
|
|
file_list=$(
|
|
for file in \
|
|
$BSDCONFIG \
|
|
$menu_program_list \
|
|
$submenu_program_list \
|
|
$cmd_program_list \
|
|
$BSDCFG_SHARE/script.subr \
|
|
; do
|
|
[ -e "$file" ] && echo $file
|
|
done | sort -u
|
|
)
|
|
|
|
#
|
|
# Build list of includes used by the above files
|
|
#
|
|
include_file_list=
|
|
for file in $file_list; do
|
|
include_file_list="$include_file_list $(
|
|
awk "$print_includes_awk" $file
|
|
)"
|
|
done
|
|
|
|
#
|
|
# Sort the list of includes and remove duplicate entries
|
|
#
|
|
include_file_list=$(
|
|
for include_file in $include_file_list; do
|
|
echo "$include_file"
|
|
done | sort -u
|
|
)
|
|
|
|
#
|
|
# Search previously-discovered include files for further includes
|
|
#
|
|
before="$include_file_list"
|
|
while :; do
|
|
for file in $include_file_list; do
|
|
include_file_list="$include_file_list $(
|
|
awk "$print_includes_awk" $BSDCFG_SHARE/$file
|
|
)"
|
|
done
|
|
|
|
#
|
|
# Sort list of includes and remove duplicate entries [again]
|
|
#
|
|
include_file_list=$(
|
|
for include_file in $include_file_list; do
|
|
echo "$include_file"
|
|
done | sort -u
|
|
)
|
|
|
|
[ "$include_file_list" = "$before" ] && break
|
|
before="$include_file_list"
|
|
done
|
|
fi
|
|
|
|
#
|
|
# Start the directional-graph (digraph) output
|
|
#
|
|
printf 'strict digraph "" { // Empty name to prevent SVG Auto-Tooltip\n'
|
|
label_format="$msg_graph_label_with_command"
|
|
[ "$SHOW_GRAPH_LABEL_DATE" ] &&
|
|
label_format="$msg_graph_label_with_command_and_date"
|
|
lang="${LANG:-$LC_ALL}"
|
|
printf "\n\tlabel = \"$label_format\"\n" \
|
|
"${lang:+LANG=${lang%%[$IFS]*} }bsdconfig $pgm${ARGV:+ $ARGV}" \
|
|
"$( date +"%c %Z" )"
|
|
|
|
#
|
|
# Print graph-specific properties
|
|
#
|
|
printf '\n\t/*\n\t * Graph setup and orientation\n\t */\n'
|
|
printf '\tlabelloc = top;\t\t// display above label at top of graph\n'
|
|
printf '\trankdir = LR;\t\t// create ranks left-to-right\n'
|
|
printf '\torientation = portrait;\t// default\n'
|
|
printf '\tratio = fill;\t\t// approximate aspect ratio\n'
|
|
printf '\tcenter = 1;\t\t// center drawing on page\n'
|
|
|
|
#
|
|
# Perform edge-concentration when displaying a lot of information
|
|
#
|
|
# NOTE: This is disabled because dot(1) version 2.28.0 (current) and older have
|
|
# a bug that causes a crash when rankdir = LR and concentrate = true
|
|
#
|
|
# NOTE: Do not re-enable until said bug is fixed in some future revision.
|
|
#
|
|
#[ "$SHOW_INCLUDES" -a "$SHOW_CMDLINE" ] &&
|
|
# printf '\tconcentrate = true;\t// enable edge concentrators\n'
|
|
|
|
#
|
|
# Print font details for graph/cluster label(s)
|
|
#
|
|
printf '\n\t/*\n\t * Font details for graph/cluster label(s)\n\t */\n'
|
|
printf '\tfontname = "Times-Italic";\n'
|
|
printf '\tfontsize = 14;\n'
|
|
|
|
#
|
|
# Print default node attributes
|
|
#
|
|
printf '\n\t/*\n\t * Default node attributes\n\t */\n'
|
|
printf '\tnode [\n'
|
|
printf '\t\tfontname = "Times-Roman",\n'
|
|
printf '\t\tfontsize = 12,\n'
|
|
printf '\t\twidth = 2.5, // arbitrary minimum width for all nodes\n'
|
|
printf '\t\tfixedsize = true, // turn minimum width into exact width\n'
|
|
printf '\t];\n'
|
|
|
|
#
|
|
# Print top-level item(s)
|
|
#
|
|
printf '\n\t/*\n\t * bsdconfig(8)\n\t */\n'
|
|
shape=circle color=black fillcolor=yellow style=filled
|
|
begin_nodelist "$shape" "$color" "$fillcolor" "$style"
|
|
print_node "bsdconfig" "fontname = \"Times-Bold\"" "fontsize = 16"
|
|
end_nodelist
|
|
|
|
#
|
|
# Print menus
|
|
#
|
|
printf '\n\t/*\n\t * Menu items\n\t */\n'
|
|
shape=box color=black fillcolor=lightblue style=filled
|
|
begin_nodelist "$shape" "$color" "$fillcolor" "$style"
|
|
for menu_program in $menu_program_list; do
|
|
print_node "$menu_program" "label = \"${menu_program#*/}\""
|
|
done
|
|
end_nodelist
|
|
|
|
#
|
|
# Print sub-menus
|
|
#
|
|
printf '\n\t/*\n\t * Sub-menu items\n\t */\n'
|
|
shape=box color=black fillcolor=lightblue style=filled
|
|
begin_nodelist "$shape" "$color" "$fillcolor" "$style"
|
|
for submenu_program in $submenu_program_list; do
|
|
print_node "$submenu_program" "label = \"${submenu_program#*/}\""
|
|
done
|
|
end_nodelist
|
|
|
|
#
|
|
# Print menu relationships
|
|
#
|
|
printf '\n\t/*\n\t * Menu item relationships\n\t */\n'
|
|
shape=box color=black fillcolor=lightblue style=filled edge_color=blue
|
|
begin_nodelist "$shape" "$color" "$fillcolor" "$style"
|
|
print_node edge "penwidth = 5.0" "style = bold" "color = $edge_color"
|
|
for menu_program in $menu_program_list; do
|
|
print_node2 "bsdconfig" "$menu_program"
|
|
done
|
|
end_nodelist
|
|
|
|
#
|
|
# Print sub-menu relationships
|
|
#
|
|
printf '\n\t/*\n\t * Sub-menu item relationships\n\t */\n'
|
|
shape=box color=black fillcolor=lightblue style=filled edge_color=blue
|
|
begin_nodelist "$shape" "$color" "$fillcolor" "$style"
|
|
# Lock sub-menu headport to the West (unless `-c' was passed)
|
|
[ "$SHOW_CMDLINE" -o ! "$SHOW_INCLUDES" ] && print_node edge "headport = w"
|
|
print_node edge "style = bold" "color = $edge_color"
|
|
for submenu_program in $submenu_program_list; do
|
|
for menu_program in $menu_program_list; do
|
|
case "$menu_program" in
|
|
[0-9][0-9][0-9].*/*) : fall-through ;;
|
|
*) continue # Not a menu item
|
|
esac
|
|
|
|
# Continue if program directories do not match
|
|
[ "${menu_program%%/*}" = "${submenu_program%%/*}" ] ||
|
|
continue
|
|
|
|
print_node2 "$menu_program" "$submenu_program"
|
|
break
|
|
done
|
|
done
|
|
end_nodelist
|
|
|
|
#
|
|
# [Optionally] Print include files
|
|
#
|
|
if [ "$SHOW_INCLUDES" ]; then
|
|
printf '\n\t/*\n\t * Include files\n\t */\n'
|
|
shape=oval color=black fillcolor=white style=filled
|
|
begin_nodelist "$shape" "$color" "$fillcolor" "$style"
|
|
printf '\t\tconstraint = false;\n'
|
|
for include_file in $include_file_list; do
|
|
print_node "$include_file" \
|
|
"label = \"${include_file##*/}\""
|
|
done
|
|
end_nodelist
|
|
fi
|
|
|
|
#
|
|
# [Optionally] Print f_include() usage/relationships
|
|
#
|
|
if [ "$SHOW_INCLUDES" ]; then
|
|
printf '\n\t/*\n\t * Include usage\n\t */\n'
|
|
shape=oval color=black fillcolor=white style=filled edge_color=grey
|
|
begin_nodelist "$shape" "$color" "$fillcolor" "$style"
|
|
print_node edge "style = dashed" "color = $edge_color"
|
|
#print_node edge "label = \"\\T\"" "fontsize = 9"
|
|
# NOTE: Edge labels are buggy on large graphs
|
|
file_list=$(
|
|
for file in \
|
|
$BSDCONFIG \
|
|
$menu_program_list \
|
|
$submenu_program_list \
|
|
$cmd_program_list \
|
|
$include_file_list \
|
|
; do
|
|
[ -f "$BSDCFG_SHARE/$file" ] &&
|
|
echo $BSDCFG_SHARE/$file
|
|
[ -e "$file" ] && echo $file
|
|
done | sort -u
|
|
)
|
|
for file in $file_list; do
|
|
# Skip binary files and text files that don't use f_include()
|
|
grep -qlI f_include $file || continue
|
|
|
|
awk \
|
|
-v file="${file#$BSDCFG_SHARE/}" \
|
|
-v bsdconfig="$BSDCONFIG" \
|
|
'
|
|
BEGIN { regex = "^f_include \\$BSDCFG_SHARE/" }
|
|
( $0 ~ regex ) {
|
|
sub(regex, "")
|
|
if ( file == bsdconfig ) sub(".*/", "", file)
|
|
printf "\t\t\"%s\" -> \"%s\";\n", $0, file
|
|
}
|
|
' $file
|
|
done | sort
|
|
end_nodelist
|
|
fi
|
|
|
|
#
|
|
# Print command-line shortcuts
|
|
#
|
|
if [ "$SHOW_CMDLINE" ]; then
|
|
printf '\n\t/*\n\t * Command-line shortcuts\n\t */\n'
|
|
shape=parallelogram color=black fillcolor=lightseagreen style=filled
|
|
begin_nodelist "$shape" "$color" "$fillcolor" "$style"
|
|
for file in */INDEX; do
|
|
awk -v item="${file%%/*}" '
|
|
/^menu_selection="/ {
|
|
sub(/^.*="/, "")
|
|
sub(/\|.*/, "")
|
|
printf "\t\t\"bsdconfig %s\"", $0
|
|
printf " [ label = \"%s\" ];\n", $0
|
|
}
|
|
' $file
|
|
done
|
|
end_nodelist
|
|
fi
|
|
|
|
#
|
|
# Print command-line shortcut relationships
|
|
#
|
|
if [ "$SHOW_CMDLINE" ]; then
|
|
printf '\n\t/*\n\t * Command-line shortcut relationships\n\t */\n'
|
|
shape=box color=black fillcolor=lightseagreen style=filled
|
|
begin_nodelist "$shape" "$color" "$fillcolor" "$style"
|
|
print_node edge "headport = w" "weight = 100.0"
|
|
print_node edge "style = bold" "color = $fillcolor"
|
|
for file in */INDEX; do
|
|
awk -v item="${file%%/*}" \
|
|
-v node_fillcolor="$node_fillcolor" \
|
|
-v edge_color="$edge_color" \
|
|
'
|
|
/^menu_selection="/ {
|
|
sub(/^.*="/, "")
|
|
sub(/"$/, "")
|
|
|
|
if ( ! $0 ) next
|
|
|
|
split($0, menusel, "|")
|
|
if ( menusel[2] !~ "^/" )
|
|
sub(/^/, item "/", menusel[2])
|
|
|
|
printf "\t\t\"bsdconfig %s\" -> \"%s\";\n",
|
|
menusel[1], menusel[2]
|
|
}
|
|
' $file
|
|
done
|
|
end_nodelist
|
|
fi
|
|
|
|
#
|
|
# Print clusters
|
|
#
|
|
bgcolor_bsdconfig="lightyellow"
|
|
bgcolor_includes="gray98"
|
|
bgcolor_menuitem="aliceblue"
|
|
bgcolor_shortcuts="honeydew"
|
|
printf '\n\t/*\n\t * Clusters\n\t */\n'
|
|
printf '\tsubgraph "cluster_bsdconfig" {\n'
|
|
printf '\t\tbgcolor = "%s";\n' "$bgcolor_bsdconfig"
|
|
printf '\t\tlabel = "bsdconfig(8)";\n'
|
|
printf '\t\ttooltip = "bsdconfig(8)";\n'
|
|
print_node "bsdconfig"
|
|
end_nodelist
|
|
if [ "$SHOW_INCLUDES" ]; then
|
|
for include_file in $include_file_list; do
|
|
echo $include_file
|
|
done | awk \
|
|
-v bgcolor="$bgcolor_bsdconfig" \
|
|
-v msg_subroutines="$msg_subroutines" \
|
|
'
|
|
BEGIN { created = 0 }
|
|
function end_subgraph() { printf "\t};\n" }
|
|
( $0 !~ "/" ) {
|
|
if ( ! created )
|
|
{
|
|
printf "\tsubgraph \"%s\" {\n",
|
|
"cluster_bsdconfig_includes"
|
|
printf "\t\tbgcolor = \"%s\";\n", bgcolor
|
|
printf "\t\tlabel = \"bsdconfig %s\";\n",
|
|
msg_subroutines
|
|
created++
|
|
}
|
|
printf "\t\t\"%s\";\n", $1
|
|
}
|
|
END { created && end_subgraph() }
|
|
' # END-QUOTE
|
|
|
|
for include_file in $include_file_list; do
|
|
echo $include_file
|
|
done | awk -v msg_subroutines="$msg_subroutines" '
|
|
BEGIN { created = 0 }
|
|
function end_subgraph() { printf "\t};\n" }
|
|
( $0 ~ "/" ) {
|
|
include_dir_tmp = $1
|
|
sub("/[^/]*$", "", include_dir_tmp)
|
|
gsub(/[^[:alnum:]_]/, "_", include_dir_tmp)
|
|
|
|
if ( created && include_dir != include_dir_tmp )
|
|
{
|
|
end_subgraph()
|
|
created = 0
|
|
}
|
|
|
|
if ( ! created )
|
|
{
|
|
include_dir = include_dir_tmp
|
|
printf "\tsubgraph \"cluster_%s_includes\" {\n",
|
|
include_dir
|
|
printf "\t\tbgcolor = \"thistle\";\n"
|
|
printf "\t\tlabel = \"%s %s\";\n", include_dir,
|
|
msg_subroutines
|
|
created++
|
|
}
|
|
|
|
printf "\t\t\"%s\";\n", $1
|
|
}
|
|
END { created && end_subgraph() }'
|
|
fi
|
|
for INDEX in */INDEX; do
|
|
menu_title=
|
|
menu_help=
|
|
f_include_lang "$INDEX"
|
|
|
|
item="${INDEX%%/*}"
|
|
printf '\tsubgraph "cluster_%s" {\n' "$item"
|
|
|
|
case "$item" in
|
|
[0-9][0-9][0-9].*) bgcolor="$bgcolor_menuitem" ;;
|
|
*) bgcolor="$bgcolor_shortcuts"
|
|
esac
|
|
printf '\t\tbgcolor = "%s";\n' "$bgcolor"
|
|
if [ "$menu_title" ]; then
|
|
printf '\t\tlabel = "%s\\n\\"%s\\"";\n' "$item" "$menu_title"
|
|
else
|
|
printf '\t\tlabel = "%s";\n' "$item"
|
|
fi
|
|
printf '\t\ttooltip = "%s";\n' "${menu_help:-$item}"
|
|
|
|
program_list=$(
|
|
for program in \
|
|
$menu_program_list \
|
|
$submenu_program_list \
|
|
$cmd_program_list \
|
|
; do
|
|
echo "$program"
|
|
done | sort -u
|
|
)
|
|
for program in $program_list; do
|
|
case "$program" in "$item"/*)
|
|
print_node "$program" "label = \"${program#*/}\""
|
|
esac
|
|
done
|
|
|
|
if [ "$SHOW_INCLUDES" ]; then
|
|
item_include_list=
|
|
[ -d "$item/include" ] &&
|
|
item_include_list=$( find "$item/include" -type f )
|
|
item_include_list=$(
|
|
for item_include in $item_include_list; do
|
|
for include_file in $include_file_list; do
|
|
[ "$item_include" = "$include_file" ] ||
|
|
continue
|
|
echo "$item_include"; break
|
|
done
|
|
done
|
|
)
|
|
if [ "$item_include_list" ]; then
|
|
printf '\t\tsubgraph "cluster_%s_includes" {\n' "$item"
|
|
printf '\t\t\tbgcolor = "%s";\n' "$bgcolor_includes"
|
|
printf '\t\t\tlabel = "%s";\n' "$msg_includes"
|
|
fi
|
|
for item_include in $item_include_list; do
|
|
printf '\t\t\t"%s";\n' "$item_include"
|
|
done
|
|
[ "$item_include_list" ] && printf '\t\t};\n'
|
|
fi
|
|
|
|
if [ "$SHOW_CMDLINE" ]; then
|
|
printf '\t\tsubgraph "cluster_%s_shortcuts" {\n' "$item"
|
|
printf '\t\t\tbgcolor = "%s";\n' "$bgcolor_shortcuts"
|
|
printf '\t\t\tlabel = "%s";\n' "$msg_shortcuts"
|
|
awk '/^menu_selection="/ {
|
|
sub(/^.*="/, "")
|
|
sub(/\|.*/, "")
|
|
printf "\t\t\t\"bsdconfig %s\";\n", $0
|
|
}' "$INDEX"
|
|
printf '\t\t};\n'
|
|
fi
|
|
|
|
end_nodelist
|
|
done
|
|
|
|
printf '\n}\n'
|
|
|
|
################################################################################
|
|
# END
|
|
################################################################################
|