diff --git a/src/ns.sh b/src/ns.sh new file mode 100644 index 0000000..947ec91 --- /dev/null +++ b/src/ns.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# Namespace support +# +# Copyright (C) 2014 Mike Gerwitz +# +# This file is part of pkgsh. +# +# pkgsh is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +## + +[ -z $__PKGSH_INC_NS ] || return +__PKGSH_INC_NS=1 + + +## +# Apply to current namespace +# +# Extracts the namespace `ns` of the function in which this application is +# invoked and calls `$ns::$cmd`, passing all arguments 2..N, where N is the +# number of arguments passed to `@::`. +# +# If no namespace is found, then $cmd is invoked as-is, without any +# namespace prefix. +# +function @:: +{ + local -r cmd="$1" fn="${FUNCNAME[1]}" + local -r ns="${fn%::*}" + shift + + if [[ "$ns" == "$fn" ]]; then + "$cmd" "$@" + else + "$ns::$cmd" "$@" + fi +} + diff --git a/test/ns/test-@::-multi.sh b/test/ns/test-@::-multi.sh new file mode 100644 index 0000000..71163fe --- /dev/null +++ b/test/ns/test-@::-multi.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# Tests current namespace application on nested namespaces +# +# Copyright (C) 2014 Mike Gerwitz +# +# This file is part of pkgsh. +# +# pkgsh is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# `@::` should take the full namespace path of any arbitrary depth, not just +# the first namespace (up to the first `::`). +## + +source src/ns.sh + +declare -a expected=("o n e" two three) +declare -a given=() + + +# attempts to invoke `next` within the same namespace +foo::bar::baz::try() +{ + # SUT + @:: next "$@" +} + +foo::bar::baz::next() +{ + given=("$@") +} + + +foo::bar::baz::try "${expected[@]}" + +set -- "${given[@]}" +test $# -eq "${#expected[@]}" + +# all arguments should be passed, properly quoted +declare -i i=0 +while true; do + test "$1" == "${expected[i]}" + shift || break + ((++i)) +done + diff --git a/test/ns/test-@::-nons.sh b/test/ns/test-@::-nons.sh new file mode 100644 index 0000000..07b5988 --- /dev/null +++ b/test/ns/test-@::-nons.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# Tests current namespace application on absent namespace +# +# Copyright (C) 2014 Mike Gerwitz +# +# This file is part of pkgsh. +# +# pkgsh is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# If no namespace exists on the function in which `@::` is used, then the +# command should be invoked normally, without any namespace prefix. +## + +source src/ns.sh + +declare -a expected=("o n e" two three) +declare -a given=() + + +# attempts to invoke `next` within the same namespace +try() +{ + # SUT + @:: next "$@" +} + +next() +{ + given=("$@") +} + + +try "${expected[@]}" + +set -- "${given[@]}" +test $# -eq "${#expected[@]}" + +# all arguments should be passed, properly quoted +declare -i i=0 +while true; do + test "$1" == "${expected[i]}" + shift || break + ((++i)) +done +