123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- #!/bin/bash
-
-
- ##--------------------##
- ## PRINTING FRONT-END ##
- ##--------------------##
-
- debug() {
- #
- # You already know what it does
- #
- # BTW, following are equivalent:
- #
- # debug "var1=$var1" "var2=$var2" "result=$result"
- # debug -v var1 var2 result
- # debug -v "var@ result"
- #
- $FFOO_DEBUG || return 0
- __echo "$@"
- }
-
-
- debug_pipe() {
- #
- # Debug the whole pipe.
- #
- grep . \
- | while IFS= read line;
- do
- debug "|$1: '$line'"
- echo "$line"
- done
- }
-
-
- die() {
- #
- # A Perl-style death
- #
- __echo -t
- __echo $*
- __exits 9
- }
-
-
- usage_is() {
- #
- # Echo out usage patterns and (by default) exit 2
- #
- # Specify -e STATUS for exit status, or "-E" to prevent
- # exiting. Use "--" to delimit end of arguments processed
- # by usage_is.
- #
- # Recommended usage is to define usage() in your script and
- # use this in body.
- #
- local es=2
- while true; do case "$1" in
- -e) es="$2"; shift 2 ;;
- -E) es=""; shift ;;
- *) break ;;
- esac done
- __echo -u "$@";
- test -n "$es" && __exits "$es"
- }
-
-
- think() {
- #
- # If verose is on, think loud
- #
- # Use "-l" to split every parameter to separate line, (useful
- # or longer warnings)
- #
- $FFOO_VERBOSE || return 0
- __echo "$@"
- }
-
-
- warn() {
- #
- # Warn them
- #
- # Use "-l" to split every parameter to separate line, (useful
- # or longer warnings)
- #
- # Resist temptation to prefix "warning" or similar BS here.
- # STDERR is *made* for warnings.
- #
- __echo "$@"
- }
-
-
- ##----------##
- ## BACK-END ##
- ##----------##
-
-
- __cat() {
- # cat without starting a process
- while IFS= read line;
- do echo "$line"; done
- }
-
-
- __cut_stack() {
- #
- # call stack except the head that fits pattern $1
- #
- local patt=${1:-"^__"}
- printf -- '%s\n' "${FUNCNAME[@]}" \
- | perl -ne "
- my \$checking = 1;
- while (<>) {
- next if (\$checking and m/$patt/);
- \$checking = 0;
- print qq/\$_\\n/;
- }
- "
- }
-
-
- __echo() {
- #
- # A smarter echo backend
- #
- # A smarter backend for debug, warn, think, die and
- # usage_is.
- #
- # -c cmd echo output of a command
- # -f file echo output of a file (- for stdin)
- # -l line [line...] echo each line separately
- # -t add stack trace to output
- # -u patt [patt...] convert each patt to usage pattern
- # -v var [var...] show contents of each var
- #
- ffoo import mkpretty_${FFOO_MKPRETTY}
- local frontend # who (of core.sh) was called (=> prettyprinter choice)
- local caller # which user's function (or script) called it
- frontend="$(__cut_stack '^__echo' | head -1 )"
- caller="$(
- __cut_stack \
- '^__echo|^warn$|^debug$|^die$|^usage$|^usage_is$|^think$' \
- | head -1
- )"
- test "$frontend" == "main" && frontend=$(basename $0)
- test "$caller" == "main" && caller=$(basename $0)
- test "$frontend" == "usage" && frontend=usage_is
- local prettyfn=__cat
- local src
- while true; do case $1 in
- -c|--cmd) src=cmd; shift; break ;;
- -f|--files) src=files; shift; break ;;
- -l|--lines) src=lines; shift; break ;;
- -t|--trace) src=trace; shift; break ;;
- -u|--usage) src=usage; shift; break ;;
- -v|--vars) src=vars; shift; break ;;
- *) src=args; break ;;
- esac done
- prettyfn=mkpretty_$frontend
- case $frontend in
- warn|debug|die|usage_is) __echo_$src "$@" | $prettyfn >&2 ;;
- think) __echo_$src "$@" | $prettyfn ;;
- *) echo "do not call __echo* directly: $frontend" >&2;
- __exits 2 ;;
- esac
- }
-
-
- __echo_args() {
- echo "$@"
- }
-
-
- __echo_cmd() {
- local c=\$
- test $(id -u) -eq 0 && c=\#
- echo "$c $*"
- $@
- echo "^ exit status: $?"
- }
-
-
- __echo_files() {
- local fp
- for fp in "$@";
- do
- test -s "$fp" || continue
- echo "-- $fp --"
- cat $fp
- done
- }
-
-
- __echo_lines() {
- local l;
- for l in "$@"; do __echo "$l"; done
- }
-
-
- __echo_trace() {
- $FFOO_DEBUG || return 0
- echo "== trace =="
- caller | sed -e 's/^/-> /g'
- }
-
-
- __echo_usage() {
- local u
- for u in "$@";
- do echo "usage: $caller $u"
- done
- }
-
-
- __echo_vars() {
- local vn
- for vn in "$@";
- do
- local heel="${vn:0-1}" # last char
- local toes="${vn%%$heel}" # all but last char
- case "$heel" in
- @)
- # FIXME: review+fix the eval (even at cost of
- # dropping the feature)
- local vars=$(eval "echo \"\${!$toes$heel}\"")
- __echo_vars $vars
- ;;
- *)
- __echo "$vn='$(echo -n ${!vn})'"
- ;;
- esac
- done
- }
-
-
- ## ---- ##
- ## UTIL ##
- ## ---- ##
-
-
- __exits() {
- #
- # Like exit but will not exit interactive session
- #
- # fastfoo libs are not intended for use in interactive
- # session (one should use fff for that), but for development
- # and testing purposes we want to enable it
- #
- test -z "$PS1" && exit $1
- }
-
-
- echo_hr() {
- #
- # A horizontal ruler out of char "$1" all across terminal
- #
- test 0$COLUMNS -gt 0 || return
- local char="$1"
- local i
- for (( i=1; $i<$COLUMNS; i=$i+1 )); do echo -n "$char"; done
- echo
- }
-
-
- mute_known() {
- #
- # Mute known messages
- #
- # For those yums and rpms that don't know theit manners.
- # Use with care!
- #
- grep -vxf <(iniread -s mute -k $1 mute.ini)
- }
-
-
- append_if_missing() {
- #
- # Append line to the file but only if it's not already there
- #
- # Handy for your fstabs, or whatever line-based confs Handy
- # for your fstabs, or whatever line-based confs
- #
- local line=$1
- local file=$2
- grep -qsx "$line" $file || echo "$line" >> $file
- }
-
-
- collapse_tilde() {
- #
- # Exchange home back to "~"
- #
- # Nice to save them users from some eye pain.
- #
- perl -pe "s|^$HOME|~|"
- }
-
-
- expand_tilde() {
- #
- # Exchange "~" for home
- #
- perl -pe "s|^[[:space:]]*~|$HOME|"
- }
-
-
- select_args() {
- #
- # Filter args based on type, print one per line
- #
- local want_lopt=false # --long-opt
- local want_sopt=false # -s
- local want_bopt=false # -bndl
- local want_word=false # everything else
- local want="$1"
- shift
- case $want in
- word) want_word=true ;;
- opt) want_lopt=true
- want_sopt=true
- want_bopt=true ;;
- sopt) want_sopt=true ;;
- bopt) want_bopt=true ;;
- lopt) want_lopt=true ;;
- *) usage_is "word|opt|sopt|bopt|lopt args"
- esac
- while true; do case "$1" in
- "") return; ;;
- --*) $want_lopt && echo "$1"; shift ;;
- -n) $want_sopt && echo -e "\055n"; shift ;;
- -e) $want_sopt && echo -e "\055e"; shift ;;
- -E) $want_sopt && echo -e "\055E"; shift ;;
- -?) $want_sopt && echo "$1"; shift ;;
- -*) $want_bopt && echo "$1"; shift ;;
- *) $want_word && echo "$1"; shift ;;
- esac done | tr '\n' ' '
- }
|