diff --git a/Makefile b/Makefile index 2944ef0..15252b7 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ MAJOR_VERSION=1 -VERSION=1.20 +VERSION=1.21 TARGET := bash-boost-$(VERSION) SRCS := $(shell find src -type f -name "*.sh" | sort) diff --git a/docgen b/docgen index bfb7c3f..079a2dc 100755 --- a/docgen +++ b/docgen @@ -54,6 +54,9 @@ sub formatmd { elsif (my ($v) = ($text =~ m/^\s*\@returns:\s*(.*)$/)) { print "\n**Returns:** $v\n"; } + elsif (($v) = ($text =~ m/^\s*\@requires:\s*(.*)$/)) { + print "\n**Requires:** bash $v or later\n"; + } elsif ($text =~ m/^\s*\@notes:/) { print "\n**Notes:**\n\n"; } diff --git a/src/MANUAL.md b/src/MANUAL.md index b981a97..e23c260 100644 --- a/src/MANUAL.md +++ b/src/MANUAL.md @@ -1,7 +1,7 @@ --- title: BASH-BOOST(1) author: github.com/tomocafe -date: August 11, 2024 +date: September 9, 2024 --- @@ -1133,6 +1133,8 @@ func() { Unpacks list items into named variables +**Requires:** bash 4.3 or later + **Arguments:** - `LISTVAR`: name of the list variable (do not include $) @@ -1142,6 +1144,8 @@ Unpacks list items into named variables Maps a function over a list, modifying it in place +**Requires:** bash 4.3 or later + **Arguments:** - `LISTVAR`: name of the list variable (do not include $) @@ -1151,6 +1155,8 @@ Maps a function over a list, modifying it in place Maps a function over a list of keys to generate an associative array +**Requires:** bash 4.3 or later + **Arguments:** - `LISTVAR`: name of an associative array variable (do not include $) diff --git a/src/core/core.sh b/src/core/core.sh index 9132601..59942cf 100644 --- a/src/core/core.sh +++ b/src/core/core.sh @@ -165,3 +165,13 @@ function bb_cleanup () { done < <(set -o posix; set) : # don't use return "$__bb_true" here, it's now undefined } + +function _bb_checkbashversion () { + [[ ${BASH_VERSINFO[0]} -lt ${1:-0} ]] && return $__bb_false + [[ ${BASH_VERSINFO[0]} -eq ${1:-0} && ${BASH_VERSINFO[1]} -lt ${2:-0} ]] && return $__bb_false + return $__bb_true +} + +function _bb_unsupportedbashversion () { + echo "$1: requires bash ${2:-0}.${3:-0} or later (detected $BASH_VERSION)" 1>&2 +} diff --git a/src/man/man1/bash-boost.1 b/src/man/man1/bash-boost.1 index 55ac686..10d9261 100644 --- a/src/man/man1/bash-boost.1 +++ b/src/man/man1/bash-boost.1 @@ -1,208 +1,175 @@ -.\" Automatically generated by Pandoc 2.19.2 +.\" Automatically generated by Pandoc 3.3 .\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "BASH-BOOST" "1" "August 11, 2024" "" "" -.hy +.TH "BASH\-BOOST" "1" "September 9, 2024" "" .SH Package cli/arg -.PP Routines for parsing command line arguments .PP \f[B]Example:\f[R] .IP -.nf -\f[C] +.EX bb_setprog \[dq]myprogram\[dq] bb_addopt f:foo \[dq]Number of foos (default: 2)\[dq] 2 bb_addflag b:bar \[dq]Bar flag\[dq] bb_setpositional \[dq]THINGS\[dq] \[dq]Things to process\[dq] bb_parseargs \[dq]$\[at]\[dq] -set -- \[dq]${BB_POSARGS[\[at]]}\[dq] # $\[at] now only contains the positional arguments -bb_checkopt bar && echo \[dq]You gave the bar flag!\[dq] -bb_getopt -v fooval foo -[[ $fooval -gt 0 ]] || bb_errusage \[dq]foo val must be greater than 0\[dq] +set \-\- \[dq]${BB_POSARGS[\[at]]}\[dq] \f[I]# $\[at] now only contains the positional arguments\f[R] +bb_checkopt bar \f[B]&&\f[R] echo \[dq]You gave the bar flag!\[dq] +bb_getopt \-v fooval foo +\f[B][[\f[R] $fooval \-gt 0 \f[B]]]\f[R] \f[B]||\f[R] bb_errusage \[dq]foo val must be greater than 0\[dq] echo \[dq]You set foo to $fooval\[dq] -for arg in \[dq]$\[at]\[dq]; do +\f[B]for\f[R] arg \f[B]in\f[R] \[dq]$\[at]\[dq]\f[B];\f[R] \f[B]do\f[R] echo \[dq]You have item $arg\[dq] -done -\f[R] -.fi +\f[B]done\f[R] +.EE .PP \f[B]Example:\f[R] .IP -.nf -\f[C] +.EX bb_setprog \[dq]copy\[dq] bb_addflag \[dq]f:force\[dq] \[dq]force overwrite destination\[dq] bb_addarg \[dq]src\[dq] \[dq]source file/directory\[dq] bb_addarg \[dq]dst\[dq] \[dq]destination path\[dq] bb_parseargs \[dq]$\[at]\[dq] -bb_getopt -v src src || bb_errusage \[dq]missing required src argument\[dq] -bb_getopt -v dst fst || bb_errusage \[dq]missing required dst argument\[dq] -[[ -e \[dq]$dst\[dq] && ! bb_checkopt force ]] && bb_fatal \[dq]$dst exists\[dq] +bb_getopt \-v src src \f[B]||\f[R] bb_errusage \[dq]missing required src argument\[dq] +bb_getopt \-v dst fst \f[B]||\f[R] bb_errusage \[dq]missing required dst argument\[dq] +\f[B][[\f[R] \-e \[dq]$dst\[dq] \f[B]&&\f[R] ! bb_checkopt force \f[B]]]\f[R] \f[B]&&\f[R] bb_fatal \[dq]$dst exists\[dq] cp \[dq]$src\[dq] \[dq]$dst\[dq] -\f[R] -.fi -.SS \f[V]bb_addopt [SHORTNAME:]LONGNAME [DESCRIPTION] [DEFAULT]\f[R] -.PP +.EE +.SS \f[CR]bb_addopt [SHORTNAME:]LONGNAME [DESCRIPTION] [DEFAULT]\f[R] Adds a command line option to be parsed .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]SHORTNAME\f[R]: optional single character, e.g.\ \[lq]f\[rq] for an --f FOO option +\f[CR]SHORTNAME\f[R]: optional single character, e.g.\ \[lq]f\[rq] for +an \-f FOO option .IP \[bu] 2 -\f[V]LONGNAME\f[R]: required long name, e.g.\ \[lq]foo\[rq] for a +\f[CR]LONGNAME\f[R]: required long name, e.g.\ \[lq]foo\[rq] for a \[en]foo FOO option .IP \[bu] 2 -\f[V]DESCRIPTION\f[R]: description of the option used in help +\f[CR]DESCRIPTION\f[R]: description of the option used in help .IP \[bu] 2 -\f[V]DEFAULT\f[R]: the default value of the option if not given in the +\f[CR]DEFAULT\f[R]: the default value of the option if not given in the command line .PP \f[B]Notes:\f[R] .PP --h and \[en]help are reserved for automatically-generated command usage -and help -.SS \f[V]bb_addarg NAME DESCRIPTION [DEFAULT]\f[R] -.PP +\-h and \[en]help are reserved for automatically\-generated command +usage and help +.SS \f[CR]bb_addarg NAME DESCRIPTION [DEFAULT]\f[R] Adds a named argument .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]NAME\f[R]: unique, one-word name of the argument +\f[CR]NAME\f[R]: unique, one\-word name of the argument .IP \[bu] 2 -\f[V]DESCRIPTION\f[R]: description of the argument used in help +\f[CR]DESCRIPTION\f[R]: description of the argument used in help .IP \[bu] 2 -\f[V]DEFAULT\f[R]: default value if not given in the command line -.SS \f[V]bb_addflag [SHORTNAME:]LONGNAME [DESCRIPTION]\f[R] -.PP +\f[CR]DEFAULT\f[R]: default value if not given in the command line +.SS \f[CR]bb_addflag [SHORTNAME:]LONGNAME [DESCRIPTION]\f[R] Adds a command line flag to be parsed .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]SHORTNAME\f[R]: optional single character, e.g.\ \[lq]f\[rq] for an --f flag +\f[CR]SHORTNAME\f[R]: optional single character, e.g.\ \[lq]f\[rq] for +an \-f flag .IP \[bu] 2 -\f[V]LONGNAME\f[R]: required long name, e.g.\ \[lq]foo\[rq] for a +\f[CR]LONGNAME\f[R]: required long name, e.g.\ \[lq]foo\[rq] for a \[en]foo flag .IP \[bu] 2 -\f[V]DESCRIPTION\f[R]: description of the option used in help +\f[CR]DESCRIPTION\f[R]: description of the option used in help .PP \f[B]Notes:\f[R] .PP --h and \[en]help are reserved for automatically-generated command usage -and help -.SS \f[V]bb_argusage\f[R] -.PP +\-h and \[en]help are reserved for automatically\-generated command +usage and help +.SS \f[CR]bb_argusage\f[R] Print the command line usage string -.SS \f[V]bb_arghelp\f[R] -.PP +.SS \f[CR]bb_arghelp\f[R] Print the command line help .PP \f[B]Notes:\f[R] .PP Includes the usage string and a list of flags and options with their descriptions. -.SS \f[V]bb_errusage MESSAGE [RETURNVAL]\f[R] -.PP +.SS \f[CR]bb_errusage MESSAGE [RETURNVAL]\f[R] Issues an error message, prints the command usage, and exits the shell .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]MESSAGE\f[R]: error message to be printed +\f[CR]MESSAGE\f[R]: error message to be printed .IP \[bu] 2 -\f[V]RETURNVAL\f[R]: return code to exit with (defaults to 1) -.SS \f[V]bb_isflag LONGNAME\f[R] -.PP +\f[CR]RETURNVAL\f[R]: return code to exit with (defaults to 1) +.SS \f[CR]bb_isflag LONGNAME\f[R] Check if LONGNAME is a registered flag (not an option) .PP \f[B]Returns:\f[R] 0 if LONGNAME is a flag, 1 otherwise (i.e.\ it is an option) -.SS \f[V]bb_setprog [PROGNAME]\f[R] -.PP +.SS \f[CR]bb_setprog [PROGNAME]\f[R] Sets the name of the program for printing usage and help .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]PROGNAME\f[R]: name of the program (defaults to current script +\f[CR]PROGNAME\f[R]: name of the program (defaults to current script name) -.SS \f[V]bb_setpositional NAME DESCRIPTION\f[R] -.PP +.SS \f[CR]bb_setpositional NAME DESCRIPTION\f[R] Sets the name and description of the positional arguments .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]NAME\f[R]: one-word name of the positional arguments -(auto-capitalized) +\f[CR]NAME\f[R]: one\-word name of the positional arguments +(auto\-capitalized) .IP \[bu] 2 -\f[V]DESCRIPTION\f[R]: description of the positionals used in help -.SS \f[V]bb_parseargs ARGS\f[R] -.PP +\f[CR]DESCRIPTION\f[R]: description of the positionals used in help +.SS \f[CR]bb_parseargs ARGS\f[R] Parses command line arguments after registering valid flags and options .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]ARGS\f[R]: the list of command line arguments, usually +\f[CR]ARGS\f[R]: the list of command line arguments, usually \[lq]$\[at]\[rq] .PP \f[B]Notes:\f[R] .IP \[bu] 2 -Check flags with \f[V]bb_checkopt LONGNAME\f[R] +Check flags with \f[CR]bb_checkopt LONGNAME\f[R] .IP \[bu] 2 Get option setting values or named arguments with -\f[V]bb_getopt LONGNAME\f[R] +\f[CR]bb_getopt LONGNAME\f[R] .IP \[bu] 2 -Get positional arguments with \f[V]${BB_POSARGS[\[at]]}\f[R] array +Get positional arguments with \f[CR]${BB_POSARGS[\[at]]}\f[R] array .IP \[bu] 2 -If the last argument is a single dash (-), read remaining arguments from -stdin -.SS \f[V]bb_processargs\f[R] -.PP -Parses arguments in $\[at] and modifies it in-place to only hold +If the last argument is a single dash (\-), read remaining arguments +from stdin +.SS \f[CR]bb_processargs\f[R] +Parses arguments in $\[at] and modifies it in\-place to only hold positional arguments .PP \f[B]Notes:\f[R] .PP -To use this in a script, you must do \f[V]shopt -s expand_aliases\f[R] -.SS \f[V]bb_getopt [-v VAR] LONGNAME\f[R] -.PP +To use this in a script, you must do \f[CR]shopt \-s expand_aliases\f[R] +.SS \f[CR]bb_getopt [\-v VAR] LONGNAME\f[R] Gets the value of option or argument by name .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]LONGNAME\f[R]: long name of the option (or named argument) +\f[CR]LONGNAME\f[R]: long name of the option (or named argument) .PP \f[B]Returns:\f[R] true if the result is nonempty -.SS \f[V]bb_checkopt LONGNAME\f[R] -.PP +.SS \f[CR]bb_checkopt LONGNAME\f[R] Returns the value of flag named LONGNAME .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LONGNAME\f[R]: long name of the flag +\f[CR]LONGNAME\f[R]: long name of the flag .PP \f[B]Returns:\f[R] the flag value, either true or false .PP \f[B]Notes:\f[R] .PP Undefined if used on an opt instead of a flag -.SS \f[V]bb_argclear\f[R] -.PP +.SS \f[CR]bb_argclear\f[R] Clears all registered argument parsing settings .PP \f[B]Notes:\f[R] @@ -210,76 +177,69 @@ Clears all registered argument parsing settings Only one \[lq]command\[rq] can be registered for parsing at once so this can be used to clear the state of a previous command and start a new one .SH Package cli/color -.PP Routines for printing text in color using ANSI escape codes -.SS \f[V]bb_colorize COLORSTR TEXT\f[R] -.PP +.SS \f[CR]bb_colorize COLORSTR TEXT\f[R] Prints the given text in color if outputting to a terminal .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]COLORSTR\f[R]: FGCOLOR[\f[I]on\f[R][BGCOLOR]] (e.g.\ red, +\f[CR]COLORSTR\f[R]: FGCOLOR[\f[I]on\f[R][BGCOLOR]] (e.g.\ red, bright_red, white_on_blue) .IP \[bu] 2 -\f[V]TEXT\f[R]: text to be printed in color +\f[CR]TEXT\f[R]: text to be printed in color .PP \f[B]Returns:\f[R] 0 if text was printed in color, 1 otherwise .PP \f[B]Notes:\f[R] .PP -Supported colors: - black - red - green - yellow - blue - magenta - cyan -- bright_gray (dark_white) - gray (bright_black) - bright_red - -bright_green - bright_yellow - bright_blue - bright_magenta - -bright_cyan - white (bright_white) +Supported colors: \- black \- red \- green \- yellow \- blue \- magenta +\- cyan \- bright_gray (dark_white) \- gray (bright_black) \- bright_red +\- bright_green \- bright_yellow \- bright_blue \- bright_magenta \- +bright_cyan \- white (bright_white) .PP This does not print a new line at the end of TEXT -.SS \f[V]bb_rawcolor COLORSTR TEXT\f[R] -.PP +.SS \f[CR]bb_rawcolor COLORSTR TEXT\f[R] Like colorize but always uses prints in color .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]COLORSTR\f[R]: FGCOLOR[\f[I]on\f[R][BGCOLOR]] (e.g.\ red, +\f[CR]COLORSTR\f[R]: FGCOLOR[\f[I]on\f[R][BGCOLOR]] (e.g.\ red, bright_red, white_on_blue) .IP \[bu] 2 -\f[V]TEXT\f[R]: text to be printed in color +\f[CR]TEXT\f[R]: text to be printed in color .PP \f[B]Notes:\f[R] .PP Use this instead of colorize if you need to still print in color even if not connected to a terminal, e.g.\ when saving the output to a variable. See colorize for supported colors -.SS \f[V]bb_colorstrip TEXT\f[R] -.PP +.SS \f[CR]bb_colorstrip TEXT\f[R] Strips ANSI color codes from text colorized by colorize (or rawcolor) .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]TEXT\f[R]: text possibly with color escape codes to be removed +\f[CR]TEXT\f[R]: text possibly with color escape codes to be removed .PP \f[B]Notes:\f[R] .PP This is only guaranteed to work on text generated by colorize and variants, not for any generic string with ANSI escape codes. .SH Package cli/input -.PP Routines for handling user input -.SS \f[V]bb_getinput VAR PROMPT\f[R] -.PP +.SS \f[CR]bb_getinput VAR PROMPT\f[R] Prompts for input and saves the response to VAR .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store response into (do not include $) +\f[CR]VAR\f[R]: variable to store response into (do not include $) .IP \[bu] 2 -\f[V]PROMPT\f[R]: text displayed to the user -.SS \f[V]bb_yn PROMPT\f[R] -.PP +\f[CR]PROMPT\f[R]: text displayed to the user +.SS \f[CR]bb_yn PROMPT\f[R] Prompts user to confirm an action by pressing Y .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]PROMPT\f[R]: text displayed to the user +\f[CR]PROMPT\f[R]: text displayed to the user .PP \f[B]Returns:\f[R] 0 if yes, 1 otherwise .PP @@ -287,153 +247,136 @@ Prompts user to confirm an action by pressing Y .PP If you want the user to type \[lq]yes\[rq], use getinput and check their response -.SS \f[V]bb_pause PROMPT\f[R] -.PP +.SS \f[CR]bb_pause PROMPT\f[R] Prompts user to press a key to continue .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]PROMPT\f[R]: text displayed to the user Default: Press any key to +\f[CR]PROMPT\f[R]: text displayed to the user Default: Press any key to continue .SH Package cli/msg -.PP Messaging routines -.SS \f[V]bb_info MESSAGE\f[R] -.PP +.SS \f[CR]bb_info MESSAGE\f[R] Prints an informational message to stderr .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]MESSAGE\f[R]: message to be printed -.SS \f[V]bb_warn MESSAGE\f[R] -.PP +\f[CR]MESSAGE\f[R]: message to be printed +.SS \f[CR]bb_warn MESSAGE\f[R] Prints a warning message to stderr .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]MESSAGE\f[R]: message to be printed -.SS \f[V]bb_error MESSAGE\f[R] -.PP +\f[CR]MESSAGE\f[R]: message to be printed +.SS \f[CR]bb_error MESSAGE\f[R] Prints an error message to stderr .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]MESSAGE\f[R]: message to be printed -.SS \f[V]bb_fatal MESSAGE [RETURNCODE]\f[R] -.PP +\f[CR]MESSAGE\f[R]: message to be printed +.SS \f[CR]bb_fatal MESSAGE [RETURNCODE]\f[R] Prints an error message to stderr and then exits the shell .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]MESSAGE\f[R]: message to be printed +\f[CR]MESSAGE\f[R]: message to be printed .IP \[bu] 2 -\f[V]RETURNCODE\f[R]: return code to exit with (defaults to 1) -.SS \f[V]bb_expect VAL1 VAL2 [MESSAGE] [RETURNCODE]\f[R] -.PP +\f[CR]RETURNCODE\f[R]: return code to exit with (defaults to 1) +.SS \f[CR]bb_expect VAL1 VAL2 [MESSAGE] [RETURNCODE]\f[R] Issues a fatal error if two given values are not equal .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAL1\f[R]: value to check +\f[CR]VAL1\f[R]: value to check .IP \[bu] 2 -\f[V]VAL2\f[R]: value to check against (golden answer) +\f[CR]VAL2\f[R]: value to check against (golden answer) .IP \[bu] 2 -\f[V]MESSAGE\f[R]: optional prefix to the error message +\f[CR]MESSAGE\f[R]: optional prefix to the error message .IP \[bu] 2 -\f[V]RETURNCODE\f[R]: return code to exit with (defaults to 1) -.SS \f[V]bb_expectsubstr TEXT PATTERN [MESSAGE] [RETURNCODE]\f[R] -.PP +\f[CR]RETURNCODE\f[R]: return code to exit with (defaults to 1) +.SS \f[CR]bb_expectsubstr TEXT PATTERN [MESSAGE] [RETURNCODE]\f[R] Issues a fatal error if a given substring is not found in some given text .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]TEXT\f[R]: text to check +\f[CR]TEXT\f[R]: text to check .IP \[bu] 2 -\f[V]PATTERN\f[R]: substring to be found +\f[CR]PATTERN\f[R]: substring to be found .IP \[bu] 2 -\f[V]MESSAGE\f[R]: optional prefix to the error message +\f[CR]MESSAGE\f[R]: optional prefix to the error message .IP \[bu] 2 -\f[V]RETURNCODE\f[R]: return code to exit with (defaults to 1) -.SS \f[V]bb_expectre TEXT PATTERN [MESSAGE] [RETURNCODE]\f[R] -.PP +\f[CR]RETURNCODE\f[R]: return code to exit with (defaults to 1) +.SS \f[CR]bb_expectre TEXT PATTERN [MESSAGE] [RETURNCODE]\f[R] Issues a fatal error if text does not match the given regular expression .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]TEXT\f[R]: text to check +\f[CR]TEXT\f[R]: text to check .IP \[bu] 2 -\f[V]PATTERN\f[R]: regular expression +\f[CR]PATTERN\f[R]: regular expression .IP \[bu] 2 -\f[V]MESSAGE\f[R]: optional prefix to the error message +\f[CR]MESSAGE\f[R]: optional prefix to the error message .IP \[bu] 2 -\f[V]RETURNCODE\f[R]: return code to exit with (defaults to 1) -.SS \f[V]bb_loglevel [LEVEL]\f[R] -.PP +\f[CR]RETURNCODE\f[R]: return code to exit with (defaults to 1) +.SS \f[CR]bb_loglevel [LEVEL]\f[R] Sets the current log level .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LEVEL\f[R]: integer representing the current log verbosity level +\f[CR]LEVEL\f[R]: integer representing the current log verbosity level (default: 0) -.SS \f[V]bb_setloglevelname LEVEL NAME\f[R] -.PP +.SS \f[CR]bb_setloglevelname LEVEL NAME\f[R] Assigns a name to the given log level .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LEVEL\f[R]: integer representing the current log verbosity level +\f[CR]LEVEL\f[R]: integer representing the current log verbosity level .IP \[bu] 2 -\f[V]NAME\f[R]: name to be assigned -.SS \f[V]bb_log LEVEL MESSAGE\f[R] -.PP +\f[CR]NAME\f[R]: name to be assigned +.SS \f[CR]bb_log LEVEL MESSAGE\f[R] Issues a message at a certain log level .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LEVEL\f[R]: minimum logging level required to print the message +\f[CR]LEVEL\f[R]: minimum logging level required to print the message .IP \[bu] 2 -\f[V]MESSAGE\f[R]: message to be printed +\f[CR]MESSAGE\f[R]: message to be printed .PP \f[B]Notes:\f[R] .PP Set BB_LOG_TIMEFMT to a valid time format string to override the default .SH Package cli/progress -.PP -Text-based progress bar and checkpoint pass/fail status line generator +Text\-based progress bar and checkpoint pass/fail status line generator .PP \f[B]Example:\f[R] .IP -.nf -\f[C] -ping -c 1 8.8.8.8 &>/dev/null; bb_checkpoint \[dq]Pinging DNS\[dq] -for pct in {0..100}; do sleep 0.1s; bb_progressbar $pct \[dq]Downloading\[dq]; done; echo -\f[R] -.fi -.SS \f[V]bb_progressbar VALUE TEXT\f[R] -.PP +.EX +ping \-c 1 8.8.8.8 &>/dev/null\f[B];\f[R] bb_checkpoint \[dq]Pinging DNS\[dq] +\f[B]for\f[R] pct \f[B]in\f[R] {0..100}\f[B];\f[R] \f[B]do\f[R] sleep 0.1s\f[B];\f[R] bb_progressbar $pct \[dq]Downloading\[dq]\f[B];\f[R] \f[B]done\f[R]\f[B];\f[R] echo +.EE +.SS \f[CR]bb_progressbar VALUE TEXT\f[R] Prints/updates a progress bar .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VALUE\f[R]: integer from 0 to 100; 100 meaning complete +\f[CR]VALUE\f[R]: integer from 0 to 100; 100 meaning complete .IP \[bu] 2 -\f[V]TEXT\f[R]: optional text to be displayed +\f[CR]TEXT\f[R]: optional text to be displayed .PP \f[B]Notes:\f[R] .PP Customize the start, end, and fill characters by setting environment variables BB_PROGRESS_START, BB_PROGRESS_END, and BB_PROGRESS_FILL. By default these are set to [, ], and . -.SS \f[V]bb_checkpoint TEXT [RESULT]\f[R] -.PP +.SS \f[CR]bb_checkpoint TEXT [RESULT]\f[R] Prints a status line with pass/fail result based on RESULT .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]TEXT\f[R]: text to be displayed +\f[CR]TEXT\f[R]: text to be displayed .IP \[bu] 2 -\f[V]RESULT\f[R]: 0 for pass, nonzero for fail; if not given, infers +\f[CR]RESULT\f[R]: 0 for pass, nonzero for fail; if not given, infers from $? .PP \f[B]Notes:\f[R] @@ -443,89 +386,78 @@ variables BB_CHECKPOINT_FILL, BB_CHECKPOINT_PASS, and BB_CHECKPOINT_FAIL. By default these are set to space, OK, and FAIL. .SH Package core -.PP Core routines -.SS \f[V]bb_load PKG ...\f[R] -.PP +.SS \f[CR]bb_load PKG ...\f[R] Loads a module or package .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]PKG\f[R]: either a package (e.g.\ cli/arg) or a whole module +\f[CR]PKG\f[R]: either a package (e.g.\ cli/arg) or a whole module (e.g.\ cli) .PP \f[B]Notes:\f[R] .PP Each package only loads once; if you happen to load one twice, the second time has no effect -.SS \f[V]bb_isloaded PKG\f[R] -.PP +.SS \f[CR]bb_isloaded PKG\f[R] Checks if a package is loaded already .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]PKG\f[R]: package name in internal format, e.g.\ bb_cli_arg +\f[CR]PKG\f[R]: package name in internal format, e.g.\ bb_cli_arg .PP \f[B]Returns:\f[R] 0 if loaded, 1 otherwise -.SS \f[V]bb_debug TEXT\f[R] -.PP +.SS \f[CR]bb_debug TEXT\f[R] Log text when debugging is enabled .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]TEXT\f[R]: message to be logged in debug mode +\f[CR]TEXT\f[R]: message to be logged in debug mode .PP \f[B]Notes:\f[R] .PP Set environment variable BB_DEBUG to enable debug mode -.SS \f[V]bb_issourced\f[R] -.PP +.SS \f[CR]bb_issourced\f[R] Check if the script is being sourced .PP \f[B]Returns:\f[R] 0 if sourced, 1 otherwise -.SS \f[V]bb_stacktrace\f[R] -.PP +.SS \f[CR]bb_stacktrace\f[R] Print a stack trace to stderr -.SS \f[V]bb_cleanup\f[R] -.PP -Clears all functions and variables defined by bash-boost +.SS \f[CR]bb_cleanup\f[R] +Clears all functions and variables defined by bash\-boost .SH Package interactive/bookmark -.PP Directory bookmarking system -.SS \f[V]bb_addbookmark [KEY] [DIR]\f[R] -.PP +.SS \f[CR]bb_addbookmark [KEY] [DIR]\f[R] Adds a bookmark to the directory for quick recall .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]KEY\f[R]: single character to assign bookmark to +\f[CR]KEY\f[R]: single character to assign bookmark to .IP \[bu] 2 -\f[V]DIR\f[R]: directory to bookmark; defaults to current directory +\f[CR]DIR\f[R]: directory to bookmark; defaults to current directory .PP \f[B]Notes:\f[R] .PP If DIR is already bookmarked, this will clear the previously associated key If KEY is already used, this will overwrite the orevious assignment -.SS \f[V]bb_delbookmark [KEY]\f[R] -.PP +.SS \f[CR]bb_delbookmark [KEY]\f[R] \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]KEY\f[R]: bookmark key to delete; prompts if unspecified +\f[CR]KEY\f[R]: bookmark key to delete; prompts if unspecified .PP \f[B]Notes:\f[R] .PP -Useful as a keyboard shortcut, e.g., Ctrl+X-B -.SS \f[V]bb_bookmark [KEY] [DIR]\f[R] -.PP +Useful as a keyboard shortcut, e.g., Ctrl+X\-B +.SS \f[CR]bb_bookmark [KEY] [DIR]\f[R] Go to the directory bookmarked by KEY if it exists, otherwise create bookmark .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]KEY\f[R]: single character to assign bookmark to; prompts if +\f[CR]KEY\f[R]: single character to assign bookmark to; prompts if unspecified .IP \[bu] 2 -\f[V]DIR\f[R]: directory to bookmark; defaults to current directory +\f[CR]DIR\f[R]: directory to bookmark; defaults to current directory .PP \f[B]Notes:\f[R] .PP @@ -534,52 +466,46 @@ key. If KEY is already used but you wish to overwrite it, use bb_addbookmark or use bb_delbookmark KEY first Useful as a keyboard shortcut, e.g., Ctrl+B -.SS \f[V]bb_showbookmark [KEY]\f[R] -.PP +.SS \f[CR]bb_showbookmark [KEY]\f[R] Shows the current mapping of KEY, or all keys if KEY is unspecified .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]KEY\f[R]: bookmark key to show -.SS \f[V]bb_getbookmark [DIR]\f[R] -.PP +\f[CR]KEY\f[R]: bookmark key to show +.SS \f[CR]bb_getbookmark [DIR]\f[R] Prints bookmark key assigned to the given DIR if such a bookmark exists .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]DIR\f[R]: directory to get assigned bookmark key of; defaults to +\f[CR]DIR\f[R]: directory to get assigned bookmark key of; defaults to current directory -.SS \f[V]bb_loadbookmark FILE\f[R] -.PP +.SS \f[CR]bb_loadbookmark FILE\f[R] Loads bookmark assignments from FILE .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]FILE\f[R]: a file containing bookmark assignments +\f[CR]FILE\f[R]: a file containing bookmark assignments .PP \f[B]Notes:\f[R] .PP FILE should be formatted with an assignment on each line, with each assignment being a letter followed by a path, separated by space .SH Package interactive/cmd -.PP Miscellaneous interactive commands -.SS \f[V]bb_mcd DIR\f[R] -.PP +.SS \f[CR]bb_mcd DIR\f[R] Make director(ies) and change directory to the last one .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]DIR\f[R]: usually a single directory to be made, but all arguments +\f[CR]DIR\f[R]: usually a single directory to be made, but all arguments are passed to mkdir and the last argument is then passed to cd if mkdir is successful -.SS \f[V]bb_up [DIR]\f[R] -.PP +.SS \f[CR]bb_up [DIR]\f[R] Change directory up .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]DIR\f[R]: go to this directory, otherwise defaults to .. +\f[CR]DIR\f[R]: go to this directory, otherwise defaults to .. if no DIR specified .PP \f[B]Notes:\f[R] @@ -589,14 +515,13 @@ After pressing TAB, the current working directory is populated, and with each further TAB, a directory is removed, moving you up the directory stack. Once you see the upward directory you want to go to, hit ENTER -.SS \f[V]bb_forkterm [ARGS ...]\f[R] -.PP +.SS \f[CR]bb_forkterm [ARGS ...]\f[R] Spawn a new terminal instance inheriting from this shell\[cq]s environment .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]ARGS\f[R]: arguments to be appended to the terminal launch command +\f[CR]ARGS\f[R]: arguments to be appended to the terminal launch command .PP \f[B]Notes:\f[R] .IP \[bu] 2 @@ -612,911 +537,848 @@ tokenized by space. If your arguments contain spaces, you will need to declare the variable as a list. .SH Package interactive/prompt -.PP Routines for managing a dynamic shell prompt -.SS \f[V]bb_loadprompt\f[R] -.PP +.SS \f[CR]bb_loadprompt\f[R] Activates the registered dynamic prompt -.SS \f[V]bb_unloadprompt\f[R] -.PP +.SS \f[CR]bb_unloadprompt\f[R] Deactivates the registered dynamic prompt .PP \f[B]Notes:\f[R] .PP This will restore the prompt to the state it was in when loadprompt was called -.SS \f[V]bb_setpromptleft FUNCTION ...\f[R] -.PP +.SS \f[CR]bb_setpromptleft FUNCTION ...\f[R] Sets the left prompt to the output of the list of given functions .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]FUNCTION\f[R]: a function whose stdout output will be added to the +\f[CR]FUNCTION\f[R]: a function whose stdout output will be added to the prompt .PP \f[B]Notes:\f[R] .PP The prompt areas are as follows: .IP -.nf -\f[C] - +----------------------------------------+ +.EX + +\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ | left prompt right prompt | | nextline prompt | - +----------------------------------------+ -\f[R] -.fi -.SS \f[V]bb_setpromptright FUNCTION ...\f[R] -.PP + +\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ +.EE +.SS \f[CR]bb_setpromptright FUNCTION ...\f[R] Sets the right prompt to the output of the list of given functions .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]FUNCTION\f[R]: a function whose stdout output will be added to the +\f[CR]FUNCTION\f[R]: a function whose stdout output will be added to the prompt -.SS \f[V]bb_setpromptnextline FUNCTION ...\f[R] -.PP +.SS \f[CR]bb_setpromptnextline FUNCTION ...\f[R] Sets the next line prompt to the output of the list of given functions .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]FUNCTION\f[R]: a function whose stdout output will be added to the +\f[CR]FUNCTION\f[R]: a function whose stdout output will be added to the prompt -.SS \f[V]bb_setwintitle FUNCTION\f[R] -.PP +.SS \f[CR]bb_setwintitle FUNCTION\f[R] Sets the window title to the output of the list of given functions .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]FUNCTION\f[R]: a function whose stdout output will used as the +\f[CR]FUNCTION\f[R]: a function whose stdout output will used as the window title -.SS \f[V]bb_settabtitle FUNCTION\f[R] -.PP +.SS \f[CR]bb_settabtitle FUNCTION\f[R] Sets the tab title to the output of the list of given functions .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]FUNCTION\f[R]: a function whose stdout output will used as the tab +\f[CR]FUNCTION\f[R]: a function whose stdout output will used as the tab title .PP \f[B]Notes:\f[R] .PP Not all terminals support this -.SS \f[V]bb_promptcolor COLORSTR TEXT\f[R] -.PP +.SS \f[CR]bb_promptcolor COLORSTR TEXT\f[R] Prints text in color, for use specifically in prompts .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]COLORSTR\f[R]: valid color string, see bb_colorize +\f[CR]COLORSTR\f[R]: valid color string, see bb_colorize .IP \[bu] 2 -\f[V]TEXT\f[R]: text to be printed in color +\f[CR]TEXT\f[R]: text to be printed in color .PP \f[B]Notes:\f[R] .PP -This is like colorize but adds [ and ] around non-printing characters +This is like colorize but adds [ and ] around non\-printing characters which are needed specifically in prompts .SH Package util/env -.PP Routines for checking and setting environment variables -.SS \f[V]bb_checkset VAR\f[R] -.PP +.SS \f[CR]bb_checkset VAR\f[R] Check if an environment variable is set or empty .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: name of the variable to check (don\[cq]t include $) +\f[CR]VAR\f[R]: name of the variable to check (don\[cq]t include $) .PP \f[B]Returns:\f[R] 1 if unset, 2 if set but empty, 0 otherwise -.SS \f[V]bb_iscmd COMMAND\f[R] -.PP +.SS \f[CR]bb_iscmd COMMAND\f[R] Check if COMMAND is a valid command .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]COMMAND\f[R]: name of command to check (e.g., ls) +\f[CR]COMMAND\f[R]: name of command to check (e.g., ls) .PP \f[B]Notes:\f[R] .PP This could be an executable in your PATH, or a function or bash builtin -.SS \f[V]bb_inpath VAR ITEM ...\f[R] -.PP -Checks if items are in the colon-separated path variable VAR +.SS \f[CR]bb_inpath VAR ITEM ...\f[R] +Checks if items are in the colon\-separated path variable VAR .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: path variable, e.g.\ PATH (do not use $) +\f[CR]VAR\f[R]: path variable, e.g.\ PATH (do not use $) .IP \[bu] 2 -\f[V]ITEM\f[R]: items to find in the path variable +\f[CR]ITEM\f[R]: items to find in the path variable .PP \f[B]Returns:\f[R] 0 if all items are in the path, 1 otherwise -.SS \f[V]bb_prependpath VAR ITEM ...\f[R] -.PP -Prepends items to the colon-separated path variable VAR +.SS \f[CR]bb_prependpath VAR ITEM ...\f[R] +Prepends items to the colon\-separated path variable VAR .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: path variable, e.g.\ PATH (do not use $) +\f[CR]VAR\f[R]: path variable, e.g.\ PATH (do not use $) .IP \[bu] 2 -\f[V]ITEM\f[R]: items to add to the path variable -.SS \f[V]bb_appendpath VAR ITEM ...\f[R] -.PP -Appends items to the colon-separated path variable VAR +\f[CR]ITEM\f[R]: items to add to the path variable +.SS \f[CR]bb_appendpath VAR ITEM ...\f[R] +Appends items to the colon\-separated path variable VAR .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: path variable, e.g.\ PATH (do not use $) +\f[CR]VAR\f[R]: path variable, e.g.\ PATH (do not use $) .IP \[bu] 2 -\f[V]ITEM\f[R]: items to add to the path variable -.SS \f[V]bb_prependpathuniq VAR ITEM ...\f[R] -.PP -Prepends unique items to the colon-separated path variable VAR +\f[CR]ITEM\f[R]: items to add to the path variable +.SS \f[CR]bb_prependpathuniq VAR ITEM ...\f[R] +Prepends unique items to the colon\-separated path variable VAR .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: path variable, e.g.\ PATH (do not use $) +\f[CR]VAR\f[R]: path variable, e.g.\ PATH (do not use $) .IP \[bu] 2 -\f[V]ITEM\f[R]: items to add to the path variable +\f[CR]ITEM\f[R]: items to add to the path variable .PP \f[B]Notes:\f[R] .PP If an item is already in the path, it is not added twice -.SS \f[V]bb_appendpathuniq VAR ITEM ...\f[R] -.PP -Appends unique items to the colon-separated path variable VAR +.SS \f[CR]bb_appendpathuniq VAR ITEM ...\f[R] +Appends unique items to the colon\-separated path variable VAR .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: path variable, e.g.\ PATH (do not use $) +\f[CR]VAR\f[R]: path variable, e.g.\ PATH (do not use $) .IP \[bu] 2 -\f[V]ITEM\f[R]: items to add to the path variable +\f[CR]ITEM\f[R]: items to add to the path variable .PP \f[B]Notes:\f[R] .PP If an item is already in the path, it is not added twice -.SS \f[V]bb_removefrompath VAR ITEM ...\f[R] -.PP -Removes items from the colon-separated path variable VAR +.SS \f[CR]bb_removefrompath VAR ITEM ...\f[R] +Removes items from the colon\-separated path variable VAR .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: path variable, e.g.\ PATH (do not use $) +\f[CR]VAR\f[R]: path variable, e.g.\ PATH (do not use $) .IP \[bu] 2 -\f[V]ITEM\f[R]: items to remove from the path variable +\f[CR]ITEM\f[R]: items to remove from the path variable .PP \f[B]Returns:\f[R] 0 if any item was removed, 1 otherwise -.SS \f[V]bb_swapinpath VAR ITEM1 ITEM2\f[R] -.PP -Swaps two items in a colon-separated path variable VAR +.SS \f[CR]bb_swapinpath VAR ITEM1 ITEM2\f[R] +Swaps two items in a colon\-separated path variable VAR .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: path variable, e.g.\ PATH (do not use $) +\f[CR]VAR\f[R]: path variable, e.g.\ PATH (do not use $) .IP \[bu] 2 -\f[V]ITEM1\f[R]: first item to swap +\f[CR]ITEM1\f[R]: first item to swap .IP \[bu] 2 -\f[V]ITEM2\f[R]: second item to swap +\f[CR]ITEM2\f[R]: second item to swap .PP \f[B]Returns:\f[R] 0 if swap is successful, 1 if either ITEM1 or ITEM2 was not in the path 2 if insufficient arguments were supplied (less than 3) 3 for internal error -.SS \f[V]bb_printpath VAR [SEP]\f[R] -.PP +.SS \f[CR]bb_printpath VAR [SEP]\f[R] Prints a path variable separated by SEP, one item per line .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: path variable, e.g.\ PATH (do not use $) +\f[CR]VAR\f[R]: path variable, e.g.\ PATH (do not use $) .IP \[bu] 2 -\f[V]SEP\f[R]: separator character, defaults to : +\f[CR]SEP\f[R]: separator character, defaults to : .SH Package util/file -.PP Routines for common file operations -.SS \f[V]bb_canonicalize [-v VAR] PATH\f[R] -.PP +.SS \f[CR]bb_canonicalize [\-v VAR] PATH\f[R] Resolves . and .. in a given absolute path .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]PATH\f[R]: an absolute path +\f[CR]PATH\f[R]: an absolute path .PP \f[B]Returns:\f[R] 1 if PATH is invalid, 0 otherwise -.SS \f[V]bb_abspath [-v VAR] TARGET [FROM]\f[R] -.PP +.SS \f[CR]bb_abspath [\-v VAR] TARGET [FROM]\f[R] Returns the absolute path from a relative one .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]TARGET\f[R]: target relative path (can be file or directory) +\f[CR]TARGET\f[R]: target relative path (can be file or directory) .IP \[bu] 2 -\f[V]FROM\f[R]: the absolute directory path from which the absolute path -is formed (Defaults to $PWD) -.SS \f[V]bb_relpath [-v VAR] TARGET [FROM]\f[R] -.PP +\f[CR]FROM\f[R]: the absolute directory path from which the absolute +path is formed (Defaults to $PWD) +.SS \f[CR]bb_relpath [\-v VAR] TARGET [FROM]\f[R] Returns the relative path from a directory to the target .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]TARGET\f[R]: target absolute path (can be file or directory) +\f[CR]TARGET\f[R]: target absolute path (can be file or directory) .IP \[bu] 2 -\f[V]FROM\f[R]: the absolute directory path from which the relative path -is formed (Defaults to $PWD) +\f[CR]FROM\f[R]: the absolute directory path from which the relative +path is formed (Defaults to $PWD) .PP \f[B]Returns:\f[R] 1 if either TARGET or FROM is invalid, 0 otherwise -.SS \f[V]bb_prettypath PATH\f[R] -.PP +.SS \f[CR]bb_prettypath PATH\f[R] Prints a pretty version of the path .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]PATH\f[R]: a path +\f[CR]PATH\f[R]: a path .PP \f[B]Notes:\f[R] .PP Replaces home directory with \[ti] -.SS \f[V]bb_countlines FILENAME ...\f[R] -.PP +.SS \f[CR]bb_countlines FILENAME ...\f[R] Counts the number of lines in a list of files .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]FILENAME\f[R]: a valid filename +\f[CR]FILENAME\f[R]: a valid filename .PP \f[B]Returns:\f[R] 1 if any of the filenames are invalid, 0 otherwise -.SS \f[V]bb_countmatches PATTERN FILENAME ...\f[R] -.PP +.SS \f[CR]bb_countmatches PATTERN FILENAME ...\f[R] Counts the number of matching lines in a list of files .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]PATTERN\f[R]: a valid bash regular expression +\f[CR]PATTERN\f[R]: a valid bash regular expression .IP \[bu] 2 -\f[V]FILENAME\f[R]: a valid filename +\f[CR]FILENAME\f[R]: a valid filename .PP \f[B]Returns:\f[R] 1 if any of the filenames are invalid, 0 otherwise -.SS \f[V]bb_extpush EXT FILENAME ...\f[R] -.PP +.SS \f[CR]bb_extpush EXT FILENAME ...\f[R] Adds the file extension EXT to all given files .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]EXT\f[R]: the file extension +\f[CR]EXT\f[R]: the file extension .IP \[bu] 2 -\f[V]FILENAME\f[R]: a valid filename -.SS \f[V]bb_extpop FILENAME ...\f[R] -.PP +\f[CR]FILENAME\f[R]: a valid filename +.SS \f[CR]bb_extpop FILENAME ...\f[R] Removes the last file extension from the given files .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]FILENAME\f[R]: a valid filename -.SS \f[V]bb_hardcopy FILENAME ...\f[R] -.PP +\f[CR]FILENAME\f[R]: a valid filename +.SS \f[CR]bb_hardcopy FILENAME ...\f[R] Replaces symbolic links with deep copies .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]FILENAME\f[R]: a valid symbolic link -.SS \f[V]bb_scriptpath [-v VAR]\f[R] -.PP +\f[CR]FILENAME\f[R]: a valid symbolic link +.SS \f[CR]bb_scriptpath [\-v VAR]\f[R] Returns the unresolved directory name of the current script .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .SH Package util/kwargs -.PP Routines for parsing keyword arg strings .PP \f[B]Example:\f[R] .IP -.nf -\f[C] -talk() { +.EX +talk() \f[B]{\f[R] bb_kwparse opts \[dq]$\[at]\[dq] - set -- \[dq]${BB_OTHERARGS[\[at]]}\[dq] # $\[at] now only contains non-kwargs - local verb=\[dq]${opts[verb]:-have}\[dq] + set \-\- \[dq]${BB_OTHERARGS[\[at]]}\[dq] \f[I]# $\[at] now only contains non\-kwargs\f[R] + local verb=\[dq]${opts[verb]:\-have}\[dq] local item - for item in \[dq]$\[at]\[dq]; do + \f[B]for\f[R] item \f[B]in\f[R] \[dq]$\[at]\[dq]\f[B];\f[R] \f[B]do\f[R] echo \[dq]You $verb $item\[dq] - done -} + \f[B]done\f[R] +\f[B]}\f[R] talk eggs milk bread talk verb=ate eggs milk bread -\f[R] -.fi -.SS \f[V]bb_kwparse MAP KEY=VAL ... ARGS ...\f[R] -.PP +.EE +.SS \f[CR]bb_kwparse MAP KEY=VAL ... ARGS ...\f[R] Parses a list of KEY=VAL pairs and stores them into a dictionary .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]MAP\f[R]: name of an associative array to be created +\f[CR]MAP\f[R]: name of an associative array to be created .IP \[bu] 2 -\f[V]KEY=VAL\f[R]: a key-value pair separated by = +\f[CR]KEY=VAL\f[R]: a key\-value pair separated by = .IP \[bu] 2 -\f[V]ARGS\f[R]: other arguments not in KEY=VAL format are ignored +\f[CR]ARGS\f[R]: other arguments not in KEY=VAL format are ignored .PP \f[B]Notes:\f[R] .PP -Get non-keyword arguments with ${BB_OTHERARGS[\[at]]} +Get non\-keyword arguments with ${BB_OTHERARGS[\[at]]} .SH Package util/list -.PP Routines for common list operations -.SS \f[V]bb_join [-v VAR] SEP ITEM ...\f[R] -.PP +.SS \f[CR]bb_join [\-v VAR] SEP ITEM ...\f[R] Joins the list of items into a string with the given separator .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]SEP\f[R]: separator +\f[CR]SEP\f[R]: separator .IP \[bu] 2 -\f[V]ITEM\f[R]: a list item -.SS \f[V]bb_split [-V LISTVAR] SEP STR\f[R] -.PP +\f[CR]ITEM\f[R]: a list item +.SS \f[CR]bb_split [\-V LISTVAR] SEP STR\f[R] Splits a string into a list based on a separator .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: list variable to store result (if not given, prints +\f[CR]LISTVAR\f[R]: list variable to store result (if not given, prints to stdout) .IP \[bu] 2 -\f[V]SEP\f[R]: separator +\f[CR]SEP\f[R]: separator .IP \[bu] 2 -\f[V]STR\f[R]: string to split -.SS \f[V]bb_inlist TARGET LIST ...\f[R] -.PP +\f[CR]STR\f[R]: string to split +.SS \f[CR]bb_inlist TARGET LIST ...\f[R] Checks if a target item exists in a given list .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]TARGET\f[R]: the search target +\f[CR]TARGET\f[R]: the search target .IP \[bu] 2 -\f[V]LIST\f[R]: a list item +\f[CR]LIST\f[R]: a list item .PP \f[B]Returns:\f[R] 0 if found, 1 otherwise -.SS \f[V]bb_push LISTVAR ITEM ...\f[R] -.PP +.SS \f[CR]bb_push LISTVAR ITEM ...\f[R] Pushes an item to a list (stack) .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: name of the list variable (do not include $) +\f[CR]LISTVAR\f[R]: name of the list variable (do not include $) .IP \[bu] 2 -\f[V]ITEM\f[R]: item to push -.SS \f[V]bb_pop LISTVAR\f[R] -.PP +\f[CR]ITEM\f[R]: item to push +.SS \f[CR]bb_pop LISTVAR\f[R] Pops an item from a list (stack) .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: name of the list variable (do not include $) -.SS \f[V]bb_unshift LISTVAR ITEM ...\f[R] -.PP +\f[CR]LISTVAR\f[R]: name of the list variable (do not include $) +.SS \f[CR]bb_unshift LISTVAR ITEM ...\f[R] Unshifts an item from a list (stack) .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: name of the list variable (do not include $) +\f[CR]LISTVAR\f[R]: name of the list variable (do not include $) .IP \[bu] 2 -\f[V]ITEM\f[R]: item to unshift -.SS \f[V]bb_shift LISTVAR\f[R] -.PP +\f[CR]ITEM\f[R]: item to unshift +.SS \f[CR]bb_shift LISTVAR\f[R] Shifts an item from a list (stack) .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: name of the list variable (do not include $) -.SS \f[V]bb_sort [-V LISTVAR] ITEM ...\f[R] -.PP +\f[CR]LISTVAR\f[R]: name of the list variable (do not include $) +.SS \f[CR]bb_sort [\-V LISTVAR] ITEM ...\f[R] Sorts the items of a list in lexicographic ascending order .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: list variable to store result (if not given, prints +\f[CR]LISTVAR\f[R]: list variable to store result (if not given, prints to stdout) .IP \[bu] 2 -\f[V]ITEM\f[R]: a list item -.SS \f[V]bb_sortdesc [-V LISTVAR] ITEM ...\f[R] -.PP +\f[CR]ITEM\f[R]: a list item +.SS \f[CR]bb_sortdesc [\-V LISTVAR] ITEM ...\f[R] Sorts the items of a list in lexicographic descending order .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: list variable to store result (if not given, prints +\f[CR]LISTVAR\f[R]: list variable to store result (if not given, prints to stdout) .IP \[bu] 2 -\f[V]ITEM\f[R]: a list item -.SS \f[V]bb_sortnums [-V LISTVAR] ITEM ...\f[R] -.PP +\f[CR]ITEM\f[R]: a list item +.SS \f[CR]bb_sortnums [\-V LISTVAR] ITEM ...\f[R] Sorts the items of a list in numerical ascending order .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: list variable to store result (if not given, prints +\f[CR]LISTVAR\f[R]: list variable to store result (if not given, prints to stdout) .IP \[bu] 2 -\f[V]ITEM\f[R]: a list item -.SS \f[V]bb_sortnumsdesc [-V LISTVAR] ITEM ...\f[R] -.PP +\f[CR]ITEM\f[R]: a list item +.SS \f[CR]bb_sortnumsdesc [\-V LISTVAR] ITEM ...\f[R] Sorts the items of a list in numerical descending order .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: list variable to store result (if not given, prints +\f[CR]LISTVAR\f[R]: list variable to store result (if not given, prints to stdout) .IP \[bu] 2 -\f[V]ITEM\f[R]: a list item -.SS \f[V]bb_sorthuman [-V LISTVAR] ITEM ...\f[R] -.PP -Sorts the items of a list in human-readable ascending order +\f[CR]ITEM\f[R]: a list item +.SS \f[CR]bb_sorthuman [\-V LISTVAR] ITEM ...\f[R] +Sorts the items of a list in human\-readable ascending order .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: list variable to store result (if not given, prints +\f[CR]LISTVAR\f[R]: list variable to store result (if not given, prints to stdout) .IP \[bu] 2 -\f[V]ITEM\f[R]: a list item +\f[CR]ITEM\f[R]: a list item .PP \f[B]Notes:\f[R] .PP Human readable, e.g., 1K, 2M, 3G -.SS \f[V]bb_sorthumandesc [-V LISTVAR] ITEM ...\f[R] -.PP -Sorts the items of a list in human-readable descending order +.SS \f[CR]bb_sorthumandesc [\-V LISTVAR] ITEM ...\f[R] +Sorts the items of a list in human\-readable descending order .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: list variable to store result (if not given, prints +\f[CR]LISTVAR\f[R]: list variable to store result (if not given, prints to stdout) .IP \[bu] 2 -\f[V]ITEM\f[R]: a list item +\f[CR]ITEM\f[R]: a list item .PP \f[B]Notes:\f[R] .PP Human readable, e.g., 1K, 2M, 3G -.SS \f[V]bb_uniq [-V LISTVAR] ITEM ...\f[R] -.PP +.SS \f[CR]bb_uniq [\-V LISTVAR] ITEM ...\f[R] Filters an unsorted list to include only unique items .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: list variable to store result (if not given, prints +\f[CR]LISTVAR\f[R]: list variable to store result (if not given, prints to stdout) .IP \[bu] 2 -\f[V]ITEM\f[R]: a list item -.SS \f[V]bb_uniqsorted [-V LISTVAR] ITEM ...\f[R] -.PP +\f[CR]ITEM\f[R]: a list item +.SS \f[CR]bb_uniqsorted [\-V LISTVAR] ITEM ...\f[R] Filters an sorted list to include only unique items .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: list variable to store result (if not given, prints +\f[CR]LISTVAR\f[R]: list variable to store result (if not given, prints to stdout) .IP \[bu] 2 -\f[V]ITEM\f[R]: a list item +\f[CR]ITEM\f[R]: a list item .PP \f[B]Notes:\f[R] .PP -Faster than uniq, but requires the list to be pre-sorted -.SS \f[V]bb_islist LISTVAR\f[R] -.PP +Faster than uniq, but requires the list to be pre\-sorted +.SS \f[CR]bb_islist LISTVAR\f[R] Checks if the variable with the given name is a list with >1 element .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: name of a variable +\f[CR]LISTVAR\f[R]: name of a variable .PP \f[B]Notes:\f[R] .PP This will return false if the variable is declared as a list but only has 1 element. In that case, you can treat the variable as a scalar anyway. -.SS \f[V]bb_rename ITEM ... -- NAME ...\f[R] -.PP +.SS \f[CR]bb_rename ITEM ... \-\- NAME ...\f[R] Assigns new variable names to items .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]ITEM\f[R]: a list item +\f[CR]ITEM\f[R]: a list item .IP \[bu] 2 -\f[V]NAME\f[R]: a variable name +\f[CR]NAME\f[R]: a variable name .PP \f[B]Example:\f[R] .IP -.nf -\f[C] -func() { - bb_rename \[dq]$\[at]\[dq] -- first second +.EX +func() \f[B]{\f[R] + bb_rename \[dq]$\[at]\[dq] \-\- first second echo \[dq]The first argument is $first\[dq] echo \[dq]The second argument is $second\[dq] -} -\f[R] -.fi -.SS \f[V]bb_unpack LISTVAR NAME ...\f[R] -.PP +\f[B]}\f[R] +.EE +.SS \f[CR]bb_unpack LISTVAR NAME ...\f[R] Unpacks list items into named variables .PP +\f[B]Requires:\f[R] bash 4.3 or later +.PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: name of the list variable (do not include $) +\f[CR]LISTVAR\f[R]: name of the list variable (do not include $) .IP \[bu] 2 -\f[V]NAME\f[R]: a variable name to hold a list element -.SS \f[V]bb_map LISTVAR FUNCTION\f[R] -.PP +\f[CR]NAME\f[R]: a variable name to hold a list element +.SS \f[CR]bb_map LISTVAR FUNCTION\f[R] Maps a function over a list, modifying it in place .PP +\f[B]Requires:\f[R] bash 4.3 or later +.PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: name of the list variable (do not include $) +\f[CR]LISTVAR\f[R]: name of the list variable (do not include $) .IP \[bu] 2 -\f[V]FUNCTION\f[R]: a function or command to map a list element to a new -value -.SS \f[V]bb_mapkeys LISTVAR FUNCTION KEYS ...\f[R] -.PP +\f[CR]FUNCTION\f[R]: a function or command to map a list element to a +new value +.SS \f[CR]bb_mapkeys LISTVAR FUNCTION KEYS ...\f[R] Maps a function over a list of keys to generate an associative array .PP +\f[B]Requires:\f[R] bash 4.3 or later +.PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: name of an associative array variable (do not include -$) +\f[CR]LISTVAR\f[R]: name of an associative array variable (do not +include $) .IP \[bu] 2 -\f[V]FUNCTION\f[R]: a function or command to map keys to values +\f[CR]FUNCTION\f[R]: a function or command to map keys to values .IP \[bu] 2 -\f[V]KEYS\f[R]: keys which will be added to the associative array with +\f[CR]KEYS\f[R]: keys which will be added to the associative array with mapped values -.SS \f[V]bb_reverselist [-V LISTVAR] ITEM ...\f[R] -.PP +.SS \f[CR]bb_reverselist [\-V LISTVAR] ITEM ...\f[R] Returns a reversed version of the given list .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: name of the returned reversed list variable (do not +\f[CR]LISTVAR\f[R]: name of the returned reversed list variable (do not include $) .IP \[bu] 2 -\f[V]ITEM\f[R]: list items to reverse +\f[CR]ITEM\f[R]: list items to reverse .SH Package util/math -.PP Routines for common math operations -.SS \f[V]bb_sum [-v VAR] NUM ...\f[R] -.PP +.SS \f[CR]bb_sum [\-v VAR] NUM ...\f[R] Returns the sum of the given numbers .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]NUM\f[R]: a valid number -.SS \f[V]bb_min [-v VAR] NUM ...\f[R] -.PP +\f[CR]NUM\f[R]: a valid number +.SS \f[CR]bb_min [\-v VAR] NUM ...\f[R] Returns the minimum of the given numbers .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]NUM\f[R]: a valid number -.SS \f[V]bb_max [-v VAR] NUM ...\f[R] -.PP +\f[CR]NUM\f[R]: a valid number +.SS \f[CR]bb_max [\-v VAR] NUM ...\f[R] Returns the maximum of the given numbers .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]NUM\f[R]: a valid number -.SS \f[V]bb_abs [-v VAR] NUM\f[R] -.PP +\f[CR]NUM\f[R]: a valid number +.SS \f[CR]bb_abs [\-v VAR] NUM\f[R] Returns the absolute value of a given number .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]NUM\f[R]: a valid number -.SS \f[V]bb_isint NUM ...\f[R] -.PP +\f[CR]NUM\f[R]: a valid number +.SS \f[CR]bb_isint NUM ...\f[R] Checks if all the given numbers are valid integers .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]NUM\f[R]: a number to check +\f[CR]NUM\f[R]: a number to check .PP \f[B]Returns:\f[R] 0 if all arguments are integers, 1 otherwise -.SS \f[V]bb_hex2dec [-V LISTVAR] NUM ...\f[R] -.PP +.SS \f[CR]bb_hex2dec [\-V LISTVAR] NUM ...\f[R] Converts numbers from hexademical (base 16) to decimal (base 10) .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: list variable to store result (if not given, prints +\f[CR]LISTVAR\f[R]: list variable to store result (if not given, prints to stdout) .IP \[bu] 2 -\f[V]NUM\f[R]: a number to convert +\f[CR]NUM\f[R]: a number to convert .PP \f[B]Returns:\f[R] 1 if any number is invalid hexadecimal, 0 otherwise -.SS \f[V]bb_dec2hex [-V LISTVAR] NUM ...\f[R] -.PP +.SS \f[CR]bb_dec2hex [\-V LISTVAR] NUM ...\f[R] Converts numbers from decimal (base 10) to hexademical (base 16) .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: list variable to store result (if not given, prints +\f[CR]LISTVAR\f[R]: list variable to store result (if not given, prints to stdout) .IP \[bu] 2 -\f[V]NUM\f[R]: a number to convert +\f[CR]NUM\f[R]: a number to convert .PP \f[B]Returns:\f[R] 1 if any number is invalid decimal, 0 otherwise -.SS \f[V]bb_oct2dec [-V LISTVAR] NUM ...\f[R] -.PP +.SS \f[CR]bb_oct2dec [\-V LISTVAR] NUM ...\f[R] Converts numbers from octal (base 8) to decimal (base 10) .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: list variable to store result (if not given, prints +\f[CR]LISTVAR\f[R]: list variable to store result (if not given, prints to stdout) .IP \[bu] 2 -\f[V]NUM\f[R]: a number to convert +\f[CR]NUM\f[R]: a number to convert .PP \f[B]Returns:\f[R] 1 if any number is invalid octal, 0 otherwise -.SS \f[V]bb_dec2oct [-V LISTVAR] NUM ...\f[R] -.PP +.SS \f[CR]bb_dec2oct [\-V LISTVAR] NUM ...\f[R] Converts numbers from decimal (base 10) to octal (base 8) .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LISTVAR\f[R]: list variable to store result (if not given, prints +\f[CR]LISTVAR\f[R]: list variable to store result (if not given, prints to stdout) .IP \[bu] 2 -\f[V]NUM\f[R]: a number to convert +\f[CR]NUM\f[R]: a number to convert .PP \f[B]Returns:\f[R] 1 if any number is invalid decimal, 0 otherwise .SH Package util/prof -.PP Routines for runtime profiling of bash scripts -.SS \f[V]bb_startprof LOGFILE\f[R] -.PP +.SS \f[CR]bb_startprof LOGFILE\f[R] Starts runtime profiling .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]LOGFILE\f[R]: (optional) file use to log profiling data Default: +\f[CR]LOGFILE\f[R]: (optional) file use to log profiling data Default: TMPDIR/bbprof.PID.out .PP \f[B]Notes:\f[R] .PP -Use the bbprof-read utility script to parse and analyze profile data -.SS \f[V]bb_stopprof\f[R] -.PP +Use the bbprof\-read utility script to parse and analyze profile data +.SS \f[CR]bb_stopprof\f[R] Stops runtime profiling .SH Package util/rand -.PP Routines for generating random sequences -.SS \f[V]bb_randint [-v VAR] MAX [MIN]\f[R] -.PP -Returns a random non-negative integer between MIN and MAX +.SS \f[CR]bb_randint [\-v VAR] MAX [MIN]\f[R] +Returns a random non\-negative integer between MIN and MAX .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]MAX\f[R]: the largest possible returned value +\f[CR]MAX\f[R]: the largest possible returned value .IP \[bu] 2 -\f[V]MIN\f[R]: the smallest possible returned value (defaults to zero) -.SS \f[V]bb_randstr [-v VAR] LENGTH [CHARSET]\f[R] -.PP +\f[CR]MIN\f[R]: the smallest possible returned value (defaults to zero) +.SS \f[CR]bb_randstr [\-v VAR] LENGTH [CHARSET]\f[R] Returns a random string of the given length .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]LENGTH\f[R]: length of the returned string +\f[CR]LENGTH\f[R]: length of the returned string .IP \[bu] 2 -\f[V]CHARSET\f[R]: string with all possible characters to use (defaults +\f[CR]CHARSET\f[R]: string with all possible characters to use (defaults to all alphanumeric characters) -.SS \f[V]bb_loadworddict [FILENAME]\f[R] -.PP +.SS \f[CR]bb_loadworddict [FILENAME]\f[R] Loads a dictionary of words .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]FILENAME\f[R]: file containing words, one per line +\f[CR]FILENAME\f[R]: file containing words, one per line .PP \f[B]Notes:\f[R] .PP The dictionary file should contain one word per line -.SS \f[V]bb_randwords [-v VAR] COUNT [SEP]\f[R] -.PP -Returns a string containing non-repeated random words from a loaded word -dictionary +.SS \f[CR]bb_randwords [\-v VAR] COUNT [SEP]\f[R] +Returns a string containing non\-repeated random words from a loaded +word dictionary .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]COUNT\f[R]: number of returned words +\f[CR]COUNT\f[R]: number of returned words .IP \[bu] 2 -\f[V]SEP\f[R]: separator to use between words (default is space) +\f[CR]SEP\f[R]: separator to use between words (default is space) .PP \f[B]Notes:\f[R] .PP You must load a word dictionary with bb_loadworddict before using this .SH Package util/string -.PP Routines for common string operations -.SS \f[V]bb_lstrip [-v VAR] TEXT\f[R] -.PP +.SS \f[CR]bb_lstrip [\-v VAR] TEXT\f[R] Strips leading (left) whitespace from text .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]TEXT\f[R]: text to strip whitespace from -.SS \f[V]bb_rstrip [-v VAR] TEXT\f[R] -.PP +\f[CR]TEXT\f[R]: text to strip whitespace from +.SS \f[CR]bb_rstrip [\-v VAR] TEXT\f[R] Strips trailing (right) whitespace from text .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]TEXT\f[R]: text to strip whitespace from -.SS \f[V]bb_strip [-v VAR] TEXT\f[R] -.PP +\f[CR]TEXT\f[R]: text to strip whitespace from +.SS \f[CR]bb_strip [\-v VAR] TEXT\f[R] Strips leading and trailing whitespace from text .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]TEXT\f[R]: text to strip whitespace from -.SS \f[V]bb_reversestr [-v VAR] TEXT\f[R] -.PP +\f[CR]TEXT\f[R]: text to strip whitespace from +.SS \f[CR]bb_reversestr [\-v VAR] TEXT\f[R] Reverses a string .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]TEXT\f[R]: text to reverse -.SS \f[V]bb_ord [-v VAR] CHAR\f[R] -.PP +\f[CR]TEXT\f[R]: text to reverse +.SS \f[CR]bb_ord [\-v VAR] CHAR\f[R] Converts character to its ASCII decimal code .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]CHAR\f[R]: a single character -.SS \f[V]bb_chr [-v VAR] CODE\f[R] -.PP +\f[CR]CHAR\f[R]: a single character +.SS \f[CR]bb_chr [\-v VAR] CODE\f[R] Converts ASCII decimal code to character .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]CODE\f[R]: an integer ASCII character code -.SS \f[V]bb_snake2camel [-v VAR] TEXT\f[R] -.PP +\f[CR]CODE\f[R]: an integer ASCII character code +.SS \f[CR]bb_snake2camel [\-v VAR] TEXT\f[R] Converts text from snake to camel case .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]TEXT\f[R]: text in snake case +\f[CR]TEXT\f[R]: text in snake case .PP \f[B]Notes:\f[R] .PP Leading underscores are preserved -.SS \f[V]bb_camel2snake [-v VAR] TEXT\f[R] -.PP +.SS \f[CR]bb_camel2snake [\-v VAR] TEXT\f[R] Converts text from camel to snake case .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]TEXT\f[R]: text in camel case -.SS \f[V]bb_titlecase [-v VAR] TEXT\f[R] -.PP +\f[CR]TEXT\f[R]: text in camel case +.SS \f[CR]bb_titlecase [\-v VAR] TEXT\f[R] Converts text into title case (every word capitalized) .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]TEXT\f[R]: text to transform +\f[CR]TEXT\f[R]: text to transform .PP \f[B]Notes:\f[R] .PP This does not check the content of the words itself and may not respect grammatical rules, e.g.\ \[lq]And\[rq] will be capitalized -.SS \f[V]bb_sentcase [-v VAR] TEXT\f[R] -.PP +.SS \f[CR]bb_sentcase [\-v VAR] TEXT\f[R] Converts text into sentence case (every first word capitalized) .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]TEXT\f[R]: text to transform -.SS \f[V]bb_urlencode [-v VAR] TEXT\f[R] -.PP +\f[CR]TEXT\f[R]: text to transform +.SS \f[CR]bb_urlencode [\-v VAR] TEXT\f[R] Performs URL (percent) encoding on the given string .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]TEXT\f[R]: text to be encoded -.SS \f[V]bb_urldecode [-v VAR] TEXT\f[R] -.PP -Decodes URL-encoded text +\f[CR]TEXT\f[R]: text to be encoded +.SS \f[CR]bb_urldecode [\-v VAR] TEXT\f[R] +Decodes URL\-encoded text .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]TEXT\f[R]: text to be decoded +\f[CR]TEXT\f[R]: text to be decoded .PP \f[B]Returns:\f[R] 1 if the input URL encoding is malformed, 0 otherwise -.SS \f[V]bb_repeatstr [-v VAR] NUM TEXT\f[R] -.PP +.SS \f[CR]bb_repeatstr [\-v VAR] NUM TEXT\f[R] Repeat TEXT NUM times .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]NUM\f[R]: repeat this many times (integer) +\f[CR]NUM\f[R]: repeat this many times (integer) .IP \[bu] 2 -\f[V]TEXT\f[R]: text to repeat -.SS \f[V]bb_centerstr [-v VAR] WIDTH TEXT [FILL]\f[R] -.PP +\f[CR]TEXT\f[R]: text to repeat +.SS \f[CR]bb_centerstr [\-v VAR] WIDTH TEXT [FILL]\f[R] Pad and center TEXT with FILL character to have WIDTH width .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]WIDTH\f[R]: width of the padded string result +\f[CR]WIDTH\f[R]: width of the padded string result .IP \[bu] 2 -\f[V]TEXT\f[R]: text to display +\f[CR]TEXT\f[R]: text to display .IP \[bu] 2 -\f[V]FILL\f[R]: character used for padding (if not given, uses space) +\f[CR]FILL\f[R]: character used for padding (if not given, uses space) .PP \f[B]Notes:\f[R] .PP If the text cannot be perfectly centered, it will be pushed closer to the left side. TEXT may contain color codes. -.SS \f[V]bb_cmpversion VER1 VER2 [DELIM]\f[R] -.PP +.SS \f[CR]bb_cmpversion VER1 VER2 [DELIM]\f[R] Checks if VER1 is greater than or equal to VER2 .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VER1\f[R]: a version string (containing only numerals and +\f[CR]VER1\f[R]: a version string (containing only numerals and delimeters) .IP \[bu] 2 -\f[V]VER2\f[R]: another version string, usually a reference point +\f[CR]VER2\f[R]: another version string, usually a reference point .IP \[bu] 2 -\f[V]DELIM\f[R]: character(s) to delimit fields in the version string -(default: .-_) +\f[CR]DELIM\f[R]: character(s) to delimit fields in the version string +(default: .\-_) .PP \f[B]Returns:\f[R] 0 if VER1 greater or equal to VER2, 1 otherwise .PP @@ -1524,31 +1386,28 @@ delimeters) .PP Numeric comparison is used, so alphabetical characters are not supported .SH Package util/time -.PP Routines for common time and date operations .PP \f[B]Example:\f[R] .IP -.nf -\f[C] -bb_timefmt \[dq]%F %T\[dq] # e.g., 2022-11-20 16:53:30 -bb_timefmt \[dq]%F %T\[dq] $(bb_now +1h) # one hour from now -bb_timefmt \[dq]%F %T\[dq] $(bb_now \[ha]h) # end of the hour -bb_timefmt \[dq]%F %T\[dq] $(bb_now +1d) # one day from now -bb_timefmt \[dq]%F %T\[dq] $(bb_now \[ha]d) # end of the day -bb_timefmt \[dq]%F %T\[dq] $(bb_now +2w \[ha]d) # after two weeks, at end of day -\f[R] -.fi -.SS \f[V]bb_now [-v VAR] [OFFSET ...]\f[R] -.PP +.EX +bb_timefmt \[dq]%F %T\[dq] \f[I]# e.g., 2022\-11\-20 16:53:30\f[R] +bb_timefmt \[dq]%F %T\[dq] $(bb_now +1h) \f[I]# one hour from now\f[R] +bb_timefmt \[dq]%F %T\[dq] $(bb_now \[ha]h) \f[I]# end of the hour\f[R] +bb_timefmt \[dq]%F %T\[dq] $(bb_now +1d) \f[I]# one day from now\f[R] +bb_timefmt \[dq]%F %T\[dq] $(bb_now \[ha]d) \f[I]# end of the day\f[R] +bb_timefmt \[dq]%F %T\[dq] $(bb_now +2w \[ha]d) \f[I]# after two weeks, at end of day\f[R] +.EE +.SS \f[CR]bb_now [\-v VAR] [OFFSET ...]\f[R] Returns a timestamp relative to the current time (in seconds after epoch) .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]OFFSET\f[R]: {+,-}N{s,m,h,d,w}[\[ha]] where N is an integer +\f[CR]OFFSET\f[R]: {+,\-}N{s,m,h,d,w}[\[ha]] where N is an integer .PP \f[B]Returns:\f[R] 1 if any offset is invalid, 0 otherwise .PP @@ -1556,31 +1415,30 @@ epoch) .PP s: seconds m: minutes h: hours d: days w: weeks Optional: trailing \[ha] rounds up; \[ha]d is short for +0d\[ha] -.SS \f[V]bb_timefmt [-v VAR] FORMAT [TIMESTAMP]\f[R] -.PP +.SS \f[CR]bb_timefmt [\-v VAR] FORMAT [TIMESTAMP]\f[R] Formats a timestamp into a desired date format .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: variable to store result (if not given, prints to stdout) +\f[CR]VAR\f[R]: variable to store result (if not given, prints to +stdout) .IP \[bu] 2 -\f[V]FORMAT\f[R]: date format string, refer to man strftime +\f[CR]FORMAT\f[R]: date format string, refer to man strftime .IP \[bu] 2 -\f[V]TIMESTAMP\f[R]: epoch time, defaults to current time (now) -.SS \f[V]bb_timedeltafmt [-v VAR] FORMAT TIME1 [TIME2]\f[R] -.PP +\f[CR]TIMESTAMP\f[R]: epoch time, defaults to current time (now) +.SS \f[CR]bb_timedeltafmt [\-v VAR] FORMAT TIME1 [TIME2]\f[R] Formats a time delta into a desired format .PP \f[B]Arguments:\f[R] .IP \[bu] 2 -\f[V]VAR\f[R]: +\f[CR]VAR\f[R]: .IP \[bu] 2 -\f[V]FORMAT\f[R]: +\f[CR]FORMAT\f[R]: .IP \[bu] 2 -\f[V]TIME1\f[R]: if TIME1 not specified, this is interpreted as a +\f[CR]TIME1\f[R]: if TIME1 not specified, this is interpreted as a duration in seconds .IP \[bu] 2 -\f[V]TIME2\f[R]: if specified, TIME1 is the end timestamp and TIME2 is +\f[CR]TIME2\f[R]: if specified, TIME1 is the end timestamp and TIME2 is the start timestamp .PP \f[B]Notes:\f[R] @@ -1590,16 +1448,14 @@ d, h, m, s represent the total value .PP \f[B]Example:\f[R] .IP -.nf -\f[C] -bb_now -v start +.EX +bb_now \-v start sleep 120s -bb_now -v end -bb_timedeltafmt -v elapsed \[dq]%H:%M:%S\[dq] end start -bb_timedeltafmt -v total_seconds \[dq]%s\[dq] end start +bb_now \-v end +bb_timedeltafmt \-v elapsed \[dq]%H:%M:%S\[dq] end start +bb_timedeltafmt \-v total_seconds \[dq]%s\[dq] end start echo \[dq]elapsed time $elapsed, $total_seconds total seconds\[dq] -# above should print \[dq]elapsed time 00:02:00, 120 total seconds\[dq] -\f[R] -.fi +\f[I]# above should print \[dq]elapsed time 00:02:00, 120 total seconds\[dq]\f[R] +.EE .SH AUTHORS github.com/tomocafe. diff --git a/src/util/_test.sh b/src/util/_test.sh index a02e8d2..5c1c45e 100644 --- a/src/util/_test.sh +++ b/src/util/_test.sh @@ -147,16 +147,22 @@ bb_expect ":$__bb_one:$__bb_two:$__bb_three:" ":x:y::" bb_rename "${__bb_tmp_list[@]}" -- __bb_one __bb_two __bb_three bb_expect ":$__bb_one:$__bb_two:$__bb_three:" ":x:y:z:" -unset __bb_one __bb_two __bb_three -bb_unpack __bb_tmp_list __bb_one __bb_two __bb_three -bb_expect ":$__bb_one:$__bb_two:$__bb_three:" ":x:y:z:" - -bb_map __bb_tmp_list bb_ord -bb_expect "${__bb_tmp_list[*]}" "120 121 122" - -__bb_tmp_list=(x y z) -bb_mapkeys __bb_tmp_map bb_ord "${__bb_tmp_list[@]}" -bb_expect "${__bb_tmp_map[z]} ${__bb_tmp_map[x]} ${__bb_tmp_map[y]}" "122 120 121" +if _bb_checkbashversion 4 3; then + unset __bb_one __bb_two __bb_three + bb_unpack __bb_tmp_list __bb_one __bb_two __bb_three + bb_expect ":$__bb_one:$__bb_two:$__bb_three:" ":x:y:z:" +fi + +if _bb_checkbashversion 4 3; then + bb_map __bb_tmp_list bb_ord + bb_expect "${__bb_tmp_list[*]}" "120 121 122" +fi + +if _bb_checkbashversion 4 3; then + __bb_tmp_list=(x y z) + bb_mapkeys __bb_tmp_map bb_ord "${__bb_tmp_list[@]}" + bb_expect "${__bb_tmp_map[z]} ${__bb_tmp_map[x]} ${__bb_tmp_map[y]}" "122 120 121" +fi bb_expect "$(bb_reverselist a b c)" "c b a" diff --git a/src/util/list.sh b/src/util/list.sh index 48717e1..fbe1c2f 100644 --- a/src/util/list.sh +++ b/src/util/list.sh @@ -264,33 +264,41 @@ function bb_rename () { # function: bb_unpack LISTVAR NAME ... # Unpacks list items into named variables +# @requires: 4.3 # @arguments: # - LISTVAR: name of the list variable (do not include $) # - NAME: a variable name to hold a list element +_bb_checkbashversion 4 3 && \ function bb_unpack () { declare -n arr="$1" bb_rename "${arr[@]}" -- "${@:2}" -} +} \ +|| bb_unpack () { _bb_unsupportedbashversion ${FUNCNAME[0]} 4 3; } # function: bb_map LISTVAR FUNCTION # Maps a function over a list, modifying it in place +# @requires: 4.3 # @arguments: # - LISTVAR: name of the list variable (do not include $) # - FUNCTION: a function or command to map a list element to a new value +_bb_checkbashversion 4 3 && \ function bb_map () { declare -n arr="$1" local -i i for (( i=0; i<${#arr[@]}; i++ )); do arr[$i]="$("$2" "${arr[$i]}" 2>/dev/null)" done -} +} \ +|| bb_map () { _bb_unsupportedbashversion ${FUNCNAME[0]} 4 3; } # function: bb_mapkeys LISTVAR FUNCTION KEYS ... # Maps a function over a list of keys to generate an associative array +# @requires: 4.3 # @arguments: # - LISTVAR: name of an associative array variable (do not include $) # - FUNCTION: a function or command to map keys to values # - KEYS: keys which will be added to the associative array with mapped values +_bb_checkbashversion 4 3 && \ function bb_mapkeys () { declare -Ag "$1" declare -n arr="$1" @@ -300,7 +308,8 @@ function bb_mapkeys () { for key in "$@"; do arr+=( ["$key"]="$("$h" "$key" 2>/dev/null)" ) done -} +} \ +|| bb_mapkeys () { _bb_unsupportedbashversion ${FUNCNAME[0]} 4 3; } # function: bb_reverselist [-V LISTVAR] ITEM ... # Returns a reversed version of the given list