20
libshlist/LICENSE
Normal file
20
libshlist/LICENSE
Normal file
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017-2018 Thomas "Ventto" Venriès <thomas.venries@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
111
libshlist/README.md
Normal file
111
libshlist/README.md
Normal file
@@ -0,0 +1,111 @@
|
||||
POSIX Shell List
|
||||
================
|
||||
|
||||
[](https://github.com/Ventto/posix-shell-list/blob/master/LICENSE)
|
||||
|
||||
*"This is a POSIX Shell list implementation."*
|
||||
|
||||
## Perks
|
||||
|
||||
* [x] **No requirement**: POSIX-compliant
|
||||
* [x] **Lightweight**: ~100 lines
|
||||
* [x] **Extra**: Additional functions to fit your needs
|
||||
* [x] **Useful**: No internal independency
|
||||
* [x] **Both**: Safe and unsafe (passing argument by reference) versions
|
||||
|
||||
# Installation
|
||||
|
||||
* Download it:
|
||||
|
||||
```bash
|
||||
$ wget https://raw.githubusercontent.com/Ventto/posix-shell-list/master/liblist.sh
|
||||
```
|
||||
|
||||
* Source the library for including the functions into your Shell script:
|
||||
|
||||
```bash
|
||||
. liblist.sh (or)
|
||||
. liblist_unsafe.sh
|
||||
```
|
||||
|
||||
* Each function is independent. So you can copy some functions into your
|
||||
script without sourcing
|
||||
|
||||
# Functions
|
||||
|
||||
The whole function documentation is in the following library scripts:
|
||||
|
||||
* `liblist.sh`: the variable assignation is required for conserving changes
|
||||
* `liblist_unsafe.sh`: uses `eval` special shell builtin for passing argument
|
||||
by reference and set the list variable
|
||||
|
||||
The following list enumerates all available functions:
|
||||
|
||||
```
|
||||
SAFE | UNSAFE
|
||||
____________________________________|_______________________________
|
||||
list <elt> <elt> ... | list <elt> <elt> ...
|
||||
list_back <lst> | list_back <lst>
|
||||
list_contains <elt> <lst> | list_contains <lst> <elt>
|
||||
list_count <elt> <lst> | list_count <lst> <elt>
|
||||
list_empty <lst> | list_empty <lst>
|
||||
list_erase <elt> <lst> | list_erase <lst> <elt>
|
||||
list_erase_from <index> <lst> | list_erase_from <lst> <index>
|
||||
list_erase_range <from> <to> <lst> | list_erase_range <lst> <from> <to>
|
||||
list_eraseat <index> <lst> | list_eraseat <lst> <index>
|
||||
list_extract <from> <to> <lst> | list_extract <lst> <from> <to>
|
||||
list_front <lst> | list_front <lst>
|
||||
list_get <index> <lst> | list_get <lst> <index>
|
||||
list_indexof <elt> <lst> | list_indexof <lst> <elt>
|
||||
list_insert <elt> <index> <lst> | list_insert <lst> <elt> <index>
|
||||
list_maps <func> <lst> | list_maps <lst> <func>
|
||||
list_pop_back <lst> | list_pop_back <lst>
|
||||
list_pop_front <lst> | list_pop_front <lst>
|
||||
list_push_back <elt> <lst> | list_push_back <lst> <elt>
|
||||
list_push_front <elt> <lst> | list_push_front <lst> <elt>
|
||||
list_remove <elt> <lst> | list_remove <lst> <elt>
|
||||
list_replace <new> <old> <lst> | list_replace <lst> <new> <old>
|
||||
list_reverse <lst> | list_reverse <lst>
|
||||
list_set <elt> <index> <lst> | list_set <lst> <elt> <index>
|
||||
list_size <lst> | list_size <lst>
|
||||
list_sort <lst> | list_sort <lst>
|
||||
list_sort_reverse <lst> | list_sort_reverse <lst>
|
||||
```
|
||||
|
||||
# Example
|
||||
|
||||
Scripts in `test/` offer an exhaustive usage of both libraries.
|
||||
|
||||
* Quick start (safe version):
|
||||
|
||||
```bash
|
||||
lst="$(list 'A' 'B' 'C')"
|
||||
lst="$(list_sort "$lst")" # { C, B, A }
|
||||
|
||||
if list_empty "$lst"; then
|
||||
echo 'The list is empty.'
|
||||
fi
|
||||
|
||||
index="$(list_indexof 'D' "$lst")" # '', empty string
|
||||
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo 'Element not found.'
|
||||
fi
|
||||
```
|
||||
|
||||
* Quick start (unsafe version):
|
||||
|
||||
```bash
|
||||
lst="$(list 'A' 'B' 'C')"
|
||||
list_sort lst # { C, B, A }
|
||||
|
||||
if list_empty lst; then
|
||||
echo 'The list is empty.'
|
||||
fi
|
||||
|
||||
index="$(list_indexof lst 'D')" # '', empty string
|
||||
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo 'Element not found.'
|
||||
fi
|
||||
```
|
1
libshlist/_git
Normal file
1
libshlist/_git
Normal file
@@ -0,0 +1 @@
|
||||
gitdir: ../.git/modules/libshlist
|
271
libshlist/liblist.sh
Normal file
271
libshlist/liblist.sh
Normal file
@@ -0,0 +1,271 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2017-2018 Thomas "Ventto" Venriès <thomas.venries@gmail.com>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
# this software and associated documentation files (the "Software"), to deal in
|
||||
# the Software without restriction, including without limitation the rights to
|
||||
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
# the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
##
|
||||
# @brief Return a list from argument strings
|
||||
# @usage list <elt> <elt> ...
|
||||
# @print The created list
|
||||
#
|
||||
list () {
|
||||
for e; do [ -n "$e" ] && echo "$e"; done
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Prints the number of elements in the list
|
||||
# @usage list_size <lst>
|
||||
# @print The size of the list as positive integer
|
||||
#
|
||||
list_size () {
|
||||
if [ -z "$1" ]; then echo '0'; else echo "$@" | wc -l; fi
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Returns whether the list is empty(1) or not(0)
|
||||
# @usage list_empty <lst>
|
||||
# @return The exit code of the command
|
||||
#
|
||||
list_empty () {
|
||||
test -z "$1"
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Adds a new element at the beginning of the list
|
||||
# @usage list_push_front <elt> <lst>
|
||||
# @print The list result
|
||||
#
|
||||
list_push_front () {
|
||||
test "$#" -ne 2 && return 1
|
||||
if [ "$2" = '' ]; then echo "$1"; else printf '%s\n%s' "$1" "$2"; fi
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Adds a new element at the end of the list
|
||||
# @usage list_push_back <elt> <lst>
|
||||
# @print The list result
|
||||
#
|
||||
list_push_back () {
|
||||
test "$#" -ne 2 && return 1
|
||||
if [ "$2" = '' ]; then echo "$1"; else printf '%s\n%s' "$2" "$1"; fi
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Inserts new elements in the list before a specified position
|
||||
# @usage list_insert <elt> <index> <lst>
|
||||
# @print The list result
|
||||
#
|
||||
list_insert () {
|
||||
test "$#" -ne 3 && return 1
|
||||
i="$2"; [ "$i" != '$' ] && i=$((i+1)); echo "$3" | sed "${i}i${1}"
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Modifies an element from the list at a specified position
|
||||
# @usage list_set <elt> <index> <lst>
|
||||
# @print The list result
|
||||
#
|
||||
list_set () {
|
||||
test "$#" -ne 3 && return 1
|
||||
i="$2"; i=$((i+1)); echo "$3" | sed -e "${i}s/.*/$1/"
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Extracts a range of elements from the list between two specified
|
||||
# positions
|
||||
# @usage list_extract <from_index> <to_index> <lst>
|
||||
# @print The list result
|
||||
#
|
||||
list_extract () {
|
||||
test "$#" -ne 3 && return 1
|
||||
i="$1"; j="$2"; i=$((i+1)); j=$((j+1)); echo "$3" | sed -n "${i},${j}p"
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Replaces all elements from the list with a specified element
|
||||
# @usage list_replace <new_elt> <old_elt> <lst>
|
||||
# @print The list result
|
||||
#
|
||||
list_replace () {
|
||||
test "$#" -ne 3 && return 1; echo "$3" | sed -e "s/^$1$/$2/g"
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Prints the element at a specified position
|
||||
# @usage list_get <index> <lst>
|
||||
# @print The element found
|
||||
#
|
||||
list_get () {
|
||||
test "$#" -ne 2 && return 1; i="$1"; i=$((i+1)); echo "$2" | sed -n "${i}p"
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Prints the head of the list
|
||||
# @usage list_front <lst>
|
||||
# @print The element found
|
||||
#
|
||||
list_front () {
|
||||
test "$#" -ne 1 && return 1; echo "$@" | sed -n '1p'
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Prints the queue of the list
|
||||
# @usage list_back <lst>
|
||||
# @print The element found
|
||||
#
|
||||
list_back () {
|
||||
test "$#" -ne 1 && return 1; echo "$@" | sed -n '$p'
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Removes the first-hit element from a list
|
||||
# @usage list_erase <elt> <lst>
|
||||
# @print The list result
|
||||
#
|
||||
list_erase () {
|
||||
test "$#" -ne 2 && return 1; echo "$2" | sed -e "0,/^$1$/ s///" -e '/^$/d'
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Removes a range of elements from a list between two specified
|
||||
# positions
|
||||
# @usage list_erase_range <from_index> <to_index> <lst>
|
||||
# @print The list result
|
||||
#
|
||||
list_erase_range () {
|
||||
test "$#" -ne 3 && return 1
|
||||
i="$1"; j="$2"; i=$((i+1)); j=$((j+1)); echo "$3" | sed "${i},${j}d"
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Removes all elements from a specified position
|
||||
# @usage list_erase_from <index> <lst>
|
||||
# @print The list result
|
||||
#
|
||||
list_erase_from () {
|
||||
test "$#" -ne 2 && return 1; i="$1"; i=$((i+1)); echo "$2" | sed "${i},\$d"
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Removes the element at a specified position
|
||||
# @usage list_eraseat <index> <lst>
|
||||
# @print The list result
|
||||
#
|
||||
list_eraseat () {
|
||||
test "$#" -ne 2 && return 1; i="$1"; i=$((i+1)); echo "$2" | sed "${i}d"
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Removes all the elements from the list, which are equal to given
|
||||
# element
|
||||
# @usage list_remove <elt> <lst>
|
||||
# @print The list result
|
||||
#
|
||||
list_remove () {
|
||||
test "$#" -ne 2 && return 1; echo "$2" | sed -e "/^$1$/d"
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Removes the first element of the list
|
||||
# @usage list_pop_front <lst>
|
||||
# @print The list result
|
||||
#
|
||||
list_pop_front () {
|
||||
test "$#" -ne 1 && return 1; echo "$1" | sed '1d'
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Removes the last element of the list
|
||||
# @usage list_pop_back <lst>
|
||||
# @print The list result
|
||||
#
|
||||
list_pop_back () {
|
||||
test "$#" -ne 1 && return 1; echo "$1" | sed '$d'
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Prints the index of a specified element
|
||||
# @usage list_indexof <elt> <lst>
|
||||
# @print The index or empty string if the element is not found
|
||||
#
|
||||
list_indexof () {
|
||||
test "$#" -ne 2 && return 1; i=0
|
||||
for e in $2; do
|
||||
[ "$e" = "$1" ] && { echo "$i"; return 0; }; i=$((i+1));
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Returns whether the list contains a specified element(0) or not(1)
|
||||
# @usage list_contains <elt> <lst>
|
||||
# @return 0 or 1
|
||||
#
|
||||
list_contains () {
|
||||
test "$#" -ne 2 && return 1
|
||||
for e in $2; do [ "$e" = "$1" ] && return 0; done; return 1
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Counts the number of a specified element in the list
|
||||
# @usage list_count <elt> <lst>
|
||||
# @print The number of elements as positive integer
|
||||
#
|
||||
list_count () {
|
||||
test "$#" -ne 2 && return 1
|
||||
i=0; for e in $2; do [ "$e" = "$1" ] && { i=$((i+1)); }; done; echo "$i"
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Maps every element of the list
|
||||
# @usage list_maps <func> <lst>
|
||||
# @print The list result
|
||||
#
|
||||
list_map () {
|
||||
test "$#" -ne 2 && return 1; for e in $2; do eval "$1 $e"; done
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Reverses the list
|
||||
# @usage list_reverse <lst>
|
||||
# @print The list result
|
||||
#
|
||||
list_reverse() {
|
||||
test "$#" -ne 1 && return 1; echo "$1" | sed '1!x;H;1h;$!d;g'
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Sorts the list
|
||||
# @usage list_sort <lst>
|
||||
# @print The list result
|
||||
#
|
||||
list_sort () {
|
||||
test "$#" -ne 1 && return 1; echo "$1" | sort -n
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Sorts and reverses the sense of the list
|
||||
# @usage list_sort_reverse <lst>
|
||||
# @print The list result
|
||||
#
|
||||
list_sort_reverse () {
|
||||
test "$#" -ne 1 && return 1; echo "$1" | sort -nr
|
||||
}
|
286
libshlist/liblist_unsafe.sh
Normal file
286
libshlist/liblist_unsafe.sh
Normal file
@@ -0,0 +1,286 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2017-2018 Thomas "Ventto" Venriès <thomas.venries@gmail.com>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
# this software and associated documentation files (the "Software"), to deal in
|
||||
# the Software without restriction, including without limitation the rights to
|
||||
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
# the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
##
|
||||
# @brief Prints a list from arguments
|
||||
# @usage list <elt> <elt> ...
|
||||
# @print The list result
|
||||
#
|
||||
list () {
|
||||
for e; do [ -n "$e" ] && echo "$e"; done
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Prints the number of elements in the list
|
||||
# @usage list_size <lst>
|
||||
# @print The size of the list as positive integer
|
||||
#
|
||||
list_size () {
|
||||
test "$#" -ne 1 && { echo "0"; return; }
|
||||
eval "test -n \"\$$1\"" && { eval "echo \"\$$1\" | wc -l"; return; }
|
||||
echo '0'
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Returns whether the list is empty(1) or not(0)
|
||||
# @usage list_empty <lst>
|
||||
# @return 0 or 1
|
||||
#
|
||||
list_empty () {
|
||||
eval "test -z \"\$$1\""
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Adds a new element at the beginning of the list
|
||||
# @usage list_push_front <lst> <elt>
|
||||
# @out Set the variable passed by reference
|
||||
#
|
||||
list_push_front () {
|
||||
test "$#" -ne 2 && return 1
|
||||
eval "test -n \"\$$1\"" || { eval "$1='$2'"; return; }
|
||||
eval "$1=\"\$(printf '%s\n%s' '$2' \"\$$1\")\"";
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Adds a new element at the end of the list
|
||||
# @usage list_push_back <lst> <elt>
|
||||
# @out Set the variable passed by reference
|
||||
#
|
||||
list_push_back () {
|
||||
test "$#" -ne 2 && return 1
|
||||
eval "test -n \"\$$1\"" || { eval "$1='$2'"; return; }
|
||||
eval "test -n \"\$$1\"" || { eval "$1='$2'"; return; }
|
||||
eval "$1=\"\$(printf '%s\n%s' \"\$$1\" '$2')\"";
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Inserts new elements in the list before a specified position
|
||||
# @usage list_insert <lst> <elt> <index>
|
||||
# @out Set the variable passed by reference
|
||||
#
|
||||
list_insert () {
|
||||
test "$#" -ne 3 && return 1; i="$3"; [ "$i" != '$' ] && i=$((i+1))
|
||||
eval "$1=\"\$(echo \"\$$1\" | sed \"${i}i${2}\")\""
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Modifies an element from the list at a specified position
|
||||
# @usage list_set <lst> <elt> <index>
|
||||
# @out Set the variable passed by reference
|
||||
#
|
||||
list_set () {
|
||||
test "$#" -ne 3 && return 1
|
||||
i="$3"; i=$((i+1)); eval "$1=\"\$(echo \"\$$1\" | sed \"${i}s/.*/$2/\")\""
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Extracts a range of elements from the list between two specified
|
||||
# positions
|
||||
# @usage list_extract <lst> <from_index> <to_index>
|
||||
# @out Set the variable passed by reference
|
||||
#
|
||||
list_extract () {
|
||||
test "$#" -ne 3 && return 1; i="$2"; j="$3"; i=$((i+1)); j=$((j+1))
|
||||
eval "$1=\"\$(echo \"\$$1\" | sed -n \"${i},${j}p\")\""
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Replaces all elements from the list with a specified element
|
||||
# @usage list_replace <lst> <old_elt> <new_elt>
|
||||
# @out Set the variable passed by reference
|
||||
#
|
||||
list_replace () {
|
||||
test "$#" -ne 3 && return 1
|
||||
eval "$1=\"\$(echo \"\$$1\" | sed -e \"s/^$2$/$3/g\")\""
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Prints the element at a specified position
|
||||
# @usage list_get <lst> <index>
|
||||
# @print The element found
|
||||
#
|
||||
list_get () {
|
||||
test "$#" -ne 2 && return 1; i="$2"; i=$((i+1));
|
||||
eval "echo \"\$$1\" | sed -n \"${i}p\""
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Prints the head of the list
|
||||
# @usage list_front <lst>
|
||||
# @print The element found
|
||||
#
|
||||
list_front () {
|
||||
test "$#" -ne 1 && return 1; eval "echo \"\$$1\" | sed -n '1p'"
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Prints the queue of the list
|
||||
# @usage list_back <lst>
|
||||
# @print The element found
|
||||
#
|
||||
list_back () {
|
||||
test "$#" -ne 1 && return 1; eval "echo \"\$$1\" | sed -n '\$p'"
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Removes the first-hit element from a list
|
||||
# @usage list_erase <lst> <elt>
|
||||
# @out Set the variable passed by reference
|
||||
#
|
||||
list_erase () {
|
||||
test "$#" -ne 2 && return 1
|
||||
eval "$1=\"\$(echo \"\$$1\" | sed -e \"0,/^$2$/ s///\" -e '/^$/d')\""
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Removes a range of elements from a list between two specified
|
||||
# positions
|
||||
# @usage list_erase_range <lst> <from_index> <to_index>
|
||||
# @out Set the variable passed by reference
|
||||
#
|
||||
list_erase_range () {
|
||||
test "$#" -ne 3 && return 1
|
||||
i="$2"; j="$3"; i=$((i+1)); j=$((j+1));
|
||||
eval "$1=\"\$(echo \"\$$1\" | sed \"${i},${j}d\")\""
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Removes all elements from a specified position
|
||||
# @usage list_erase_from <lst> <index>
|
||||
# @out Set the variable passed by reference
|
||||
#
|
||||
list_erase_from () {
|
||||
test "$#" -ne 2 && return 1
|
||||
i="$2"; i=$((i+1)); eval "$1=\"\$(echo \"\$$1\" | sed \"${i},\\\$d\")\""
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Removes the element at a specified position
|
||||
# @usage list_eraseat <lst> <index>
|
||||
# @out Set the variable passed by reference
|
||||
#
|
||||
list_eraseat () {
|
||||
test "$#" -ne 2 && return 1
|
||||
i="$2"; i=$((i+1)); eval "$1=\"\$(echo \"\$$1\" | sed \"${i}d\")\""
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Removes all the elements from the list, which are equal to given
|
||||
# element
|
||||
# @usage list_remove <lst> <elt>
|
||||
# @out Set the variable passed by reference
|
||||
#
|
||||
list_remove () {
|
||||
test "$#" -ne 2 && return 1
|
||||
eval "$1=\"\$(echo \"\$$1\" | sed -e \"/^$2$/d\")\""
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Removes the first element of the list
|
||||
# @usage list_pop_front <lst>
|
||||
# @out Set the variable passed by reference
|
||||
#
|
||||
list_pop_front () {
|
||||
test "$#" -ne 1 && return 1; eval "$1=\"\$(echo \"\$$1\" | sed '1d')\""
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Removes the last element of the list
|
||||
# @usage list_pop_back <lst>
|
||||
# @out Set the variable passed by reference
|
||||
#
|
||||
list_pop_back () {
|
||||
test "$#" -ne 1 && return 1; eval "$1=\"\$(echo \"\$$1\" | sed '\$d')\""
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Prints the index of a specified element
|
||||
# @usage list_indexof <lst> <elt>
|
||||
# @print positive integer or -1 if not found
|
||||
#
|
||||
list_indexof () {
|
||||
test "$#" -ne 2 && return 1; i=0
|
||||
eval "for e in \$$1; do
|
||||
[ \"\$e\" = '$2' ] && { echo \"\$i\"; return 0; }; i=\$((i+1));
|
||||
done"
|
||||
return 1
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Returns whether the list contains a specified element(0) or not(1)
|
||||
# @usage list_contains <lst> <elt>
|
||||
# @return 0 or 1
|
||||
#
|
||||
list_contains () {
|
||||
test "$#" -ne 2 && return 1
|
||||
eval "for e in \$$1; do [ \"\$e\" = '$2' ] && return 0; done; return 1"
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Prints the number of a specified element in the list
|
||||
# @usage list_count <lst> <elt>
|
||||
# @print The number of elements as positive integer
|
||||
#
|
||||
list_count () {
|
||||
test "$#" -ne 2 && { echo '0'; return; }
|
||||
eval "i=0; for e in \$$1; do [ \"\$e\" = '$2' ] && { i=\$((i+1)); };done;"
|
||||
echo "$i"
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Maps every element of the list
|
||||
# @usage list_maps <lst> <func>
|
||||
# @out Set the variable passed by reference
|
||||
#
|
||||
list_map () {
|
||||
test "$#" -ne 2 && return 1
|
||||
eval "$1=\"\$(for e in \$$1; do eval \"$2 \$e\"; done)\""
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Reverses the list
|
||||
# @usage list_reverse <lst>
|
||||
# @out Set the variable passed by reference
|
||||
#
|
||||
list_reverse() {
|
||||
test "$#" -ne 1 && return 1
|
||||
eval "$1=\"\$(echo \"\$$1\" | sed '1!x;H;1h;\$!d;g')\""
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Sorts the list
|
||||
# @usage list_sort <lst>
|
||||
# @out Set the variable passed by reference
|
||||
#
|
||||
list_sort () {
|
||||
test "$#" -ne 1 && return 1; eval "$1=\"\$(echo \"\$$1\" | sort -n)\""
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Sorts and reverses the sense of the list
|
||||
# @usage list_sort_reverse <lst>
|
||||
# @out Set the variable passed by reference
|
||||
#
|
||||
list_sort_reverse () {
|
||||
test "$#" -ne 1 && return 1; eval "$1=\"\$(echo \"\$$1\" | sort -nr)\""
|
||||
}
|
85
libshlist/test/test.sh
Normal file
85
libshlist/test/test.sh
Normal file
@@ -0,0 +1,85 @@
|
||||
#!/bin/sh
|
||||
|
||||
. ./liblist.sh
|
||||
|
||||
print_list () {
|
||||
echo '==========List============'
|
||||
printf "%s\n" "$1"
|
||||
echo '--------------------------'
|
||||
printf "Size: %s\t\n\n" "$(list_size "$1")"
|
||||
}
|
||||
|
||||
Test_Delete () {
|
||||
lst="$(list '1' '12' '23' \
|
||||
'33' '215' '-456' \
|
||||
'1236' '1' '12' \
|
||||
'3' '-3' '33' \
|
||||
'1' '12' '-55' \
|
||||
'123' '-1002' '-1' )"
|
||||
|
||||
printf "TEST: Deletion\n\n"
|
||||
echo 'test: Initialization'; print_list "$lst"
|
||||
|
||||
lst="$(list_remove '1' "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_erase '33' "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_eraseat '3' "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_pop_front "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_pop_back "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_erase_from '8' "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_erase_range '1' '2' "$lst")"; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_erase_range '0' '0' "$lst")"; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_extract '1' '3' "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_extract '1' '30' "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_extract '1' '0' "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
}
|
||||
|
||||
Test_Addition () {
|
||||
lst=
|
||||
|
||||
printf "TEST: Addition\n\n"
|
||||
echo 'test: Initialization'; print_list "$lst"
|
||||
|
||||
lst="$(list_push_front '12' "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_push_back '33' "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_push_front '1' "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_insert '23' '2' "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_push_back '215' "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
}
|
||||
|
||||
inc () { i="$1"; i=$((i+1)); echo "${i}"; }
|
||||
Test_Set() {
|
||||
lst="$(list '1' '12' '23' \
|
||||
'33' '215' '-456' \
|
||||
'1236' '1' '12' )"
|
||||
|
||||
printf "TEST: Set\n\n"
|
||||
echo 'test: Initialization'; print_list "$lst"
|
||||
|
||||
lst="$(list_reverse "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_sort "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_sort_reverse "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_map inc "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_replace '2' '999' "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_set '999' '3' "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
lst="$(list_set '999' '6' "$lst")" ; echo 'test:' ; print_list "$lst"
|
||||
}
|
||||
|
||||
Test_Get() {
|
||||
lst="$(list '1' '12' '23' \
|
||||
'33' '215' '-456' \
|
||||
'1236' '1' '12' )"
|
||||
|
||||
printf "TEST: Get\n\n"
|
||||
echo 'test: Initialization'; print_list "$lst"
|
||||
|
||||
printf 'test: elt=' ; list_front "$lst"
|
||||
printf 'test: elt=' ; list_back "$lst"
|
||||
printf 'test: elt=' ; list_get '2' "$lst"
|
||||
printf 'test: index=' ; list_indexof '1' "$lst" | grep -E '^[0-9]+$' || echo
|
||||
printf 'test: index=' ; list_indexof '-456' "$lst" | grep -E '^[0-9]+$' || echo
|
||||
printf 'test: contains='; list_contains '1236' "$lst" && echo 'yes' || echo 'no'
|
||||
printf 'test: contains='; list_contains '999' "$lst" && echo 'yes' || echo 'no'
|
||||
printf 'test: count=' ; list_count '1' "$lst"
|
||||
printf 'test: count=' ; list_count '215' "$lst"
|
||||
printf 'test: empty=' ; list_empty "$lst" && echo 'yes' || echo 'no'
|
||||
}
|
210
libshlist/test/test_unsafe.sh
Normal file
210
libshlist/test/test_unsafe.sh
Normal file
@@ -0,0 +1,210 @@
|
||||
#!/bin/sh
|
||||
|
||||
. ./liblist_unsafe.sh
|
||||
|
||||
print_list () {
|
||||
echo '==========List============'
|
||||
eval "printf \"%s\\n\" \"\$$1\""
|
||||
echo '--------------------------'
|
||||
eval "printf \"Size: %s\t\n\n\" \"\$(list_size $1)\""
|
||||
}
|
||||
|
||||
Test_Delete () {
|
||||
lst="$(list '1' '12' '23' \
|
||||
'33' '215' '-456' \
|
||||
'1236' '1' '12' \
|
||||
'3' '-3' '33' \
|
||||
'1' '12' '-55' \
|
||||
'123' '-1002' '-1' )"
|
||||
|
||||
printf "TEST: Deletion\n\n"
|
||||
echo 'test: Initialization'; print_list lst
|
||||
|
||||
list_remove lst '1' ; echo 'test:' ; print_list lst
|
||||
list_erase lst '33' ; echo 'test:' ; print_list lst
|
||||
list_eraseat lst 3 ; echo 'test:' ; print_list lst
|
||||
list_pop_front lst ; echo 'test:' ; print_list lst
|
||||
list_pop_back lst ; echo 'test:' ; print_list lst
|
||||
list_erase_from lst 8 ; echo 'test:' ; print_list lst
|
||||
list_erase_range lst 1 2 ; echo 'test:' ; print_list lst
|
||||
list_erase_range lst 0 0 ; echo 'test:' ; print_list lst
|
||||
list_extract lst 1 3 ; echo 'test:' ; print_list lst
|
||||
list_extract lst 1 30 ; echo 'test:' ; print_list lst
|
||||
list_extract lst 1 0 ; echo 'test:' ; print_list lst
|
||||
}
|
||||
|
||||
Test_Addition () {
|
||||
lst=
|
||||
|
||||
printf "TEST: Addition\n\n"
|
||||
echo 'test: Initialization'; print_list lst
|
||||
|
||||
list_push_front lst '12' ; echo 'test:' ; print_list lst
|
||||
list_push_back lst '33' ; echo 'test:' ; print_list lst
|
||||
list_push_front lst '1' ; echo 'test:' ; print_list lst
|
||||
list_insert lst '23' 2 ; echo 'test:' ; print_list lst
|
||||
list_push_back lst '215' ; echo 'test:' ; print_list lst
|
||||
}
|
||||
|
||||
inc () { i="$1"; i=$((i+1)); echo "${i}"; }
|
||||
Test_Set() {
|
||||
lst="$(list '1' '12' '23' \
|
||||
'33' '215' '-456' \
|
||||
'1236' '1' '12' )"
|
||||
|
||||
printf "TEST: Set\n\n"
|
||||
echo 'test: Initialization'; print_list lst
|
||||
|
||||
list_reverse lst ; echo 'test:' ; print_list lst
|
||||
list_sort lst ; echo 'test:' ; print_list lst
|
||||
list_sort_reverse lst ; echo 'test:' ; print_list lst
|
||||
list_map lst inc ; echo 'test:' ; print_list lst
|
||||
list_replace lst '2' '999' ; echo 'test:' ; print_list lst
|
||||
list_set lst '999' 3 ; echo 'test:' ; print_list lst
|
||||
list_set lst '999' 6 ; echo 'test:' ; print_list lst
|
||||
}
|
||||
|
||||
Test_Get() {
|
||||
lst="$(list '1' '12' '23' \
|
||||
'33' '215' '-456' \
|
||||
'1236' '1' '12' )"
|
||||
|
||||
printf "TEST: Set\n\n"
|
||||
echo 'test: Initialization'; print_list lst
|
||||
|
||||
printf 'test: elt=' ; list_front lst
|
||||
printf 'test: elt=' ; list_back lst
|
||||
printf 'test: elt=' ; list_get lst 2
|
||||
printf 'test: index=' ; list_indexof lst '1' | grep -E '^[0-9]+$' || echo
|
||||
printf 'test: index=' ; list_indexof lst '-456' | grep -E '^[0-9]+$' || echo
|
||||
printf 'test: contains='; list_contains lst '1236' && echo 'yes' || echo 'no'
|
||||
printf 'test: contains='; list_contains lst '2' && echo 'yes' || echo 'no'
|
||||
printf 'test: count=' ; list_count lst '1'
|
||||
printf 'test: count=' ; list_count lst '215'
|
||||
printf 'test: empty=' ; list_empty lst && echo 'yes' || echo 'no'
|
||||
}
|
||||
|
||||
Test_Void() {
|
||||
lst="$(list '' '' '')"
|
||||
|
||||
printf "TEST: Void\n\n"
|
||||
echo 'test: Initialization'; print_list lst
|
||||
|
||||
printf 'test (void): empty=' ; list_empty lst && echo 'yes' || echo 'no'
|
||||
printf 'test (void): size=' ; list_size lst
|
||||
|
||||
list_reverse lst ; echo 'test:' ; print_list lst
|
||||
list_sort lst ; echo 'test:' ; print_list lst
|
||||
list_sort_reverse lst ; echo 'test:' ; print_list lst
|
||||
list_replace lst '2' '999' ; echo 'test:' ; print_list lst
|
||||
list_set lst '999' 3 ; echo 'test:' ; print_list lst
|
||||
list_set lst '999' 6 ; echo 'test:' ; print_list lst
|
||||
list_map lst inc ; echo 'test:' ; print_list lst
|
||||
list_remove lst '1' ; echo 'test:' ; print_list lst
|
||||
list_erase lst '33' ; echo 'test:' ; print_list lst
|
||||
list_eraseat lst 3 ; echo 'test:' ; print_list lst
|
||||
list_pop_front lst ; echo 'test:' ; print_list lst
|
||||
list_pop_back lst ; echo 'test:' ; print_list lst
|
||||
list_erase_from lst 8 ; echo 'test:' ; print_list lst
|
||||
list_erase_range lst 1 2 ; echo 'test:' ; print_list lst
|
||||
list_erase_range lst 0 0 ; echo 'test:' ; print_list lst
|
||||
list_extract lst 1 3 ; echo 'test:' ; print_list lst
|
||||
list_extract lst 1 30 ; echo 'test:' ; print_list lst
|
||||
list_extract lst 1 0 ; echo 'test:' ; print_list lst
|
||||
list_push_front lst '2' ; echo 'test:' ; print_list lst
|
||||
list_push_back lst '4' ; echo 'test:' ; print_list lst
|
||||
list_push_front lst '1' ; echo 'test:' ; print_list lst
|
||||
list_insert lst '3' 2 ; echo 'test:' ; print_list lst
|
||||
list_push_back lst '5' ; echo 'test:' ; print_list lst
|
||||
}
|
||||
|
||||
Test_BadArg() {
|
||||
lst="$1"
|
||||
printf "TEST: BadArg\n\n"
|
||||
echo 'test: Initialization'; print_list lst
|
||||
|
||||
list_push_front lst ; echo 'test:' ; print_list lst
|
||||
list_push_front '' ; echo 'test:' ; print_list lst
|
||||
list_push_front ; echo 'test:' ; print_list lst
|
||||
|
||||
list_push_back lst ; echo 'test:' ; print_list lst
|
||||
list_push_back '' ; echo 'test:' ; print_list lst
|
||||
list_push_back ; echo 'test:' ; print_list lst
|
||||
|
||||
list_insert lst '' ; echo 'test:' ; print_list lst
|
||||
list_insert lst ; echo 'test:' ; print_list lst
|
||||
list_insert 2 ; echo 'test:' ; print_list lst
|
||||
|
||||
list_reverse ; echo 'test:' ; print_list lst
|
||||
list_sort ; echo 'test:' ; print_list lst
|
||||
list_sort_reverse ; echo 'test:' ; print_list lst
|
||||
|
||||
list_replace lst '2' ; echo 'test:' ; print_list lst
|
||||
list_replace lst ; echo 'test:' ; print_list lst
|
||||
list_replace ; echo 'test:' ; print_list lst
|
||||
|
||||
list_set lst '999' ; echo 'test:' ; print_list lst
|
||||
list_set lst ; echo 'test:' ; print_list lst
|
||||
list_set ; echo 'test:' ; print_list lst
|
||||
|
||||
list_map lst ; echo 'test:' ; print_list lst
|
||||
list_map inc ; echo 'test:' ; print_list lst
|
||||
list_map ; echo 'test:' ; print_list lst
|
||||
|
||||
list_remove lst ; echo 'test:' ; print_list lst
|
||||
list_remove '1' ; echo 'test:' ; print_list lst
|
||||
list_remove ; echo 'test:' ; print_list lst
|
||||
|
||||
list_erase lst ; echo 'test:' ; print_list lst
|
||||
list_erase '33' ; echo 'test:' ; print_list lst
|
||||
list_erase ; echo 'test:' ; print_list lst
|
||||
|
||||
list_eraseat lst ; echo 'test:' ; print_list lst
|
||||
list_eraseat 3 ; echo 'test:' ; print_list lst
|
||||
list_eraseat ; echo 'test:' ; print_list lst
|
||||
|
||||
list_pop_front ; echo 'test:' ; print_list lst
|
||||
list_pop_back ; echo 'test:' ; print_list lst
|
||||
|
||||
list_erase_from lst ; echo 'test:' ; print_list lst
|
||||
list_erase_from 8 ; echo 'test:' ; print_list lst
|
||||
list_erase_from ; echo 'test:' ; print_list lst
|
||||
|
||||
list_erase_range lst 0 ; echo 'test:' ; print_list lst
|
||||
list_erase_range lst ; echo 'test:' ; print_list lst
|
||||
list_erase_range ; echo 'test:' ; print_list lst
|
||||
|
||||
list_extract 0 1 ; echo 'test:' ; print_list lst
|
||||
list_extract lst 1 ; echo 'test:' ; print_list lst
|
||||
list_extract lst ; echo 'test:' ; print_list lst
|
||||
list_extract ; echo 'test:' ; print_list lst
|
||||
|
||||
printf 'test: elt=' ; list_front || echo
|
||||
printf 'test: elt=' ; list_back || echo
|
||||
|
||||
printf 'test: elt=' ; list_get lst || echo
|
||||
printf 'test: elt=' ; list_get 2 || echo
|
||||
printf 'test: elt=' ; list_get || echo
|
||||
|
||||
printf 'test: index=' ; list_indexof lst | grep -E '^[0-9]+$' || echo
|
||||
printf 'test: index=' ; list_indexof '-456' | grep -E '^[0-9]+$' || echo
|
||||
printf 'test: index=' ; list_indexof | grep -E '^[0-9]+$' || echo
|
||||
|
||||
printf 'test: contains='; list_contains lst && echo 'yes' || echo 'no'
|
||||
printf 'test: contains='; list_contains '2' && echo 'yes' || echo 'no'
|
||||
printf 'test: contains='; list_contains && echo 'yes' || echo 'no'
|
||||
|
||||
printf 'test: count=' ; list_count lst
|
||||
printf 'test: count=' ; list_count '215'
|
||||
printf 'test: count=' ; list_count
|
||||
|
||||
printf 'test: empty=' ; list_empty && echo 'yes' || echo 'no'
|
||||
}
|
||||
|
||||
Test_VoidBadArg() {
|
||||
Test_BadArg "$(list '' '' '' '')"
|
||||
}
|
||||
|
||||
Test_WithBadArg() {
|
||||
Test_BadArg "$(list 1 2 3)"
|
||||
}
|
Reference in New Issue
Block a user