summaryrefslogtreecommitdiff
path: root/bos-namespaces.sh
blob: 02f3df28edef3f91c2d7184f320455ce1b0dc04d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!bash 
## namespace handling 
 
function bos-namespaces/encode-into() {
    local -n result="$1"
    local string="$2"
    local idx char tmp
 
    result=''
    for (( idx=0 ; idx < "${#string}" ; ++idx )); do
        char="${string:$idx:1}"
        case "$char" in
            [0-9A-Za-z]) tmp="$char";;
            *) printf -v tmp _%02x "'$char"
        esac
        result+="$tmp"
    done
}
 
function bos-namespaces/store-scalar-for-into() {
    local -n result="$1"
    local name; bos-namespaces/encode-into name "bos_${3}_${2}"
    declare -g "$name"
    result="$name"
}
 
function bos-namespaces/store-array-for-into() {
    local -n result="$1"
    local name; bos-namespaces/encode-into name "bos_${3}_${2}"
    declare -ga "$name"
    result="$name"
}
 
function bos-namespaces/store-dict-for-into() {
    local -n result="$1"
    local name; bos-namespaces/encode-into name "bos_${3}_${2}"
    declare -gA "$name"
    result="$name"
}
 
declare -a bos_namespace_stack
 
function bos-namespaces/current-namespace-into() {
    local -n bos_namespace_current_namespace_result="$1"
    local IFS=/
    bos_namespace_current_namespace_result="${bos_namespace_stack[*]}"
}
 
function bos-namespaces/push() {
    bos_namespace_stack+=( "$1" )
}
 
function bos-namespaces/pop() {
    unset "bos_namespace_stack[-1]"
}
 
# save all currently-visible functions in an associative array 
function bos-namespaces/save-funcs() {
    local namespace; bos-namespaces/current-namespace-into namespace
    local ns_store; bos-namespaces/store-dict-for-into ns_store saved_funcs "$namespace"
    local -n saved_funcs="$ns_store"
    local _ funcname
 
    while read -r _ _ funcname; do
        saved_funcs+=( ["$funcname"]="$(declare -pf "$funcname")" )
    done < <( declare -pF )
 
    return 0
}
 
# diff all currently-visible function against the saved ones, list the 
# ones that differ 
function bos-namespaces/list-new-funcs-into() {
    local -n result="$1"
    local namespace; bos-namespaces/current-namespace-into namespace
    local ns_store; bos-namespaces/store-dict-for-into ns_store saved_funcs "$namespace"
    local -n saved_funcs="$ns_store"
    local _ funcname new_function
 
    while read -r _ _ funcname; do
        # if a function already belong to this namespace, it's not new 
        if [[ "$funcname" == "$namespace"/* ]]; then
            continue
        fi
 
        new_function="$(declare -pf "$funcname")"
        if [[ "$new_function" != "${saved_funcs["$funcname"]}" ]]; then
            result+=( "${funcname}" )
        fi
    done < <( declare -pF )
 
    return 0
}
 
# rename a bunch of functions by prepending a prefix; restore the 
# saved function of the same name, if it exists 
function bos-namespaces/qualify-funcs() {
    local namespace; bos-namespaces/current-namespace-into namespace
    local ns_store; bos-namespaces/store-dict-for-into ns_store saved_funcs "$namespace"
    local -n saved_funcs="$ns_store"
    local _ funcname new_function
 
    for funcname in "$@"; do
        new_function="$(declare -pf "$funcname")"
        eval "${namespace}/${new_function}"
        if [[ -n "${saved_funcs["$funcname"]}" ]]; then
            eval "${saved_funcs["$funcname"]}"
        else
            unset -f "$funcname"
        fi
    done
 
    return 0
}