summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bsdconfig/dot
diff options
context:
space:
mode:
authordteske <dteske@FreeBSD.org>2012-07-14 03:16:57 +0000
committerdteske <dteske@FreeBSD.org>2012-07-14 03:16:57 +0000
commit3981b9b76aa0266598ee7b724e5981627d8ac129 (patch)
tree8b439d31cf63b5d5c97b653a3cd721fd9961baa5 /usr.sbin/bsdconfig/dot
parent5d2a55de5070f6d3a8e4b9762a397596e7b308ae (diff)
downloadFreeBSD-src-3981b9b76aa0266598ee7b724e5981627d8ac129.zip
FreeBSD-src-3981b9b76aa0266598ee7b724e5981627d8ac129.tar.gz
Import bsdconfig(8) as a replacement for the post-install abilities of
deprecated sysinstall(8). NOTE: WITH_BSDCONFIG is currently required. Submitted by: Devin Teske (dteske), Ron McDowell <rcm@fuzzwad.org> Reviewed by: Ron McDowell <rcm@fuzzwad.org> Approved by: Ed Maste (emaste)
Diffstat (limited to 'usr.sbin/bsdconfig/dot')
-rw-r--r--usr.sbin/bsdconfig/dot/INDEX53
-rw-r--r--usr.sbin/bsdconfig/dot/Makefile16
-rw-r--r--usr.sbin/bsdconfig/dot/USAGE143
-rwxr-xr-xusr.sbin/bsdconfig/dot/dot646
-rw-r--r--usr.sbin/bsdconfig/dot/include/Makefile11
-rw-r--r--usr.sbin/bsdconfig/dot/include/messages.subr30
6 files changed, 899 insertions, 0 deletions
diff --git a/usr.sbin/bsdconfig/dot/INDEX b/usr.sbin/bsdconfig/dot/INDEX
new file mode 100644
index 0000000..96b0c87
--- /dev/null
+++ b/usr.sbin/bsdconfig/dot/INDEX
@@ -0,0 +1,53 @@
+# Copyright (c) 2012 Ron McDowell
+# Copyright (c) 2012 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$
+
+#
+# Title that will be shown on the bsdconfig menu
+menu_title=""
+#
+# a short descriptive line shown at the bottom of the bsdconfig menu.
+# keep it short because any line longer than the terminal width will
+# be truncated.
+menu_help=""
+#
+# two-part variable that defines an action to take when 'keyword'
+# is passed on a bsdconfig command line. variable takes the form
+# "keyword|command" and multiple occurrences of the variable
+# (with different 'keyword's, or different 'keyword's AND 'command's)
+# are allowed. If 'command' begins with a '/' then the full
+# path to the program is needed. If 'command' begins with anything
+# else it is a path relative to the directory this INDEX file is in.
+# 'keyword' can be i18n'ed but 'command' is the name of a script.
+menu_selection="dot|dot"
+#
+# Items below this line do NOT need i18n translation----------------------
+#
+# Name of the program to be run when this menu choice is selected.
+# if it begins with a '/' then the full path to the program is needed.
+# if it begins with anything else it is a path relative to the directory
+# this INDEX file is in.
+menu_program=""
diff --git a/usr.sbin/bsdconfig/dot/Makefile b/usr.sbin/bsdconfig/dot/Makefile
new file mode 100644
index 0000000..5a87282
--- /dev/null
+++ b/usr.sbin/bsdconfig/dot/Makefile
@@ -0,0 +1,16 @@
+# $FreeBSD$
+
+NO_OBJ=
+
+SUBDIR= include
+
+FILESDIR= ${LIBEXECDIR}/bsdconfig/dot
+FILES= INDEX USAGE
+
+SCRIPTSDIR= ${FILESDIR}
+SCRIPTS= dot
+
+beforeinstall:
+ mkdir -p ${DESTDIR}${FILESDIR}
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/bsdconfig/dot/USAGE b/usr.sbin/bsdconfig/dot/USAGE
new file mode 100644
index 0000000..c1c0dc3
--- /dev/null
+++ b/usr.sbin/bsdconfig/dot/USAGE
@@ -0,0 +1,143 @@
+# Copyright (c) 2012 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 (INLUDING, 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$
+
+Usage: bsdconfig @PROGRAM_NAME@ [OPTIONS]
+
+OPTIONS:
+ -h Print usage statement and exit.
+ -c Don't show command-line shortcut relationships.
+ -d Don't show the date in the graph label.
+ -i Don't show include relationships.
+
+EXAMPLES:
+ View dot(1) language output describing bsdconfig(8) layout/make-up:
+
+ bsdconfig @PROGRAM_NAME@ | less
+
+ Render dot(1) output in SVG format (displays in most modern browsers):
+
+ bsdconfig @PROGRAM_NAME@ | dot -Tsvg -o bsdconfig.svg
+
+ NOTE: Requires `graphics/graphviz' from ports/packages.
+
+ View the above-rendered SVG file using your favorite X11-based viewer:
+
+ gimmage bsdconfig.svg
+
+ NOTE: Requires `graphics/gimmage' from ports/packages.
+
+ or
+
+ gthumb bsdconfig.svg
+
+ NOTE: Image is scaled to fit window on launch.
+ NOTE: Requires `graphics/gthumb' from ports/packages.
+
+ or
+
+ gqview bsdconfig.svg
+
+ NOTE: Requires `graphics/gqview' from ports/packages.
+
+ or
+
+ gx bsdconfig.svg
+
+ NOTE: Image is scaled to fit window on launch.
+ NOTE: Requires `graphics/gx' from ports/packages.
+
+ or
+
+ eog bsdconfig.svg
+
+ NOTE: Requires `graphics/eog' from ports/packages.
+
+ Render dot(1) output as PostScript print output consisting of multiple
+ US-Letter sized pages that can be assembled into a large poster (using
+ traditional tools such as scissors and tape):
+
+ bsdconfig @PROGRAM_NAME@ | dot -Teps -o bsdconfig.eps
+ poster -v -mLet -s1 -o bsdconfig.ps bsdconfig.eps
+
+ NOTE: Change "-s1" above to "-s0.5" to halve the size of the
+ poster or "-s2", for example, to double the poster size.
+
+ NOTE: Requires both `graphics/graphviz' and `print/poster' from
+ ports/packages.
+
+ Render dot(1) output as PostScript scaled to fit on a poster consisting
+ of 2x-wide and 4x-tall US-Letter sized pages:
+
+ bsdconfig @PROGRAM_NAME@ | dot -Teps -o bsdconfig.eps
+ poster -v -mLet -p2x4Letter -o bsdconfig.ps bsdconfig.eps
+
+ NOTE: Requires both `graphics/graphviz' and `print/poster' from
+ ports/packages.
+
+ View the above-rendered PostScript poster using X11:
+
+ gsview bsdconfig.ps
+
+ NOTE: Requires `print/gsview' from ports/packages.
+
+ or
+
+ convert bsdconfig.ps bsdconfig.pdf
+ xpdf bsdconfig.pdf
+
+ NOTE: Requires both `graphics/ImageMagick' and
+ `graphics/xdpf' from ports/packages.
+
+ NOTE: The converted PDF file is not suitable for
+ printing due to loss of quality during the
+ conversion process.
+
+ Print the above-rendered PostScript poster:
+
+ lpr -h bsdconfig.ps
+
+ NOTE: Requires configuration of a printer in `/etc/printcap'.
+
+ Extract each page of the poster into a separate PNG file:
+
+ gs -q -dNOPAUSE -dBATCH -sPAPERSIZE=letter \
+ -dTextAlphaBits=4 -dGraphicsAlphaBits=4 \
+ -sDEVICE=png16m -sOutputFile=bsdconfig%03d.png \
+ bsdconfig.ps
+
+ NOTE: Requires `print/ghostscript9' from ports/packages.
+
+ NOTE: The converted PNG files are not suitable for printing
+ due to loss of quality during the conversion process.
+
+ Extract a single page of the poster into a separate PostScript file for
+ printing individual pages from the command-line:
+
+ psselect 1 bsdconfig.ps bsdconfig-page1.ps
+ lpr -h bsdconfig-page1.ps
+
+ NOTE: Change "1" to "2" for the second page, ad-infinitum.
+ NOTE: Requires `print/psutils-letter' from ports/packages.
diff --git a/usr.sbin/bsdconfig/dot/dot b/usr.sbin/bsdconfig/dot/dot
new file mode 100755
index 0000000..e1f0e1b
--- /dev/null
+++ b/usr.sbin/bsdconfig/dot/dot
@@ -0,0 +1,646 @@
+#!/bin/sh
+#-
+# Copyright (c) 2012 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 (INLUDING, 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
+
+BSDCFG_LIBE="/usr/libexec/bsdconfig"
+. $BSDCFG_LIBE/include/common.subr || exit 1
+f_include_lang $BSDCFG_LIBE/include/messages.subr
+
+APP_DIR="dot"
+f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
+
+ipgm=$( f_index_menu_selection $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" )
+[ $? -eq $SUCCESS -a "$ipgm" ] && pgm="$ipgm"
+
+############################################################ CONFIGURATION
+
+#
+# Locataion 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 1 "$msg_directory_not_found" "$BSDCFG_LIB"
+
+#
+# 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
+ #
+ # 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 \
+ ; 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 -v file="$file" -v item="${file%%/*}" '
+ BEGIN { regex = "^f_include \\$BSDCFG_LIBE/" }
+ ( $0 ~ regex "include/" ) {
+ sub(regex, "")
+ print
+ }
+ ( $0 ~ regex "\\$APP_DIR/include/" ) {
+ sub(regex "\\$APP_DIR", item)
+ print
+ }
+ ' $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
+ #
+ for file in $include_file_list; do
+ include_file_list="$include_file_list $(
+ awk -v file="$file" -v item="${file%%/*}" '
+ BEGIN { regex = "^f_include \\$BSDCFG_LIBE/" }
+ ( $0 ~ regex "include/" ) {
+ sub(regex, "")
+ print
+ }
+ ( $0 ~ regex "\\$APP_DIR/include/" ) {
+ sub(regex "\\$APP_DIR", item)
+ print
+ }
+ ' $file
+ )"
+ done
+
+ #
+ # Sort the 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
+ )
+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 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, // 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#*include/}\""
+ 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"
+ file_list=$(
+ for file in \
+ $BSDCONFIG \
+ $menu_program_list \
+ $submenu_program_list \
+ $cmd_program_list \
+ $include_file_list \
+ ; do
+ [ -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" \
+ -v item="${file%%/*}" \
+ -v bsdconfig="$BSDCONFIG" \
+ '
+ BEGIN { regex = "^f_include \\$BSDCFG_LIBE/" }
+ ( $0 ~ regex "include/" ) {
+ sub(regex, "")
+ if ( file == bsdconfig ) sub(".*/", "", file)
+ printf "\t\t\"%s\" -> \"%s\";\n", $0, file
+ }
+ ( $0 ~ regex "\\$APP_DIR/include/" ) {
+ sub(regex "\\$APP_DIR", item)
+ if ( file == bsdconfig ) sub(".*/", "", file)
+ printf "\t\t\"%s\" -> \"%s\";\n", $0, file
+ }
+ ' $file
+ done | sort | awk '
+ BEGIN { found = 0 }
+ {
+ # If already found or no-match... just spew
+ if ( found ) { print; next }
+ if ( $0 !~ /^[[:space:]]*"include\// ) { print; next }
+ printf "\t\tedge [ label = \"\\T\", fontsize = 9 ];\n"
+ print; found = 1
+ }'
+ 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"
+if [ "$SHOW_INCLUDES" ]; then
+ printf '\t\tsubgraph "cluster_bsdconfig_includes" {\n'
+ printf '\t\t\tbgcolor = "%s";\n' "$bgcolor_includes"
+ printf '\t\t\tlabel = "%s";\n' "$msg_includes"
+ for include_file in $include_file_list; do
+ case "$include_file" in
+ include/*) printf '\t\t\t"%s";\n' "$include_file";;
+ esac
+ done
+ printf '\t\t};\n'
+fi
+end_nodelist
+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
+################################################################################
diff --git a/usr.sbin/bsdconfig/dot/include/Makefile b/usr.sbin/bsdconfig/dot/include/Makefile
new file mode 100644
index 0000000..9bbdea0
--- /dev/null
+++ b/usr.sbin/bsdconfig/dot/include/Makefile
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+NO_OBJ=
+
+FILESDIR= ${LIBEXECDIR}/bsdconfig/dot/include
+FILES= messages.subr
+
+beforeinstall:
+ mkdir -p ${DESTDIR}${FILESDIR}
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/bsdconfig/dot/include/messages.subr b/usr.sbin/bsdconfig/dot/include/messages.subr
new file mode 100644
index 0000000..527f308
--- /dev/null
+++ b/usr.sbin/bsdconfig/dot/include/messages.subr
@@ -0,0 +1,30 @@
+# Copyright (c) 2012 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$
+
+msg_graph_label_with_command="bsdconfig(8)\\\ndot(1) output generated by \`\`%s''"
+msg_graph_label_with_command_and_date="bsdconfig(8)\\\ndot(1) output generated by \`\`%s'' on\\\n%s"
+msg_includes="Includes"
+msg_shortcuts="Shortcuts"
OpenPOWER on IntegriCloud