Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/freebsd/poudriere.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan Drewery <bryan@shatow.net>2022-09-14 23:03:31 +0300
committerBryan Drewery <bryan@shatow.net>2022-11-05 18:47:57 +0300
commitffefb5706663204f56271bad77621022abfdd9cf (patch)
tree832f4105c278742c78eeccd541cc5e2f42bf258e
parent4a74af201588e35faf734b51c78ca2c8e9a92b46 (diff)
display_output: Allow filtering and re-ordering columns
This brings some major refactoring.
-rw-r--r--src/share/poudriere/include/display.sh249
-rw-r--r--test/display.sh433
2 files changed, 600 insertions, 82 deletions
diff --git a/src/share/poudriere/include/display.sh b/src/share/poudriere/include/display.sh
index ca9c218f..ff17c5f3 100644
--- a/src/share/poudriere/include/display.sh
+++ b/src/share/poudriere/include/display.sh
@@ -24,56 +24,120 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
+EX_DATAERR=65
+EX_SOFTWARE=70
+
+DISPLAY_SEP=$'\002'
+DISPLAY_DYNAMIC_FORMAT_DEFAULT="%%-%ds"
+DISPLAY_TRIM_TRAILING_FIELD=1
+
display_setup() {
[ $# -eq 1 ] || [ $# -eq 2 ] || eargs display_setup format [column_sort]
+ local IFS
+ local -; set -f
+
_DISPLAY_DATA=
- _DISPLAY_FORMAT="$1"
+ _DISPLAY_FORMAT="${1:-dynamic}"
+ _DISPLAY_HEADER=
_DISPLAY_COLUMN_SORT="${2-}"
_DISPLAY_FOOTER=
+ _DISPLAY_LINES=0
+ _DISPLAY_COLS=0
+
+ # encode
+ set -- ${_DISPLAY_FORMAT}
+ IFS="${DISPLAY_SEP}"
+ _DISPLAY_FORMAT="$@"
+ unset IFS
}
display_add() {
- local arg line tab
+ [ $# -gt 0 ] || eargs display_add col [col...]
+ local IFS
- unset line
- tab=$'\t'
- # Ensure blank arguments and spaced-arguments are respected.
- # This is mostly to deal with sorting later
- for arg do
- if [ -z "${arg}" ]; then
- arg=" "
+ if [ -z "${_DISPLAY_HEADER}" ]; then
+ local arg argi line argformat format
+
+ argi=1
+ unset line
+ format=
+ for arg do
+ # Collect header custom formats if using dynamic
+ if [ "${_DISPLAY_FORMAT}" == "dynamic" ]; then
+ case "${arg}" in
+ *:*%%*)
+ argformat="${arg#*:}"
+ arg="${arg%%:*}"
+ ;;
+ *)
+ argformat="${DISPLAY_DYNAMIC_FORMAT_DEFAULT}"
+ ;;
+ esac
+ format="${format:+${format}${DISPLAY_SEP}}${argformat}"
+ fi
+ line="${line:+${line}${DISPLAY_SEP}}${arg}"
+ hash_set _display_header "${arg}" "${argi}"
+ argi=$((argi + 1))
+ done
+ _DISPLAY_COLS=$((argi - 1))
+ _DISPLAY_HEADER="${line}"
+ if [ "${_DISPLAY_FORMAT}" == "dynamic" ]; then
+ _DISPLAY_FORMAT="${format}"
fi
- line="${line:+${line}${tab}}${arg}"
- done
+
+ return
+ fi
+
# Add in newline
- if [ -n "${_DISPLAY_DATA}" ]; then
+ if [ -n "${_DISPLAY_DATA-}" ]; then
_DISPLAY_DATA="${_DISPLAY_DATA}"$'\n'
fi
- _DISPLAY_DATA="${_DISPLAY_DATA:+${_DISPLAY_DATA}}${line}"
- return 0
+ _DISPLAY_LINES=$((_DISPLAY_LINES + 1))
+ # encode
+ IFS="${DISPLAY_SEP}"
+ _DISPLAY_DATA="${_DISPLAY_DATA:+${_DISPLAY_DATA}}""$@"
+ unset IFS
}
display_footer() {
- local arg line tab
+ local IFS
+
+ # encode
+ IFS="${DISPLAY_SEP}"
+ _DISPLAY_FOOTER="$@"
+ unset IFS
+}
- unset line
- tab=$'\t'
- # Ensure blank arguments and spaced-arguments are respected.
- for arg do
+_display_check_lengths() {
+ local cnt arg max_length
+ local IFS
+ local -; set -f
+
+ # decode
+ IFS="${DISPLAY_SEP}"
+ set -- $@
+ unset IFS
+
+ cnt=0
+ for arg in "$@"; do
+ cnt=$((cnt + 1))
if [ -z "${arg}" ]; then
- arg=" "
+ continue
+ fi
+ stripansi "${arg}" arg
+ hash_get _display_lengths "${cnt}" max_length || max_length=0
+ if [ "${#arg}" -gt "${max_length}" ]; then
+ hash_set _display_lengths "${cnt}" "${#arg}"
fi
- line="${line:+${line}${tab}}${arg}"
done
- # Add in newline
- _DISPLAY_FOOTER="${line}"
- return 0
}
+# display_output [col ...]
display_output() {
- local cnt lengths length format arg flag quiet line n
- local header header_format
+ local lengths format arg flag quiet line n
+ local cols header_format
local OPTIND=1
+ local IFS
local -
set -f
@@ -93,45 +157,84 @@ display_output() {
shift $((OPTIND-1))
- format="${_DISPLAY_FORMAT}"
+ # cols to filter/reorder on
+ cols=
+ if [ "$#" -gt 0 ]; then
+ local col awktmp
- # Determine optimal format
- n=0
- while IFS= mapfile_read_loop_redir line; do
- n=$((n + 1))
- if [ "${n}" -eq 1 ]; then
- if [ "${quiet}" -eq 1 ]; then
- continue
- fi
- header="${line}"
- fi
- IFS=$'\t'
- set -- ${line}
- unset IFS
- cnt=0
+ _DISPLAY_COLS=0
for arg in "$@"; do
- hash_get lengths ${cnt} max_length || max_length=0
- stripansi "${arg}" arg
- if [ ${#arg} -gt ${max_length} ]; then
- # Keep the hash var local to this function
- _hash_var_name "lengths" "${cnt}"
- local ${_hash_var_name}
- # Set actual value
- hash_set lengths ${cnt} ${#arg}
+ if ! hash_remove _display_header "${arg}" col; then
+ err ${EX_DATAERR:?} "No column named '${arg}'"
fi
- cnt=$((cnt + 1))
+ # cols="$3,$2,$1" for awk printing
+ cols="${cols:+${cols},}\$${col}"
+ _DISPLAY_COLS=$((_DISPLAY_COLS + 1))
done
+
+ # Re-order and filter using awk(1) back into our internal vars.
+ awktmp=$(mktemp -t display_output)
+ {
+ echo "${_DISPLAY_FORMAT}"
+ echo "${_DISPLAY_HEADER}"
+ echo "${_DISPLAY_DATA}" |
+ sort -t "${DISPLAY_SEP}" ${_DISPLAY_COLUMN_SORT}
+ echo "${_DISPLAY_FOOTER}"
+ } > "${awktmp}.in"
+ awk -F"${DISPLAY_SEP}" -vOFS="${DISPLAY_SEP}" \
+ "{print ${cols}}" "${awktmp}.in" > "${awktmp}"
+ n=-1
+ while IFS= mapfile_read_loop "${awktmp}" line; do
+ case "${n}" in
+ -1)
+ unset _DISPLAY_DATA
+ _DISPLAY_FORMAT="${line}"
+ ;;
+ 0)
+ _DISPLAY_HEADER="${line}"
+ ;;
+ "$((_DISPLAY_LINES + 1))")
+ if [ -n "${_DISPLAY_FOOTER}" ]; then
+ _DISPLAY_FOOTER="${line}"
+ fi
+ ;;
+ *)
+ if [ -n "${_DISPLAY_DATA-}" ]; then
+ _DISPLAY_DATA="${_DISPLAY_DATA}"$'\n'
+ fi
+ _DISPLAY_DATA="${_DISPLAY_DATA:+${_DISPLAY_DATA}}${line}"
+ ;;
+ esac
+ n=$((n + 1))
+ done
+ rm -f "${awktmp}" "${awktmp}.in"
+ else
+ _DISPLAY_DATA="$(echo "${_DISPLAY_DATA}" |
+ sort -t "${DISPLAY_SEP}" ${_DISPLAY_COLUMN_SORT})"
+ fi
+
+ # Determine optimal format from filtered data
+ _display_check_lengths "${_DISPLAY_HEADER}"
+ _display_check_lengths "${_DISPLAY_FOOTER}"
+ while IFS= mapfile_read_loop_redir line; do
+ _display_check_lengths "${line}"
done <<-EOF
${_DISPLAY_DATA}
- ${_DISPLAY_FOOTER}
EOF
# Set format lengths if format is dynamic width
+ # decode
+ IFS="${DISPLAY_SEP}"
+ set -- ${_DISPLAY_FORMAT}
+ unset IFS
+ format="$@"
case "${format}" in
*%%*)
+ local length
+
set -- ${format}
lengths=
- n=0
+ n=1
for arg in "$@"; do
# Check if this is a format argument
case "${arg}" in
@@ -140,9 +243,18 @@ display_output() {
esac
case ${arg} in
*%d*)
- hash_get lengths ${n} length
+ hash_remove _display_lengths "${n}" length
+ if [ "${DISPLAY_TRIM_TRAILING_FIELD}" -eq 1 ] &&
+ [ "${n}" -eq "${_DISPLAY_COLS}" ]; then
+ case "${arg}" in
+ *-*) length=0 ;;
+ esac
+ fi
lengths="${lengths:+${lengths} }${length}"
;;
+ *)
+ hash_unset _display_lengths "${n}" || :
+ ;;
esac
n=$((n + 1))
done
@@ -150,32 +262,39 @@ display_output() {
;;
esac
- # Show header separately so it is not sorted
+ # Header
if [ "${quiet}" -eq 0 ]; then
- stripansi "${header}" header
+ stripansi "${_DISPLAY_HEADER}" _DISPLAY_HEADER
stripansi "${format}" header_format
- IFS=$'\t'
- set -- ${header}
+ # decode
+ IFS="${DISPLAY_SEP}"
+ set -- ${_DISPLAY_HEADER}
unset IFS
printf "${header_format}\n" "$@"
fi
- # Sort as configured in display_setup()
- echo "${_DISPLAY_DATA}" | tail -n +2 | \
- sort -t $'\t' ${_DISPLAY_COLUMN_SORT} | \
- while IFS= mapfile_read_loop_redir line; do
- IFS=$'\t'
+ # Data
+ while IFS= mapfile_read_loop_redir line; do
+ # decode
+ IFS="${DISPLAY_SEP}"
set -- ${line}
unset IFS
printf "${format}\n" "$@"
- done
+ done <<-EOF
+ ${_DISPLAY_DATA}
+ EOF
+
+ # Footer
if [ -n "${_DISPLAY_FOOTER}" ]; then
- IFS=$'\t'
+ # decode
+ IFS="${DISPLAY_SEP}"
set -- ${_DISPLAY_FOOTER}
unset IFS
printf "${format}\n" "$@"
fi
unset _DISPLAY_DATA _DISPLAY_FORMAT \
- _DISPLAY_COLUMN_SORT _DISPLAY_FOOTER
+ _DISPLAY_COLUMN_SORT \
+ _DISPLAY_LINES _DISPLAY_COLS \
+ _DISPLAY_FOOTER _DISPLAY_HEADER
}
diff --git a/test/display.sh b/test/display.sh
index 56256016..709ba03a 100644
--- a/test/display.sh
+++ b/test/display.sh
@@ -23,6 +23,70 @@ $(cat -vet "${expected}")"
alias assert_file='_assert_file "$0:$LINENO"'
{
+ # Basic test
+ display_setup "%%-%ds %%-%ds" "-k2,2V -k1,1d"
+ display_add "Name 1" "Release"
+ display_add "blah" "11.2-RELEASE-p1"
+ display_add "blah" "10.0-RELEASE"
+ display_add "blah 1" "10.2-RELEASE"
+ display_add "blah" "10.2-RELEASE-p10"
+ display_add "blah2" "10.2-RELEASE-p1"
+ display_add "blah" "10.2-RELEASE-p1"
+ display_add "blah" "9.3-RELEASE-p10"
+ display_add "blah" "9.3-RELEASE-p1"
+ display_add "blah" "8.2-RELEASE-p1"
+ outfile=$(mktemp -t outfile)
+ display_output > "${outfile}"
+ expected=$(mktemp -t expected)
+ cat > "${expected}" <<-EOF
+ Name 1 Release
+ blah 8.2-RELEASE-p1
+ blah 9.3-RELEASE-p1
+ blah 9.3-RELEASE-p10
+ blah 10.0-RELEASE
+ blah 1 10.2-RELEASE
+ blah 10.2-RELEASE-p1
+ blah2 10.2-RELEASE-p1
+ blah 10.2-RELEASE-p10
+ blah 11.2-RELEASE-p1
+ EOF
+ assert_file "${expected}" "${outfile}"
+}
+
+{
+ # Basic test via filter path
+ display_setup "%%-%ds %%-%ds" "-k2,2V -k1,1d"
+ display_add "Name 1" "Release"
+ display_add "blah" "11.2-RELEASE-p1"
+ display_add "blah" "10.0-RELEASE"
+ display_add "blah 1" "10.2-RELEASE"
+ display_add "blah" "10.2-RELEASE-p10"
+ display_add "blah2" "10.2-RELEASE-p1"
+ display_add "blah" "10.2-RELEASE-p1"
+ display_add "blah" "9.3-RELEASE-p10"
+ display_add "blah" "9.3-RELEASE-p1"
+ display_add "blah" "8.2-RELEASE-p1"
+ outfile=$(mktemp -t outfile)
+ display_output "Name 1" "Release" > "${outfile}"
+ expected=$(mktemp -t expected)
+ cat > "${expected}" <<-EOF
+ Name 1 Release
+ blah 8.2-RELEASE-p1
+ blah 9.3-RELEASE-p1
+ blah 9.3-RELEASE-p10
+ blah 10.0-RELEASE
+ blah 1 10.2-RELEASE
+ blah 10.2-RELEASE-p1
+ blah2 10.2-RELEASE-p1
+ blah 10.2-RELEASE-p10
+ blah 11.2-RELEASE-p1
+ EOF
+ assert_file "${expected}" "${outfile}"
+}
+
+ # Basic test without trimming trailing field
+ old="${DISPLAY_TRIM_TRAILING_FIELD}"
+ DISPLAY_TRIM_TRAILING_FIELD=0
display_setup "%%-%ds %%-%ds" "-k2,2V -k1,1d"
display_add "Name" "Release"
display_add "blah" "11.2-RELEASE-p1"
@@ -50,6 +114,134 @@ alias assert_file='_assert_file "$0:$LINENO"'
blah 11.2-RELEASE-p1
EOF
assert_file "${expected}" "${outfile}"
+ DISPLAY_TRIM_TRAILING_FIELD="${old}"
+}
+
+{
+ # Test quiet mode
+ display_setup "%%-%ds %%-%ds" "-k2,2V -k1,1d"
+ display_add "Name" "Release"
+ display_add "blah" "11.2-RELEASE-p1"
+ display_add "blah" "10.0-RELEASE"
+ display_add "blah" "10.2-RELEASE"
+ display_add "blah" "10.2-RELEASE-p10"
+ display_add "blah2" "10.2-RELEASE-p1"
+ display_add "blah" "10.2-RELEASE-p1"
+ display_add "blah" "9.3-RELEASE-p10"
+ display_add "blah" "9.3-RELEASE-p1"
+ display_add "blah" "8.2-RELEASE-p1"
+ outfile=$(mktemp -t outfile)
+ display_output -q > "${outfile}"
+ expected=$(mktemp -t expected)
+ cat > "${expected}" <<-EOF
+ blah 8.2-RELEASE-p1
+ blah 9.3-RELEASE-p1
+ blah 9.3-RELEASE-p10
+ blah 10.0-RELEASE
+ blah 10.2-RELEASE
+ blah 10.2-RELEASE-p1
+ blah2 10.2-RELEASE-p1
+ blah 10.2-RELEASE-p10
+ blah 11.2-RELEASE-p1
+ EOF
+ assert_file "${expected}" "${outfile}"
+}
+
+{
+ display_setup "%%-%ds %%-%ds" "-k2,2V -k1,1d"
+ display_add "Name" "Release"
+ display_add "blah" "11.2-RELEASE-p1"
+ display_add "blah" "10.0-RELEASE"
+ display_add "blah" "10.2-RELEASE"
+ display_add "blah" "10.2-RELEASE-p10"
+ display_add "blah2" "10.2-RELEASE-p1"
+ display_add "blah" "10.2-RELEASE-p1"
+ display_add "blah" "9.3-RELEASE-p10"
+ display_add "blah" "9.3-RELEASE-p1"
+ display_add "blah" "8.2-RELEASE-p1"
+ # Test for blank and null params
+ display_add "blah3"
+ display_add "blah4" ""
+ display_add "" "11-RELEASE"
+ outfile=$(mktemp -t outfile)
+ display_output > "${outfile}"
+ expected=$(mktemp -t expected)
+ cat > "${expected}" <<-EOF
+ Name Release
+ blah3
+ blah4
+ blah 8.2-RELEASE-p1
+ blah 9.3-RELEASE-p1
+ blah 9.3-RELEASE-p10
+ blah 10.0-RELEASE
+ blah 10.2-RELEASE
+ blah 10.2-RELEASE-p1
+ blah2 10.2-RELEASE-p1
+ blah 10.2-RELEASE-p10
+ 11-RELEASE
+ blah 11.2-RELEASE-p1
+ EOF
+ assert_file "${expected}" "${outfile}"
+}
+
+{
+ display_setup "%%-%ds %%-%ds" "-k2,2V -k1,1d"
+ display_add "Name" "Release"
+ display_add "blah" "11.2-RELEASE-p1"
+ display_add "blah" "10.0-RELEASE"
+ display_add "blah" "10.2-RELEASE"
+ display_add "blah" "10.2-RELEASE-p10"
+ display_add "blah2" "10.2-RELEASE-p1"
+ display_add "blah" "10.2-RELEASE-p1"
+ display_add "blah" "9.3-RELEASE-p10"
+ display_add "blah" "9.3-RELEASE-p1"
+ display_add "blah" "8.2-RELEASE-p1"
+ outfile=$(mktemp -t outfile)
+ display_output "Name" > "${outfile}"
+ expected=$(mktemp -t expected)
+ cat > "${expected}" <<-EOF
+ Name
+ blah
+ blah
+ blah
+ blah
+ blah
+ blah
+ blah2
+ blah
+ blah
+ EOF
+ assert_file "${expected}" "${outfile}" "Filtered column"
+}
+
+{
+ display_setup "%%-%ds %%-%ds" "-k2,2V -k1,1d"
+ display_add "Name" "Release"
+ display_add "blah" "11.2-RELEASE-p1"
+ display_add "blah" "10.0-RELEASE"
+ display_add "blah" "10.2-RELEASE"
+ display_add "blah" "10.2-RELEASE-p10"
+ display_add "blah2" "10.2-RELEASE-p1"
+ display_add "blah" "10.2-RELEASE-p1"
+ display_add "blah" "9.3-RELEASE-p10"
+ display_add "blah" "9.3-RELEASE-p1"
+ display_add "blah" "8.2-RELEASE-p1"
+ outfile=$(mktemp -t outfile)
+ display_output "Release" > "${outfile}"
+ expected=$(mktemp -t expected)
+ cat > "${expected}" <<-EOF
+ Release
+ 8.2-RELEASE-p1
+ 9.3-RELEASE-p1
+ 9.3-RELEASE-p10
+ 10.0-RELEASE
+ 10.2-RELEASE
+ 10.2-RELEASE-p1
+ 10.2-RELEASE-p1
+ 10.2-RELEASE-p10
+ 11.2-RELEASE-p1
+ EOF
+ assert_file "${expected}" "${outfile}" "Filtered column"
}
{
@@ -71,6 +263,25 @@ alias assert_file='_assert_file "$0:$LINENO"'
}
{
+ # Test footer with dynamic
+ display_setup "%%-%ds %%%ds" "-k2,2V -k1,1d"
+ display_add "Name" "Memory"
+ display_add "foo" "10"
+ display_add "blah" "5"
+ display_footer "" "15 G"
+ outfile=$(mktemp -t outfile)
+ display_output "Name" "Memory" > "${outfile}"
+ expected=$(mktemp -t expected)
+ cat > "${expected}" <<-EOF
+ Name Memory
+ blah 5
+ foo 10
+ 15 G
+ EOF
+ assert_file "${expected}" "${outfile}" "dynamic with footer"
+}
+
+{
display_setup "%%-%ds %%-%ds" "-k2,2V -k1,1d"
display_add "Name" "Memory"
display_add "foo" "10"
@@ -81,27 +292,27 @@ alias assert_file='_assert_file "$0:$LINENO"'
expected=$(mktemp -t expected)
cat > "${expected}" <<-EOF
Name Memory
- blah 5
- foo 10
- 15 G
+ blah 5
+ foo 10
+ 15 G
EOF
assert_file "${expected}" "${outfile}"
}
{
display_setup "%%-%ds %%-%ds %%-%ds" "-k2,2V -k1,1d"
- display_add "Name" "Mem" "Blah"
- display_add "foo" "10" "0"
+ display_add "Name 1" "Mem" "Blah"
+ display_add "foo bar" "10" "0"
display_add "blah" "5" "0"
display_footer "" "15 GiB" "0"
outfile=$(mktemp -t outfile)
display_output > "${outfile}"
expected=$(mktemp -t expected)
cat > "${expected}" <<-EOF
- Name Mem Blah
- blah 5 0
- foo 10 0
- 15 GiB 0
+ Name 1 Mem Blah
+ blah 5 0
+ foo bar 10 0
+ 15 GiB 0
EOF
assert_file "${expected}" "${outfile}"
}
@@ -114,7 +325,7 @@ alias assert_file='_assert_file "$0:$LINENO"'
display_output > "${outfile}"
expected=$(mktemp -t expected)
cat > "${expected}" <<-EOF
- Name Release
+ Name Release
11.2-RELEASE-p1
EOF
assert_file "${expected}" "${outfile}"
@@ -197,13 +408,201 @@ alias assert_file='_assert_file "$0:$LINENO"'
expected=$(mktemp -t expected)
cat > "${expected}" <<-EOF
JID IP Address vnet_num
- 85 192.168.2.52 0
- 87 192.168.2.38 0
- 99 10.2.1.3,127.0.1.3 0
- 150 10.2.1.4,127.0.1.4 0
- 187 0
- 188 0
- 189 0
+ 85 192.168.2.52 0
+ 87 192.168.2.38 0
+ 99 10.2.1.3,127.0.1.3 0
+ 150 10.2.1.4,127.0.1.4 0
+ 187 0
+ 188 0
+ 189 0
EOF
assert_file "${expected}" "${outfile}"
}
+
+{
+ # Test with dynamic formats
+ display_setup "dynamic" "-k1,1n"
+ display_add "JID" "IP Address" "vnet_num"
+ display_add "189" "" 0
+ display_add "188" "" 0
+ display_add "187" "" 0
+ display_add "150" "10.2.1.4,127.0.1.4" 0
+ display_add "99" "10.2.1.3,127.0.1.3" 0
+ display_add "87" "192.168.2.38" 0
+ display_add "85" "192.168.2.52" 0
+ outfile=$(mktemp -t outfile)
+ display_output > "${outfile}"
+ expected=$(mktemp -t expected)
+ cat > "${expected}" <<-EOF
+ JID IP Address vnet_num
+ 85 192.168.2.52 0
+ 87 192.168.2.38 0
+ 99 10.2.1.3,127.0.1.3 0
+ 150 10.2.1.4,127.0.1.4 0
+ 187 0
+ 188 0
+ 189 0
+ EOF
+ assert_file "${expected}" "${outfile}" "dynamic formats"
+}
+
+{
+ # Test with dynamic formats with specified field format
+ display_setup "dynamic" "-k1,1n"
+ display_add "JID:%%%ds" "IP Address:%%%ds" "vnet_num"
+ display_add "189" "" 0
+ display_add "188" "" 0
+ display_add "187" "" 0
+ display_add "150" "10.2.1.4,127.0.1.4" 0
+ display_add "99" "10.2.1.3,127.0.1.3" 0
+ display_add "87" "192.168.2.38" 0
+ display_add "85" "192.168.2.52" 0
+ outfile=$(mktemp -t outfile)
+ display_output > "${outfile}"
+ expected=$(mktemp -t expected)
+ cat > "${expected}" <<-EOF
+ JID IP Address vnet_num
+ 85 192.168.2.52 0
+ 87 192.168.2.38 0
+ 99 10.2.1.3,127.0.1.3 0
+ 150 10.2.1.4,127.0.1.4 0
+ 187 0
+ 188 0
+ 189 0
+ EOF
+ assert_file "${expected}" "${outfile}" "dynamic formats with specified field format"
+}
+
+{
+ # Test filter/reorder
+ display_setup "%%%ds %%-%ds %%-%ds" "-k1,1n"
+ display_add "JID" "IP Address super long" "vnet_num"
+ display_add "189" "" 0
+ display_add "188" "" 0
+ display_add "187" "" 0
+ display_add "150" "10.2.1.4,127.0.1.4" 0
+ display_add "99" "10.2.1.3,127.0.1.3" 0
+ display_add "87" "192.168.2.38" 0
+ display_add "85" "192.168.2.52" 0
+ outfile=$(mktemp -t outfile)
+ display_output "vnet_num" "IP Address" > "${outfile}"
+ expected=$(mktemp -t expected)
+ cat > "${expected}" <<-EOF
+ vnet_num IP Address super long
+ 0 192.168.2.52
+ 0 192.168.2.38
+ 0 10.2.1.3,127.0.1.3
+ 0 10.2.1.4,127.0.1.4
+ 0
+ 0
+ 0
+ EOF
+ assert_file "${expected}" "${outfile}" "filtered/reordered column"
+}
+
+{
+ # Test filter/reorder with quiet
+ display_setup "%%%ds %%-%ds %%-%ds" "-k1,1n"
+ display_add "JID" "IP Address" "vnet_num"
+ display_add "189" "" 0
+ display_add "188" "" 0
+ display_add "187" "" 0
+ display_add "150" "10.2.1.4,127.0.1.4" 0
+ display_add "99" "10.2.1.3,127.0.1.3" 0
+ display_add "87" "192.168.2.38" 0
+ display_add "85" "192.168.2.52" 0
+ outfile=$(mktemp -t outfile)
+ display_output -q "vnet_num" "IP Address" > "${outfile}"
+ expected=$(mktemp -t expected)
+ cat > "${expected}" <<-EOF
+ 0 192.168.2.52
+ 0 192.168.2.38
+ 0 10.2.1.3,127.0.1.3
+ 0 10.2.1.4,127.0.1.4
+ 0
+ 0
+ 0
+ EOF
+ assert_file "${expected}" "${outfile}" "filtered/reordered column + quiet"
+}
+
+{
+ # Test filter/reorder
+ display_setup "%%%ds %%-%ds %%-%ds" "-k1,1n"
+ display_add "JID" "IP Address" "vnet_num"
+ display_add "189" "" 0
+ display_add "188" "" 0
+ display_add "187" "" 0
+ display_add "150" "10.2.1.4,127.0.1.4" 0
+ display_add "99" "10.2.1.3,127.0.1.3" 0
+ display_add "87" "192.168.2.38" 0
+ display_add "85" "192.168.2.52" 0
+ outfile=$(mktemp -t outfile)
+ display_output "vnet_num" "IP Address" > "${outfile}"
+ expected=$(mktemp -t expected)
+ cat > "${expected}" <<-EOF
+ vnet_num IP Address
+ 0 192.168.2.52
+ 0 192.168.2.38
+ 0 10.2.1.3,127.0.1.3
+ 0 10.2.1.4,127.0.1.4
+ 0
+ 0
+ 0
+ EOF
+ assert_file "${expected}" "${outfile}" "filtered column"
+}
+
+{
+ # Test with dynamic formats with filter/reorder
+ display_setup "dynamic" "-k1,1n"
+ display_add "JID" "IP Address" "vnet_num"
+ display_add "189" "" 0
+ display_add "188" "" 0
+ display_add "187" "" 0
+ display_add "150" "10.2.1.4,127.0.1.4" 0
+ display_add "99" "10.2.1.3,127.0.1.3" 0
+ display_add "87" "192.168.2.38" 0
+ display_add "85" "192.168.2.52" 0
+ outfile=$(mktemp -t outfile)
+ display_output "JID" "vnet_num" "IP Address" > "${outfile}"
+ expected=$(mktemp -t expected)
+ cat > "${expected}" <<-EOF
+ JID vnet_num IP Address
+ 85 0 192.168.2.52
+ 87 0 192.168.2.38
+ 99 0 10.2.1.3,127.0.1.3
+ 150 0 10.2.1.4,127.0.1.4
+ 187 0
+ 188 0
+ 189 0
+ EOF
+ assert_file "${expected}" "${outfile}" "dynamic formats with reordered cols"
+}
+
+{
+ # Test with dynamic formats and filtered/reordered
+ display_setup "dynamic" "-k1,1n"
+ display_add "JID" "IP Address" "vnet_num"
+ display_add "189" "" 0
+ display_add "188" "" 0
+ display_add "187" "" 0
+ display_add "150" "10.2.1.4,127.0.1.4" 0
+ display_add "99" "10.2.1.3,127.0.1.3" 0
+ display_add "87" "192.168.2.38" 0
+ display_add "85" "192.168.2.52" 0
+ outfile=$(mktemp -t outfile)
+ display_output "vnet_num" "IP Address" "JID" > "${outfile}"
+ expected=$(mktemp -t expected)
+ cat > "${expected}" <<-EOF
+ vnet_num IP Address JID
+ 0 192.168.2.52 85
+ 0 192.168.2.38 87
+ 0 10.2.1.3,127.0.1.3 99
+ 0 10.2.1.4,127.0.1.4 150
+ 0 187
+ 0 188
+ 0 189
+ EOF
+ assert_file "${expected}" "${outfile}" "dynamic format with reordered column"
+}