This commit is contained in:
olli 2024-06-25 12:10:19 +02:00
parent 567a3ae1a9
commit ae1379180c

View File

@ -1,66 +1,34 @@
function g_calc { function g_calc {
# function for calcul
# $g_fd_bc_in $fd_bc_out have to be global
unset g_calc_result unset g_calc_result
local g_calc_jobs g_rnd # check if bc is already running
local g_bc_running=true if [[ -z "$g_fd_bc_in" || -z "$g_fd_bc_out" ]]
mapfile -t g_calc_jobs < <(jobs -r)
g_calc_jobs_v=${g_calc_jobs[*]}
[[ $g_calc_jobs_v =~ bc ]] || unset g_bc_running
# Use bc in backround for multiple bc's running much faster
if [ -z "${g_bc_running}" ]
then then
local bc_input="$g_tmp/$$-g_bc_input"
g_kill_all_background_jobs bc-ql local bc_output="$g_tmp/$$-g_bc_output"
g_kill_all_background_jobs sed # create fifo pipe
[ -p "$bc_input" ] || mkfifo "$bc_input"
g_rnd=$$ [ -p "$bc_output" ] || mkfifo "$bc_output"
mkdir -p ${g_tmp}/${g_rnd} # run bc in background und switch i/o to pipes
[ -p ${g_tmp}/${g_rnd}/bc-in ] || mkfifo ${g_tmp}/${g_rnd}/bc-in bc -ql < "$bc_input" > "$bc_output" 2>&1 &
[ -p ${g_tmp}/${g_rnd}/bc-out ] || mkfifo ${g_tmp}/${g_rnd}/bc-out # store in filedescriptiors
[ -p ${g_tmp}/${g_rnd}/bc-sed-in ] || mkfifo ${g_tmp}/${g_rnd}/bc-sed-in exec {g_fd_bc_in}> "$bc_input"
[ -p ${g_tmp}/${g_rnd}/bc-sed-out ] || mkfifo ${g_tmp}/${g_rnd}/bc-sed-out exec {g_fd_bc_out}< "$bc_output"
fi
# bc stream channel # send calculation and read result
{ bc -ql <${g_tmp}/${g_rnd}/bc-in 2>&1 >${g_tmp}/${g_rnd}/bc-out & } 2>/dev/null echo "$1" >&${g_fd_bc_in}
exec 3>${g_tmp}/${g_rnd}/bc-in 4<${g_tmp}/${g_rnd}/bc-out read -u ${g_fd_bc_out} g_calc_result
g_calc_result=${g_calc_result//-./-0.}
# sed stream channel g_calc_result=${g_calc_result//./0.}
{ sed -su 's/^\./0./; s/^-\./-0./' <${g_tmp}/${g_rnd}/bc-sed-in >${g_tmp}/${g_rnd}/bc-sed-out & } 2>/dev/null if ! g_num_valid_number $g_calc_result
exec 5>${g_tmp}/${g_rnd}/bc-sed-in 6<${g_tmp}/${g_rnd}/bc-sed-out
g_bc_running="true"
fi
# do bc
echo "scale=8; $@" >&3
local g_bc_out
if ! read -t 0.1 g_bc_out <&4
then then
g_traceback "$@" echo "${FUNCNAME} $@" 1>&2
( exec 3<&- ) 2>/dev/null unset g_calc_result
( exec 4<&- ) 2>/dev/null
( exec 5<&- ) 2>/dev/null
( exec 6<&- ) 2>/dev/null
#unset g_bc_running
return 1
fi
# do sed
echo ${g_bc_out} >&5
local g_sed_out
if ! read -t 0.1 g_sed_out <&6
then
g_traceback "$@"
( exec 3<&- ) 2>/dev/null
( exec 4<&- ) 2>/dev/null
( exec 5<&- ) 2>/dev/null
( exec 6<&- ) 2>/dev/null
#unset g_bc_running
return 1 return 1
fi fi
# store result
g_calc_result=$g_sed_out
} }