123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- #!/bin/bash
-
- ffoo import exits
- ffoo import mkpretty
-
-
- ##--------------------##
- ## 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'"
- echos "$line"
- done
- }
-
-
- die() {
- #
- # A fatal error
- #
- __echo -t
- __echo "$@"
- exits_error
- }
-
-
- echos() {
- #
- # Safer version of echo able to echo "-n"
- #
- # Traditional echo is broken in that it does not
- # distinguish between string to print and its own switches
- # (-e, -E or -n), leading to unexpected behavior.
- #
- # This echo version circumvents this by using printf.
- #
- printf -- '%s\n' "$@"
- }
-
-
- 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=$FFOO_EXITS_OK
- 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 echos "$line"; done
- }
-
-
- __cut_stack() {
- #
- # call stack except the head that fits pattern $1
- #
- local patt=${1:-"^__"}
- echos "${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
- #
- 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 # which source, or "producer" (__echo_*()) to use
- 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_usage ;;
- esac
- }
-
-
- __echo_args() {
- echos "$@"
- }
-
-
- __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 "echos \"\${!$toes$heel}\"")"
- __echo_vars "$vars"
- ;;
- *)
- __echo "$vn='$(echos "${!vn}")'"
- ;;
- esac
- done
- }
|