Skip to content

Commit 0c3a616

Browse files
committed
fix: core.trap_add now works properly
1 parent 9e240d1 commit 0c3a616

File tree

5 files changed

+73
-23
lines changed

5 files changed

+73
-23
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ Added functions: `core.trap_add` (not working), `core.trap_remove` `core.shopt_p
1212

1313
Use [Basalt](https://github.com/hyperupcall/basalt), a Bash package manager, to add this project as a dependency
1414

15-
1615
```sh
1716
basalt add hyperupcall/bash-core
1817
```

basalt.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ description = 'Core lightweight functions that any Bash programmer will love'
77

88
[run]
99
dependencies = ['https://github.com/hyperupcall/bats-all.git@v4.1.0']
10-
sourceDirs = ['./pkg/lib/public']
10+
sourceDirs = ['pkg/lib/public', 'pkg/lib/util']
1111
builtinDirs = []
1212
binDirs = []
1313
completionDirs = []

examples/example.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env bash
2+
3+
set -eo pipefail
4+
shopt -s dotglob globstar nullglob
5+
6+
for f in ../pkg/**/*.sh; do
7+
source "$f"
8+
done; unset f
9+
10+
fn1() {
11+
printf '%s\n' 'Function 1 called'
12+
}
13+
14+
fn2() {
15+
printf '%s\n' 'Function 2 called'
16+
}
17+
18+
core.trap_add 'fn1' SIGINT
19+
core.trap_add 'fn2' SIGINT
20+
core.trap_remove 'fn2' SIGINT
21+
22+
read -r

pkg/lib/public/bash-core.sh

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# shellcheck shell=bash
22

33
core.init() {
4+
# TODO: way below should error if any variables are not set
5+
46
if [ ${___global_bash_core_has_init__+x} ]; then
57
return
68
fi
@@ -10,10 +12,9 @@ core.init() {
1012
declare -ag ___global_shopt_stack___=()
1113
}
1214

13-
# @description Get version of the package, from the point of the
14-
# callsite. In other words, it returns the version of the package
15-
# that has the file containing the direct caller of this function
16-
# @set REPLY The full path to the directory
15+
# @description Get version of the package, from the point of the callsite. In other words, it
16+
# returns the version of the package that has the file containing the direct caller of this
17+
# function @set REPLY The full path to the directory
1718
core.get_package_dir() {
1819
# local start_dir="${1:-"${BASH_SOURCE[1]}"}"
1920

@@ -30,13 +31,20 @@ core.trap_add() {
3031
local signal_spec="$2"
3132

3233
# validation
34+
if [ -z "$function" ]; then
35+
printf '%s\n' "Error: core.trap_add: First argument cannot be empty"
36+
return 1
37+
fi
38+
if [ -z "$signal_spec" ]; then
39+
printf '%s\n' "Error: core.trap_add: Second argument cannot be empty"
40+
return 1
41+
fi
3342
local regex='^[0-9]+$'
3443
if [[ "$signal_spec" =~ $regex ]]; then
3544
printf '%s\n' "Error: core.trap_add: Passing numbers for the signal specs is prohibited"
3645
return 1
3746
fi; unset regex
3847
signal_spec="${signal_spec#SIG}"
39-
4048
if ! declare -f "$function" &>/dev/null; then
4149
printf '%s\n' "Error: core.trap_add: Function '$function' not defined" >&2
4250
return 1
@@ -46,21 +54,14 @@ core.trap_add() {
4654
___global_trap_table___["$signal_spec"]="${___global_trap_table___[$signal_spec]}"$'\x1C'"$function"
4755

4856
local global_trap_handler_name=
49-
printf -v global_trap_handler_name '%q' "__global_trap_${signal_spec}_handler___"
50-
51-
eval 'if ! '"$global_trap_handler_name"'() {
52-
local trap_handlers= trap_handler=
53-
IFS=$'"'\x1C'"' read -ra trap_handlers <<< "${___global_trap_table___[$signal_spec]}"
54-
for trap_func in "${trap_handlers[@]}"; do
55-
if declare -f "$trap_handler"; then
56-
:
57-
else
58-
printf "%s\n" "Warn: core.trap_add: Function '"'\$function'"' registered for signal '"'\$signal_spec'"' no longer exists" >&2
59-
fi
60-
done
61-
}; then
62-
false
63-
fi'
57+
printf -v global_trap_handler_name '%q' "___global_trap_${signal_spec}_handler___"
58+
59+
if ! eval "$global_trap_handler_name() {
60+
core.trap_common_global_handler "$signal_spec"
61+
}"; then
62+
printf '%s\n' "Error: core.trap_add: Could not eval function"
63+
return 1
64+
fi
6465
trap "$global_trap_handler_name" "$signal_spec"
6566
}
6667

@@ -69,13 +70,20 @@ core.trap_remove() {
6970
local signal_spec="$2"
7071

7172
# validation
73+
if [ -z "$function" ]; then
74+
printf '%s\n' "Error: core.trap_add: First argument cannot be empty"
75+
return 1
76+
fi
77+
if [ -z "$signal_spec" ]; then
78+
printf '%s\n' "Error: core.trap_add: Second argument cannot be empty"
79+
return 1
80+
fi
7281
local regex='^[0-9]+$'
7382
if [[ "$signal_spec" =~ $regex ]]; then
7483
printf '%s\n' "Error: core.trap_add: Passing numbers for the signal specs is prohibited"
7584
return 1
7685
fi; unset regex
7786
signal_spec="${signal_spec#SIG}"
78-
7987
if ! declare -f "$function" &>/dev/null; then
8088
printf '%s\n' "Error: core.trap_add: Function '$function' not defined" >&2
8189
return 1

pkg/lib/util/util.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# shellcheck shell=bash
2+
3+
core.trap_common_global_handler() {
4+
local signal_spec="$1"
5+
6+
local trap_handlers=
7+
IFS=$'\x1C' read -ra trap_handlers <<< "${___global_trap_table___[$signal_spec]}"
8+
9+
local trap_handler=
10+
for trap_handler in "${trap_handlers[@]}"; do
11+
if [ -z "$trap_handler" ]; then
12+
continue
13+
fi
14+
15+
if declare -f "$trap_handler" &>/dev/null; then
16+
"$trap_handler"
17+
else
18+
printf "%s\n" "Warn: core.trap_add: Function '$trap_handler' registered for signal '$signal_spec' no longer exists. Skipping" >&2
19+
fi
20+
done; unset trap_func
21+
}

0 commit comments

Comments
 (0)