many bugfix, fixed getopt split

This commit is contained in:
2026-10-13 16:01:13 +02:00
parent b5be992d82
commit ba1e07744e
22 changed files with 478 additions and 125 deletions
+119
View File
@@ -0,0 +1,119 @@
#!/usr/bin/env bash
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
#
# * Redistribution and use in source and binary forms,
# * with or without modification, are permitted provided
# * that the following conditions are met:
# *
# * Redistributions of source code must retain the above
# * copyright notice, this list of conditions and the
# * following disclaimer.
# *
# * Redistributions in binary form must reproduce the above
# * copyright notice, this list of conditions and the following
# * disclaimer in the documentation and/or other materials
# * provided with the distribution.
# *
# * Neither the name of the copyright holder nor the names
# * of any other contributors may be used to endorse or
# * promote products derived from this software without
# * specific prior written permission.
# *
# * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
# * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# * OF SUCH DAMAGE.
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Helpers for the option parsing of the commands. The project rule is to never
# use eval: these functions rebuild argument lists in pure bash.
# Split the output of getopt into the array whose name is $1, without eval and
# without xargs. getopt prints the normalised arguments as one shell-quoted
# line (options bare, every argument in single quotes, a quote inside an
# argument written '\''), for instance:
# -s 'a b' --long 'it'\''s' -- 'file' ''
# Quoted text is taken verbatim (newlines included), an empty argument ('')
# yields an empty element, and nothing is ever evaluated. The usual call is
# local -a _pargs=()
# _getopt_split _pargs "$PARSED"
# set -- "${_pargs[@]}"
# Usage: _getopt_split <array_name> <getopt_output>
_getopt_split()
{
local -n _gs_out="$1"
local s="$2" tok="" in_tok=0 run
local run_re=$'^[^ \t\n\'\\\\]+'
_gs_out=()
while [[ -n "$s" ]]; do
case "${s:0:1}" in
"'")
s="${s:1}"
if [[ "$s" == *\'* ]]; then
tok+="${s%%\'*}"
s="${s#*\'}"
else
# Unterminated quote (never produced by getopt): keep the rest
tok+="$s"
s=""
fi
in_tok=1
;;
'\')
tok+="${s:1:1}"
s="${s:2}"
in_tok=1
;;
' '|$'\t'|$'\n')
(( in_tok )) && _gs_out+=("$tok")
tok=""
in_tok=0
s="${s:1}"
;;
*)
[[ "$s" =~ $run_re ]] || break
run="${BASH_REMATCH[0]}"
tok+="$run"
s="${s:${#run}}"
in_tok=1
;;
esac
done
(( in_tok )) && _gs_out+=("$tok")
return 0
}
export -f _getopt_split
# Put back traps saved with "trap -p" (one "trap -- 'command' SIGNAL" line per
# trap), without eval. Used to restore the caller's traps after temporarily
# replacing them. An empty argument restores nothing.
# Usage: _trap_restore "$(trap -p INT TERM)"
_trap_restore()
{
local line
local -a w=()
while IFS= read -r line; do
[[ "$line" == "trap -- "* ]] || continue
_getopt_split w "$line"
# w = (trap -- <command> <SIGNAL>)
[[ ${#w[@]} -eq 4 ]] && trap -- "${w[2]}" "${w[3]}"
done <<< "$1"
return 0
}
export -f _trap_restore
# ------------------------------------------------------------------------------
# EOF