declare -gA __BC__DIR __BC__META __BC__FD __BC__REP __BC__OWNER
__BC__FAILED=125
__BC__at=""
shopt -s expand_aliases
alias __BC_BAIL='return $?'
alias __BC_THROW='{ __bc_complain "${FUNCNAME[0]} ($?)"; return "$__BC__FAILED"; }'
__bc_complain() {
printf '%s: %s at %s\n' "${__BC__word:-?}" "$1" "${__BC__at:-?}" >&2
}
BC_JOIN() {
__BC__at="${BASH_SOURCE[1]:-?}:${BASH_LINENO[0]:-?}"
__BC__word=${FUNCNAME[0]}
[[ -n ${1-} && $1 != */* && $1 != *[[:space:]]* ]] \
|| { __bc_complain "label ${1-} will not name a file"; return "$__BC__FAILED"; }
[[ ${2-} == /* ]] \
|| { __bc_complain "workspace ${2-} is not an absolute path"; return "$__BC__FAILED"; }
[[ -z ${__BC__DIR[$1]-} ]] \
|| { __bc_complain "label $1 is already joined from ${__BC__DIR[$1]}"; return "$__BC__FAILED"; }
__BC__DIR[$1]=$2
local __bc_label=$1 IFS=' '
shift 2 || __BC_THROW
__BC__META[$__bc_label]="${*@Q}"
__bc_attach "$__bc_label"
}
BC_INSTR() {
__BC__at="${BASH_SOURCE[1]:-?}:${BASH_LINENO[0]:-?}"
__BC__word=${FUNCNAME[0]}
[[ -n ${__BC__DIR[${1-}]-} ]] \
|| { __bc_complain "label ${1-} is not joined"; return "$__BC__FAILED"; }
[[ $BASHPID == "${__BC__OWNER[$1]}" ]] || __bc_reattach "$1" || __BC_BAIL
case "${2-}" in
say) __bc_send "$1" SAY "${@:3}" ;;
ask) __bc_ask "$1" "${@:3}" ;;
*) __bc_complain "unknown verb ${2-}"; return "$__BC__FAILED" ;;
esac
}
__bc_attach() {
local __bc_dir=${__BC__DIR[$1]}
local __bc_tok="$1::$BASHPID.${EPOCHREALTIME#*[.,]}.${SRANDOM:-$RANDOM$RANDOM}"
local __bc_fd __bc_rep __bc_acct
[[ -p "$__bc_dir/join" ]] || { __bc_complain "no session at $__bc_dir"; return "$__BC__FAILED"; }
__bc_account __bc_acct "$1"
mkfifo "$__bc_dir/up.$__bc_tok" || __BC_THROW
__bc_announce "$__bc_tok" "$__bc_acct" >"$__bc_dir/join" || __BC_BAIL
exec {__bc_fd}>"$__bc_dir/up.$__bc_tok" || __BC_THROW
exec {__bc_rep}<>"$__bc_dir/rep.$__bc_tok" || __BC_THROW
__BC__FD[$1]=$__bc_fd
__BC__REP[$1]=$__bc_rep
__BC__OWNER[$1]=$BASHPID
}
__bc_reattach() {
local __bc_fd=${__BC__FD[$1]} __bc_rep=${__BC__REP[$1]}
exec {__bc_fd}>&- {__bc_rep}>&- || __BC_THROW
__bc_attach "$1"
}
__bc_account() {
local __bc_out=$1 IFS=' '
local -a __bc_meta="(${__BC__META[$2]-})"
set -- "at=$EPOCHREALTIME" \
pid "$BASHPID" \
shlvl "$SHLVL" \
subshell "$BASH_SUBSHELL" \
versinfo "(${BASH_VERSINFO[*]@Q})" \
bash "$BASH" \
zero "$0" \
flags "$-" \
shellopts "$SHELLOPTS" \
bashopts "$BASHOPTS" \
command "${BASH_EXECUTION_STRING-}" \
brought "(${__bc_meta[*]@Q})"
printf -v "$__bc_out" '(%s)' "${*@Q}"
}
__bc_announce() {
local LC_ALL=C
local __bc_room=$(( 4096 - ${#1} - 4 )) __bc_from=0
while (( ${#2} - __bc_from > __bc_room )); do
printf '%s + %s\n' "$1" "${2:__bc_from:__bc_room}" || __BC_THROW
__bc_from=$(( __bc_from + __bc_room ))
done
printf '%s . %s\n' "$1" "${2:__bc_from}" || __BC_THROW
}
__bc_send() {
local IFS=' ' __bc_fd=${__BC__FD[$1]}
set -- "$2" "at=$EPOCHREALTIME" "${@:3}"
printf '(%s)\n' "${*@Q}" >&"$__bc_fd" || __BC_THROW
}
__bc_ask() {
__bc_send "$1" ASK "${@:2}" || __BC_BAIL
local __bc_line
IFS= read -r __bc_line <&"${__BC__REP[$1]}" || __BC_THROW
local -a __bc_answer="$__bc_line"
"${__bc_answer[@]}"
}