From 6e4446f49e68db9c2f07f13031e72b947d686359 Mon Sep 17 00:00:00 2001 From: imos Date: Mon, 15 Sep 2014 22:14:16 +0900 Subject: [PATCH 01/58] Fix a typo. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 887b5ad..f9a0f71 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Glog-like logging imosh provides a standard way for logging like glog. ```sh -LOG ERROR 'something bad happends!' +LOG ERROR 'some error happens!' ``` Usage From 432c9106947fd6b3f253d3abecb6dd7418476ebe Mon Sep 17 00:00:00 2001 From: imos Date: Wed, 17 Sep 2014 02:59:02 +0900 Subject: [PATCH 02/58] Add imosh::internal::set. --- Makefile | 4 ++-- imosh | 11 +++++++++++ library/20-internal/set.sh | 10 ++++++++++ library/{99-footer.sh => 99-footer/footer.sh} | 0 test/internal/set_test.sh | 11 +++++++++++ 5 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 library/20-internal/set.sh rename library/{99-footer.sh => 99-footer/footer.sh} (100%) create mode 100644 test/internal/set_test.sh diff --git a/Makefile b/Makefile index 73bb7c9..9c7d0b1 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ concat: @echo '#!/bin/bash' >imosh @echo "# Last update: $$(git log --date=iso --pretty=format:'%cd (%h)' library | head -n 1)" >>imosh @echo '#' >>imosh - @for library in library/*.sh; do \ + @for library in library/*.sh library/*/*.sh; do \ cat "$${library}"; \ echo; \ done >>imosh @@ -13,5 +13,5 @@ test: concat bash --version env bash -c shopt - @if ! bash test/main.sh test/*_test.sh; then exit 1; fi + @if ! bash test/main.sh test/*_test.sh test/*/*_test.sh; then exit 1; fi .PHONY: test diff --git a/imosh b/imosh index 2b0dba2..dc1f5cc 100755 --- a/imosh +++ b/imosh @@ -1054,5 +1054,16 @@ php::start() { fi } +# Usage: +# imosh::internal::set destination source +# +# Sets the content of a variable specfied in source into destination. +imosh::internal::set() { + local __set_destination="$1" + local __set_source="$2" + + eval "${__set_destination}=\"\${${__set_source}}\"" +} + LOG INFO 'imosh is ready.' diff --git a/library/20-internal/set.sh b/library/20-internal/set.sh new file mode 100644 index 0000000..47a78e6 --- /dev/null +++ b/library/20-internal/set.sh @@ -0,0 +1,10 @@ +# Usage: +# imosh::internal::set destination source +# +# Sets the content of a variable specfied in source into destination. +imosh::internal::set() { + local __set_destination="$1" + local __set_source="$2" + + eval "${__set_destination}=\"\${${__set_source}}\"" +} diff --git a/library/99-footer.sh b/library/99-footer/footer.sh similarity index 100% rename from library/99-footer.sh rename to library/99-footer/footer.sh diff --git a/test/internal/set_test.sh b/test/internal/set_test.sh new file mode 100644 index 0000000..f99aa74 --- /dev/null +++ b/test/internal/set_test.sh @@ -0,0 +1,11 @@ +test::imosh_internal_set() { + local source destination + + source='test' + imosh::internal::set destination source + EXPECT_EQ 'test' "${destination}" + + source=$'abc\x00\x01\x02\x03\x04\x05\x06\x07\x08xyz' + imosh::internal::set destination source + EXPECT_EQ $'abc\x00\x01\x02\x03\x04\x05\x06\x07\x08xyz' "${destination}" +} From c70aa14c9d8cf47db1444e79fed12a8fa2d9744b Mon Sep 17 00:00:00 2001 From: imos Date: Wed, 17 Sep 2014 03:19:15 +0900 Subject: [PATCH 03/58] Change the header of imosh. --- Makefile | 6 ++++-- imosh | 6 +++--- library/00-header.sh | 2 -- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 9c7d0b1..96be8ce 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,9 @@ concat: @echo '#!/bin/bash' >imosh - @echo "# Last update: $$(git log --date=iso --pretty=format:'%cd (%h)' library | head -n 1)" >>imosh - @echo '#' >>imosh + @echo '# imos is a utility library for BASH.' >>imosh + @echo '' >>imosh + @echo "IMOSH_VERSION='$$(git log --pretty=format:'%ci (%h)' library | head -n 1)'" >>imosh + @echo '' >>imosh @for library in library/*.sh library/*/*.sh; do \ cat "$${library}"; \ echo; \ diff --git a/imosh b/imosh index dc1f5cc..eeab77a 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash -# Last update: 2014-09-15 21:33:44 +0900 (2547256) -# -# imosh - Libraries for BASH. +# imos is a utility library for BASH. + +IMOSH_VERSION='2014-09-17 02:59:02 +0900 (432c910)' if ! shopt login_shell >/dev/null; then set -e -u diff --git a/library/00-header.sh b/library/00-header.sh index 3834bc7..87cf572 100644 --- a/library/00-header.sh +++ b/library/00-header.sh @@ -1,5 +1,3 @@ -# imosh - Libraries for BASH. - if ! shopt login_shell >/dev/null; then set -e -u fi From 700843ed9d492e7f3602d32ea35599b090f24224 Mon Sep 17 00:00:00 2001 From: imos Date: Wed, 17 Sep 2014 03:19:26 +0900 Subject: [PATCH 04/58] Update imosh. --- imosh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imosh b/imosh index eeab77a..993af52 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-17 02:59:02 +0900 (432c910)' +IMOSH_VERSION='2014-09-17 03:19:15 +0900 (c70aa14)' if ! shopt login_shell >/dev/null; then set -e -u From 6f7844d11acb00d01b2e7b5d8086a788724c33e8 Mon Sep 17 00:00:00 2001 From: imos Date: Wed, 17 Sep 2014 03:33:09 +0900 Subject: [PATCH 05/58] Refactor 20-color.sh and move it to 10-variable/color.sh. --- imosh | 29 ++++++++++++++--------------- library/10-variable/color.sh | 13 +++++++++++++ library/20-color.sh | 14 -------------- 3 files changed, 27 insertions(+), 29 deletions(-) create mode 100644 library/10-variable/color.sh delete mode 100644 library/20-color.sh diff --git a/imosh b/imosh index 993af52..42e2b7c 100755 --- a/imosh +++ b/imosh @@ -60,21 +60,6 @@ imosh::get_child_processes() { ps -axo ppid,pid | awk "{ if (\$1 == ${ppid}) print \$2; }" } -imosh::internal::style() { - echo -en "\\033[${1}m" -} - -IMOSH_STYLE_DEFAULT="$(imosh::internal::style '0')" -IMOSH_COLOR_DEFAULT="$(imosh::internal::style '0;39')" -IMOSH_COLOR_BLACK="$(imosh::internal::style '0;30')" -IMOSH_COLOR_RED="$(imosh::internal::style '0;31')" -IMOSH_COLOR_GREEN="$(imosh::internal::style '0;32')" -IMOSH_COLOR_YELLOW="$(imosh::internal::style '0;33')" -IMOSH_COLOR_BLUE="$(imosh::internal::style '0;34')" -IMOSH_COLOR_MAGENTA="$(imosh::internal::style '0;35')" -IMOSH_COLOR_CYAN="$(imosh::internal::style '0;36')" -IMOSH_COLOR_WHITE="$(imosh::internal::style '0;37')" - imosh::shell_escape() { local arg local search="'" @@ -1054,6 +1039,20 @@ php::start() { fi } +# Color definitions. A shell script should restore terminal's original color +# using IMOSH_STYLE_DEFAULT when it changes color or style. + +IMOSH_STYLE_DEFAULT=$'\033[0m' +IMOSH_COLOR_DEFAULT=$'\033[0;39m' +IMOSH_COLOR_BLACK=$'\033[0;30m' +IMOSH_COLOR_RED=$'\033[0;31m' +IMOSH_COLOR_GREEN=$'\033[0;32m' +IMOSH_COLOR_YELLOW=$'\033[0;33m' +IMOSH_COLOR_BLUE=$'\033[0;34m' +IMOSH_COLOR_MAGENTA=$'\033[0;35m' +IMOSH_COLOR_CYAN=$'\033[0;36m' +IMOSH_COLOR_WHITE=$'\033[0;37m' + # Usage: # imosh::internal::set destination source # diff --git a/library/10-variable/color.sh b/library/10-variable/color.sh new file mode 100644 index 0000000..4bb3382 --- /dev/null +++ b/library/10-variable/color.sh @@ -0,0 +1,13 @@ +# Color definitions. A shell script should restore terminal's original color +# using IMOSH_STYLE_DEFAULT when it changes color or style. + +IMOSH_STYLE_DEFAULT=$'\033[0m' +IMOSH_COLOR_DEFAULT=$'\033[0;39m' +IMOSH_COLOR_BLACK=$'\033[0;30m' +IMOSH_COLOR_RED=$'\033[0;31m' +IMOSH_COLOR_GREEN=$'\033[0;32m' +IMOSH_COLOR_YELLOW=$'\033[0;33m' +IMOSH_COLOR_BLUE=$'\033[0;34m' +IMOSH_COLOR_MAGENTA=$'\033[0;35m' +IMOSH_COLOR_CYAN=$'\033[0;36m' +IMOSH_COLOR_WHITE=$'\033[0;37m' diff --git a/library/20-color.sh b/library/20-color.sh deleted file mode 100644 index dd95482..0000000 --- a/library/20-color.sh +++ /dev/null @@ -1,14 +0,0 @@ -imosh::internal::style() { - echo -en "\\033[${1}m" -} - -IMOSH_STYLE_DEFAULT="$(imosh::internal::style '0')" -IMOSH_COLOR_DEFAULT="$(imosh::internal::style '0;39')" -IMOSH_COLOR_BLACK="$(imosh::internal::style '0;30')" -IMOSH_COLOR_RED="$(imosh::internal::style '0;31')" -IMOSH_COLOR_GREEN="$(imosh::internal::style '0;32')" -IMOSH_COLOR_YELLOW="$(imosh::internal::style '0;33')" -IMOSH_COLOR_BLUE="$(imosh::internal::style '0;34')" -IMOSH_COLOR_MAGENTA="$(imosh::internal::style '0;35')" -IMOSH_COLOR_CYAN="$(imosh::internal::style '0;36')" -IMOSH_COLOR_WHITE="$(imosh::internal::style '0;37')" From c906d5a22c15aeb31718914f8fc6491a6eacea84 Mon Sep 17 00:00:00 2001 From: imos Date: Wed, 17 Sep 2014 03:33:24 +0900 Subject: [PATCH 06/58] Update imosh. --- imosh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imosh b/imosh index 42e2b7c..37186f6 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-17 03:19:15 +0900 (c70aa14)' +IMOSH_VERSION='2014-09-17 03:33:09 +0900 (6f7844d)' if ! shopt login_shell >/dev/null; then set -e -u From 4c6446ab10b4f1754dc76bc69ddcd5695e52946e Mon Sep 17 00:00:00 2001 From: imos Date: Wed, 17 Sep 2014 03:39:17 +0900 Subject: [PATCH 07/58] Kill 20-child-processes.sh because it is not used. --- library/20-child-processes.sh | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 library/20-child-processes.sh diff --git a/library/20-child-processes.sh b/library/20-child-processes.sh deleted file mode 100644 index ec20479..0000000 --- a/library/20-child-processes.sh +++ /dev/null @@ -1,4 +0,0 @@ -imosh::get_child_processes() { - local ppid="$1" - ps -axo ppid,pid | awk "{ if (\$1 == ${ppid}) print \$2; }" -} From 173814c0118063d84bbe5f34f83471e924cec52c Mon Sep 17 00:00:00 2001 From: imos Date: Wed, 17 Sep 2014 03:39:24 +0900 Subject: [PATCH 08/58] Update imosh. --- imosh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/imosh b/imosh index 37186f6..251d53b 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-17 03:33:09 +0900 (6f7844d)' +IMOSH_VERSION='2014-09-17 03:39:17 +0900 (4c6446a)' if ! shopt login_shell >/dev/null; then set -e -u @@ -55,11 +55,6 @@ exec 101>&- 102>&- 103>&- 104>&- # Open descriptors for LOG without calling init_log. exec 101>/dev/null 102>/dev/null 103>/dev/null 104>/dev/null -imosh::get_child_processes() { - local ppid="$1" - ps -axo ppid,pid | awk "{ if (\$1 == ${ppid}) print \$2; }" -} - imosh::shell_escape() { local arg local search="'" From e6c089390c188e0d7de93bac7b6abba9370d4d52 Mon Sep 17 00:00:00 2001 From: imos Date: Thu, 18 Sep 2014 01:47:29 +0900 Subject: [PATCH 09/58] Rename imosh::internal::set to func::strcpy. --- imosh | 12 ++++++------ library/20-func/strcpy.sh | 10 ++++++++++ library/20-internal/set.sh | 10 ---------- test/{internal/set_test.sh => func/strcpy_test.sh} | 6 +++--- 4 files changed, 19 insertions(+), 19 deletions(-) create mode 100644 library/20-func/strcpy.sh delete mode 100644 library/20-internal/set.sh rename test/{internal/set_test.sh => func/strcpy_test.sh} (65%) diff --git a/imosh b/imosh index 251d53b..bb35bf3 100755 --- a/imosh +++ b/imosh @@ -1049,14 +1049,14 @@ IMOSH_COLOR_CYAN=$'\033[0;36m' IMOSH_COLOR_WHITE=$'\033[0;37m' # Usage: -# imosh::internal::set destination source +# func::strcpy destination source # -# Sets the content of a variable specfied in source into destination. -imosh::internal::set() { - local __set_destination="$1" - local __set_source="$2" +# Assigns the content of a variable specified as source into destination. +func::strcpy() { + local __strcpy_destination="$1" + local __strcpy_source="$2" - eval "${__set_destination}=\"\${${__set_source}}\"" + eval "${__strcpy_destination}=\"\${${__strcpy_source}}\"" } LOG INFO 'imosh is ready.' diff --git a/library/20-func/strcpy.sh b/library/20-func/strcpy.sh new file mode 100644 index 0000000..ba8d0c3 --- /dev/null +++ b/library/20-func/strcpy.sh @@ -0,0 +1,10 @@ +# Usage: +# func::strcpy destination source +# +# Assigns the content of a variable specified as source into destination. +func::strcpy() { + local __strcpy_destination="$1" + local __strcpy_source="$2" + + eval "${__strcpy_destination}=\"\${${__strcpy_source}}\"" +} diff --git a/library/20-internal/set.sh b/library/20-internal/set.sh deleted file mode 100644 index 47a78e6..0000000 --- a/library/20-internal/set.sh +++ /dev/null @@ -1,10 +0,0 @@ -# Usage: -# imosh::internal::set destination source -# -# Sets the content of a variable specfied in source into destination. -imosh::internal::set() { - local __set_destination="$1" - local __set_source="$2" - - eval "${__set_destination}=\"\${${__set_source}}\"" -} diff --git a/test/internal/set_test.sh b/test/func/strcpy_test.sh similarity index 65% rename from test/internal/set_test.sh rename to test/func/strcpy_test.sh index f99aa74..d5928d2 100644 --- a/test/internal/set_test.sh +++ b/test/func/strcpy_test.sh @@ -1,11 +1,11 @@ -test::imosh_internal_set() { +test::func_strcpy() { local source destination source='test' - imosh::internal::set destination source + func::strcpy destination source EXPECT_EQ 'test' "${destination}" source=$'abc\x00\x01\x02\x03\x04\x05\x06\x07\x08xyz' - imosh::internal::set destination source + func::strcpy destination source EXPECT_EQ $'abc\x00\x01\x02\x03\x04\x05\x06\x07\x08xyz' "${destination}" } From 588cbe65fb74b668430fa5fdec8e9d636ab1e4bb Mon Sep 17 00:00:00 2001 From: imos Date: Thu, 18 Sep 2014 02:07:51 +0900 Subject: [PATCH 10/58] Add func::escapeshellarg. --- imosh | 14 +++++++++++++- library/20-func/escapeshellarg.sh | 11 +++++++++++ test/func/escapeshellarg_test.sh | 11 +++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 library/20-func/escapeshellarg.sh create mode 100644 test/func/escapeshellarg_test.sh diff --git a/imosh b/imosh index bb35bf3..7d241a3 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-17 03:39:17 +0900 (4c6446a)' +IMOSH_VERSION='2014-09-18 01:47:29 +0900 (e6c0893)' if ! shopt login_shell >/dev/null; then set -e -u @@ -1048,6 +1048,18 @@ IMOSH_COLOR_MAGENTA=$'\033[0;35m' IMOSH_COLOR_CYAN=$'\033[0;36m' IMOSH_COLOR_WHITE=$'\033[0;37m' +# Usage: +# func::escapeshellarg variable +# +# Escapes variable's content. +func::escapeshellarg() { + local __escapeshellarg_variable="$1" + local __escapeshellarg_search="'" + local __escapeshellarg_replace="'\\''" + + eval "${__escapeshellarg_variable}=\"'\${${__escapeshellarg_variable}//\${__escapeshellarg_search}/\${__escapeshellarg_replace}}'\"" +} + # Usage: # func::strcpy destination source # diff --git a/library/20-func/escapeshellarg.sh b/library/20-func/escapeshellarg.sh new file mode 100644 index 0000000..20971db --- /dev/null +++ b/library/20-func/escapeshellarg.sh @@ -0,0 +1,11 @@ +# Usage: +# func::escapeshellarg variable +# +# Escapes variable's content. +func::escapeshellarg() { + local __escapeshellarg_variable="$1" + local __escapeshellarg_search="'" + local __escapeshellarg_replace="'\\''" + + eval "${__escapeshellarg_variable}=\"'\${${__escapeshellarg_variable}//\${__escapeshellarg_search}/\${__escapeshellarg_replace}}'\"" +} diff --git a/test/func/escapeshellarg_test.sh b/test/func/escapeshellarg_test.sh new file mode 100644 index 0000000..d0029f6 --- /dev/null +++ b/test/func/escapeshellarg_test.sh @@ -0,0 +1,11 @@ +test::func_escapeshellarg() { + local variable + + variable='test' + func::escapeshellarg variable + EXPECT_EQ "'test'" "${variable}" + + variable="abc def'ghi\\jkl" + func::escapeshellarg variable + EXPECT_EQ "'abc def'\\''ghi\\jkl'" "${variable}" +} From 285bb1104cb3b59b073fb5f61f0638662a00ae56 Mon Sep 17 00:00:00 2001 From: imos Date: Thu, 18 Sep 2014 02:42:36 +0900 Subject: [PATCH 11/58] Replace imosh::shell_escape with func::escapeshellarg. --- imosh | 72 ++++++++++++++++++++------------------- library/20-escape.sh | 9 ----- library/20-func/let.sh | 10 ++++++ library/30-flags.sh | 32 ++++++----------- library/40-php.sh | 2 -- library/80-flags/imosh.sh | 12 +++++++ library/80-flags/php.sh | 1 + test/escape_test.sh | 4 --- 8 files changed, 70 insertions(+), 72 deletions(-) delete mode 100644 library/20-escape.sh create mode 100644 library/20-func/let.sh create mode 100644 library/80-flags/imosh.sh create mode 100644 library/80-flags/php.sh delete mode 100644 test/escape_test.sh diff --git a/imosh b/imosh index 7d241a3..0509148 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-18 01:47:29 +0900 (e6c0893)' +IMOSH_VERSION='2014-09-18 02:07:51 +0900 (588cbe6)' if ! shopt login_shell >/dev/null; then set -e -u @@ -55,16 +55,6 @@ exec 101>&- 102>&- 103>&- 104>&- # Open descriptors for LOG without calling init_log. exec 101>/dev/null 102>/dev/null 103>/dev/null 104>/dev/null -imosh::shell_escape() { - local arg - local search="'" - local replace="'\"'\"'" - for arg in "$@"; do - arg="${arg//${search}/${replace}}" - echo -n "'${arg}'" - done -} - __IMOSH_STACK_TRACED=0 imosh::on_exit() { @@ -707,13 +697,12 @@ imosh::internal::define_flag() { if php::isset "__IMOSH_FLAGS_TYPE_${name}"; then LOG FATAL "already defined flag: ${name}" fi - eval "FLAGS_${name}=$(imosh::shell_escape "${default_value}")" - eval "__IMOSH_FLAGS_TYPE_${name}=${type}" + func::strcpy "FLAGS_${name}" 'default_value' + func::strcpy "__IMOSH_FLAGS_TYPE_${name}" 'type' if [ "${ARGS_alias}" != '' ]; then imosh::internal::define_flag "${type}" --alias_flag \ "${ARGS_alias}" "${default_value}" "${description}" - eval "__IMOSH_FLAGS_ALIASES+=( \ - $(imosh::shell_escape "${name}:${ARGS_alias}"))" + __IMOSH_FLAGS_ALIASES+=("${name}:${ARGS_alias}") fi if (( ! ARGS_alias_flag )); then local escaped_default_value='' @@ -726,15 +715,17 @@ imosh::internal::define_flag() { escaped_default_value='false' fi ;; - *) escaped_default_value="$(imosh::shell_escape "${default_value}")";; + *) + escaped_default_value="${default_value}" + func::escapeshellarg escaped_default_value + ;; esac - eval "__IMOSH_FLAGS_DEFAULT_${name}=$( - imosh::shell_escape "--${name}=${escaped_default_value}")" + func::let "__IMOSH_FLAGS_DEFAULT_${name}" \ + "--${name}=${escaped_default_value}" if [ "${ARGS_alias}" != '' ]; then description+=" (Alias: --${ARGS_alias})" fi - eval "__IMOSH_FLAGS_DESCRIPTION_${name}=$( - imosh::shell_escape "${description}")" + func::let "__IMOSH_FLAGS_DESCRIPTION_${name}" "${description}" __IMOSH_FLAGS+=("${group}:${name}") fi } @@ -897,19 +888,6 @@ readonly IMOSH_INIT=' __IMOSH_FLAGS=() __IMOSH_FLAGS_ALIASES=() -DEFINE_bool --group=imosh --alias=h help false \ - 'Print this help message and exit.' -DEFINE_bool --group=imosh 'alsologtostderr' false \ - 'Log messages go to stderr in addition to logfiles.' -DEFINE_bool --group=imosh 'logtostderr' false \ - 'Log messages go to stderr instead of logfiles.' -DEFINE_string --group=imosh 'log_dir' '' \ - 'Directory to output log files. Output no files if this flag is empty.' -DEFINE_string --group=imosh 'stacktrace_threshold' 'FATAL' \ - 'Threshold to show stacktrace.' -DEFINE_bool --group=imosh 'help_groff' false \ - 'Use groff for help output.' - imosh::mktemp() { TMPDIR="${TMPDIR%/}" export IMOSH_TMPDIR="$(mktemp -d "${TMPDIR:-/tmp}/imosh.XXXXXX")" @@ -1022,8 +1000,6 @@ EOM exec 110<"${__IMOSH_PHP_STDOUT}" } -DEFINE_bool --group=imosh disown_php false 'Disown a PHP process.' - php::stop() { php::internal::kill } @@ -1060,6 +1036,17 @@ func::escapeshellarg() { eval "${__escapeshellarg_variable}=\"'\${${__escapeshellarg_variable}//\${__escapeshellarg_search}/\${__escapeshellarg_replace}}'\"" } +# Usage: +# func::let destination value +# +# Assigns value into destination. +func::let() { + local __let_destination="$1" + local __let_value="$2" + + eval "${__let_destination}=\"\${__let_value}\"" +} + # Usage: # func::strcpy destination source # @@ -1071,5 +1058,20 @@ func::strcpy() { eval "${__strcpy_destination}=\"\${${__strcpy_source}}\"" } +DEFINE_bool --group=imosh --alias=h help false \ + 'Print this help message and exit.' +DEFINE_bool --group=imosh 'alsologtostderr' false \ + 'Log messages go to stderr in addition to logfiles.' +DEFINE_bool --group=imosh 'logtostderr' false \ + 'Log messages go to stderr instead of logfiles.' +DEFINE_string --group=imosh 'log_dir' '' \ + 'Directory to output log files. Output no files if this flag is empty.' +DEFINE_string --group=imosh 'stacktrace_threshold' 'FATAL' \ + 'Threshold to show stacktrace.' +DEFINE_bool --group=imosh 'help_groff' false \ + 'Use groff for help output.' + +DEFINE_bool --group=imosh disown_php false 'Disown a PHP process.' + LOG INFO 'imosh is ready.' diff --git a/library/20-escape.sh b/library/20-escape.sh deleted file mode 100644 index 736de59..0000000 --- a/library/20-escape.sh +++ /dev/null @@ -1,9 +0,0 @@ -imosh::shell_escape() { - local arg - local search="'" - local replace="'\"'\"'" - for arg in "$@"; do - arg="${arg//${search}/${replace}}" - echo -n "'${arg}'" - done -} diff --git a/library/20-func/let.sh b/library/20-func/let.sh new file mode 100644 index 0000000..9dc6ac0 --- /dev/null +++ b/library/20-func/let.sh @@ -0,0 +1,10 @@ +# Usage: +# func::let destination value +# +# Assigns value into destination. +func::let() { + local __let_destination="$1" + local __let_value="$2" + + eval "${__let_destination}=\"\${__let_value}\"" +} diff --git a/library/30-flags.sh b/library/30-flags.sh index ab14471..d06f372 100644 --- a/library/30-flags.sh +++ b/library/30-flags.sh @@ -66,13 +66,12 @@ imosh::internal::define_flag() { if php::isset "__IMOSH_FLAGS_TYPE_${name}"; then LOG FATAL "already defined flag: ${name}" fi - eval "FLAGS_${name}=$(imosh::shell_escape "${default_value}")" - eval "__IMOSH_FLAGS_TYPE_${name}=${type}" + func::strcpy "FLAGS_${name}" 'default_value' + func::strcpy "__IMOSH_FLAGS_TYPE_${name}" 'type' if [ "${ARGS_alias}" != '' ]; then imosh::internal::define_flag "${type}" --alias_flag \ "${ARGS_alias}" "${default_value}" "${description}" - eval "__IMOSH_FLAGS_ALIASES+=( \ - $(imosh::shell_escape "${name}:${ARGS_alias}"))" + __IMOSH_FLAGS_ALIASES+=("${name}:${ARGS_alias}") fi if (( ! ARGS_alias_flag )); then local escaped_default_value='' @@ -85,15 +84,17 @@ imosh::internal::define_flag() { escaped_default_value='false' fi ;; - *) escaped_default_value="$(imosh::shell_escape "${default_value}")";; + *) + escaped_default_value="${default_value}" + func::escapeshellarg escaped_default_value + ;; esac - eval "__IMOSH_FLAGS_DEFAULT_${name}=$( - imosh::shell_escape "--${name}=${escaped_default_value}")" + func::let "__IMOSH_FLAGS_DEFAULT_${name}" \ + "--${name}=${escaped_default_value}" if [ "${ARGS_alias}" != '' ]; then description+=" (Alias: --${ARGS_alias})" fi - eval "__IMOSH_FLAGS_DESCRIPTION_${name}=$( - imosh::shell_escape "${description}")" + func::let "__IMOSH_FLAGS_DESCRIPTION_${name}" "${description}" __IMOSH_FLAGS+=("${group}:${name}") fi } @@ -255,16 +256,3 @@ readonly IMOSH_INIT=' __IMOSH_FLAGS=() __IMOSH_FLAGS_ALIASES=() - -DEFINE_bool --group=imosh --alias=h help false \ - 'Print this help message and exit.' -DEFINE_bool --group=imosh 'alsologtostderr' false \ - 'Log messages go to stderr in addition to logfiles.' -DEFINE_bool --group=imosh 'logtostderr' false \ - 'Log messages go to stderr instead of logfiles.' -DEFINE_string --group=imosh 'log_dir' '' \ - 'Directory to output log files. Output no files if this flag is empty.' -DEFINE_string --group=imosh 'stacktrace_threshold' 'FATAL' \ - 'Threshold to show stacktrace.' -DEFINE_bool --group=imosh 'help_groff' false \ - 'Use groff for help output.' diff --git a/library/40-php.sh b/library/40-php.sh index 53fb7e4..203fbd9 100644 --- a/library/40-php.sh +++ b/library/40-php.sh @@ -94,8 +94,6 @@ EOM exec 110<"${__IMOSH_PHP_STDOUT}" } -DEFINE_bool --group=imosh disown_php false 'Disown a PHP process.' - php::stop() { php::internal::kill } diff --git a/library/80-flags/imosh.sh b/library/80-flags/imosh.sh new file mode 100644 index 0000000..7c2d932 --- /dev/null +++ b/library/80-flags/imosh.sh @@ -0,0 +1,12 @@ +DEFINE_bool --group=imosh --alias=h help false \ + 'Print this help message and exit.' +DEFINE_bool --group=imosh 'alsologtostderr' false \ + 'Log messages go to stderr in addition to logfiles.' +DEFINE_bool --group=imosh 'logtostderr' false \ + 'Log messages go to stderr instead of logfiles.' +DEFINE_string --group=imosh 'log_dir' '' \ + 'Directory to output log files. Output no files if this flag is empty.' +DEFINE_string --group=imosh 'stacktrace_threshold' 'FATAL' \ + 'Threshold to show stacktrace.' +DEFINE_bool --group=imosh 'help_groff' false \ + 'Use groff for help output.' diff --git a/library/80-flags/php.sh b/library/80-flags/php.sh new file mode 100644 index 0000000..4f4877f --- /dev/null +++ b/library/80-flags/php.sh @@ -0,0 +1 @@ +DEFINE_bool --group=imosh disown_php false 'Disown a PHP process.' diff --git a/test/escape_test.sh b/test/escape_test.sh deleted file mode 100644 index 4ac8ce4..0000000 --- a/test/escape_test.sh +++ /dev/null @@ -1,4 +0,0 @@ -test::shell_escape() { - EXPECT_EQ "'foo'" "$(imosh::shell_escape foo)" - EXPECT_EQ "'foo'\"'\"'bar'" "$(imosh::shell_escape "foo'bar")" -} From 5592abcb5d7f19caa6951f69b09e3e3fb3ddadc9 Mon Sep 17 00:00:00 2001 From: imos Date: Thu, 18 Sep 2014 02:44:25 +0900 Subject: [PATCH 12/58] Add a test for func::let. --- imosh | 2 +- test/func/let_test.sh | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 test/func/let_test.sh diff --git a/imosh b/imosh index 0509148..f513b12 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-18 02:07:51 +0900 (588cbe6)' +IMOSH_VERSION='2014-09-18 02:42:36 +0900 (285bb11)' if ! shopt login_shell >/dev/null; then set -e -u diff --git a/test/func/let_test.sh b/test/func/let_test.sh new file mode 100644 index 0000000..135612b --- /dev/null +++ b/test/func/let_test.sh @@ -0,0 +1,9 @@ +test::func_let() { + local destination + + func::let destination 'test' + EXPECT_EQ 'test' "${destination}" + + func::let destination $'abc\x00\x01\x02\x03\x04\x05\x06\x07\x08xyz' + EXPECT_EQ $'abc\x00\x01\x02\x03\x04\x05\x06\x07\x08xyz' "${destination}" +} From 58398f3ba41c37181d43f8f765f9ab18d985aef9 Mon Sep 17 00:00:00 2001 From: imos Date: Thu, 18 Sep 2014 03:27:50 +0900 Subject: [PATCH 13/58] Add func::intval. --- imosh | 74 ++++++++++++++++++----------- library/20-func/intval.sh | 15 ++++++ library/20-internal/convert_type.sh | 28 +++++++++++ library/30-flags.sh | 29 ----------- test/func/intval_test.sh | 20 ++++++++ 5 files changed, 108 insertions(+), 58 deletions(-) create mode 100644 library/20-func/intval.sh create mode 100644 library/20-internal/convert_type.sh create mode 100644 test/func/intval_test.sh diff --git a/imosh b/imosh index f513b12..d115e65 100755 --- a/imosh +++ b/imosh @@ -633,35 +633,6 @@ imosh::stack_trace() { # __IMOSH_FLAGS_DESCRIPTION_= # __IMOSH_FLAGS_ALIASES=(from:to ...) -imosh::internal::convert_type() { - local type="$1"; shift - local value="$*" - - case "${type}" in - int) - if [[ "${value}" =~ ^-?[0-9]+$ ]]; then - print "${value}" - else - return 1 - fi - ;; - string) - print "${value}" - ;; - bool) - case "${value}" in - 1|T|t|[Tt]rue) print 1;; - 0|F|f|[Ff]alse) print 0;; - *) return 1;; - esac - ;; - variant) - print "${value}" - ;; - *) LOG FATAL "no such type: ${type}";; - esac -} - imosh::internal::flag_type() { local name="$1" @@ -1036,6 +1007,22 @@ func::escapeshellarg() { eval "${__escapeshellarg_variable}=\"'\${${__escapeshellarg_variable}//\${__escapeshellarg_search}/\${__escapeshellarg_replace}}'\"" } +# Usage: +# func::intval variable +# +# Casts variable into integer type. If it fails, returns 1. +func::intval() { + local __intval_variable="$1" + + local __intval_value + eval "__intval_value=\"\${${__intval_variable}}\"" + if [[ "${__intval_value}" =~ ^[[:space:]]*(-?[0-9]+) ]]; then + func::let "${__intval_variable}" "${BASH_REMATCH[1]}" + else + return 1 + fi +} + # Usage: # func::let destination value # @@ -1058,6 +1045,35 @@ func::strcpy() { eval "${__strcpy_destination}=\"\${${__strcpy_source}}\"" } +imosh::internal::convert_type() { + local type="$1"; shift + local value="$1"; shift + + case "${type}" in + int) + if [[ "${value}" =~ ^-?[0-9]+$ ]]; then + print "${value}" + else + return 1 + fi + ;; + string) + print "${value}" + ;; + bool) + case "${value}" in + 1|T|t|[Tt]rue) print 1;; + 0|F|f|[Ff]alse) print 0;; + *) return 1;; + esac + ;; + variant) + print "${value}" + ;; + *) LOG FATAL "no such type: ${type}";; + esac +} + DEFINE_bool --group=imosh --alias=h help false \ 'Print this help message and exit.' DEFINE_bool --group=imosh 'alsologtostderr' false \ diff --git a/library/20-func/intval.sh b/library/20-func/intval.sh new file mode 100644 index 0000000..caf2317 --- /dev/null +++ b/library/20-func/intval.sh @@ -0,0 +1,15 @@ +# Usage: +# func::intval variable +# +# Casts variable into integer type. If it fails, returns 1. +func::intval() { + local __intval_variable="$1" + + local __intval_value + eval "__intval_value=\"\${${__intval_variable}}\"" + if [[ "${__intval_value}" =~ ^[[:space:]]*(-?[0-9]+) ]]; then + func::let "${__intval_variable}" "${BASH_REMATCH[1]}" + else + return 1 + fi +} diff --git a/library/20-internal/convert_type.sh b/library/20-internal/convert_type.sh new file mode 100644 index 0000000..33011f2 --- /dev/null +++ b/library/20-internal/convert_type.sh @@ -0,0 +1,28 @@ +imosh::internal::convert_type() { + local type="$1"; shift + local value="$1"; shift + + case "${type}" in + int) + if [[ "${value}" =~ ^-?[0-9]+$ ]]; then + print "${value}" + else + return 1 + fi + ;; + string) + print "${value}" + ;; + bool) + case "${value}" in + 1|T|t|[Tt]rue) print 1;; + 0|F|f|[Ff]alse) print 0;; + *) return 1;; + esac + ;; + variant) + print "${value}" + ;; + *) LOG FATAL "no such type: ${type}";; + esac +} diff --git a/library/30-flags.sh b/library/30-flags.sh index d06f372..857a5dc 100644 --- a/library/30-flags.sh +++ b/library/30-flags.sh @@ -2,35 +2,6 @@ # __IMOSH_FLAGS_DESCRIPTION_= # __IMOSH_FLAGS_ALIASES=(from:to ...) -imosh::internal::convert_type() { - local type="$1"; shift - local value="$*" - - case "${type}" in - int) - if [[ "${value}" =~ ^-?[0-9]+$ ]]; then - print "${value}" - else - return 1 - fi - ;; - string) - print "${value}" - ;; - bool) - case "${value}" in - 1|T|t|[Tt]rue) print 1;; - 0|F|f|[Ff]alse) print 0;; - *) return 1;; - esac - ;; - variant) - print "${value}" - ;; - *) LOG FATAL "no such type: ${type}";; - esac -} - imosh::internal::flag_type() { local name="$1" diff --git a/test/func/intval_test.sh b/test/func/intval_test.sh new file mode 100644 index 0000000..7febd1f --- /dev/null +++ b/test/func/intval_test.sh @@ -0,0 +1,20 @@ +test::func_intval() { + local variable + + variable=12345 + func::intval variable + EXPECT_EQ 12345 "${variable}" + + variable=-12345678901234567890 + func::intval variable + EXPECT_EQ -12345678901234567890 "${variable}" + + variable=' -123.456 ' + func::intval variable + EXPECT_EQ -123 "${variable}" + + variable='abc' + if func::intval variable; then + LOG FATAL 'abc cannot be cast to an integer.' + fi +} From 838c2fca0f2e64bf5778bd4e8094c615d3abb2df Mon Sep 17 00:00:00 2001 From: imos Date: Sat, 20 Sep 2014 04:19:39 +0900 Subject: [PATCH 14/58] Add func::floatval, func::str_replace and func::strval. --- imosh | 47 +++++++++++++++++++++++++++++++--- library/20-func/floatval.sh | 15 +++++++++++ library/20-func/let.sh | 4 +-- library/20-func/str_replace.sh | 14 ++++++++++ library/20-func/strval.sh | 9 +++++++ test/func/floatval_test.sh | 20 +++++++++++++++ test/func/str_replace_test.sh | 31 ++++++++++++++++++++++ test/func/strval_test.sh | 19 ++++++++++++++ 8 files changed, 154 insertions(+), 5 deletions(-) create mode 100644 library/20-func/floatval.sh create mode 100644 library/20-func/str_replace.sh create mode 100644 library/20-func/strval.sh create mode 100644 test/func/floatval_test.sh create mode 100644 test/func/str_replace_test.sh create mode 100644 test/func/strval_test.sh diff --git a/imosh b/imosh index d115e65..77ffba0 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-18 02:42:36 +0900 (285bb11)' +IMOSH_VERSION='2014-09-18 03:27:50 +0900 (58398f3)' if ! shopt login_shell >/dev/null; then set -e -u @@ -1007,6 +1007,22 @@ func::escapeshellarg() { eval "${__escapeshellarg_variable}=\"'\${${__escapeshellarg_variable}//\${__escapeshellarg_search}/\${__escapeshellarg_replace}}'\"" } +# Usage: +# func::floatval variable +# +# Casts variable into float type. If it fails, returns 1. +func::floatval() { + local __floatval_variable="$1" + + local __floatval_value + eval "__floatval_value=\"\${${__floatval_variable}}\"" + if [[ "${__floatval_value}" =~ ^[[:space:]]*(-?[0-9]+(\.[0-9]+)?) ]]; then + func::let "${__floatval_variable}" "${BASH_REMATCH[1]}" + else + return 1 + fi +} + # Usage: # func::intval variable # @@ -1024,9 +1040,9 @@ func::intval() { } # Usage: -# func::let destination value +# func::let(string* destination, string value) # -# Assigns value into destination. +# Assigns value into *destination. func::let() { local __let_destination="$1" local __let_value="$2" @@ -1034,6 +1050,21 @@ func::let() { eval "${__let_destination}=\"\${__let_value}\"" } +# Usage: +# void func::str_replace(string* subject, string search, string replace) +# +# Replace search with replace in *subject. +func::str_replace() { + if [ "$#" -ne 3 ]; then + LOG FATAL 'func::str_replace takes exactly 3 arguments.' + fi + local __str_replace_subject_variable="${1}" + local __str_replace_search="${2}" + local __str_replace_replace="${3}" + + eval "${__str_replace_subject_variable}=\"\${${__str_replace_subject_variable}//\${__str_replace_search}/\${__str_replace_replace}}\"" +} + # Usage: # func::strcpy destination source # @@ -1045,6 +1076,16 @@ func::strcpy() { eval "${__strcpy_destination}=\"\${${__strcpy_source}}\"" } +# Usage: +# func::strval variable +# +# Casts variable into string type. If it fails, returns 1. +func::strval() { + local __strval_variable="$1" + + eval "${__strval_variable}=\"\${${__strval_variable}}\"" +} + imosh::internal::convert_type() { local type="$1"; shift local value="$1"; shift diff --git a/library/20-func/floatval.sh b/library/20-func/floatval.sh new file mode 100644 index 0000000..b763927 --- /dev/null +++ b/library/20-func/floatval.sh @@ -0,0 +1,15 @@ +# Usage: +# func::floatval variable +# +# Casts variable into float type. If it fails, returns 1. +func::floatval() { + local __floatval_variable="$1" + + local __floatval_value + eval "__floatval_value=\"\${${__floatval_variable}}\"" + if [[ "${__floatval_value}" =~ ^[[:space:]]*(-?[0-9]+(\.[0-9]+)?) ]]; then + func::let "${__floatval_variable}" "${BASH_REMATCH[1]}" + else + return 1 + fi +} diff --git a/library/20-func/let.sh b/library/20-func/let.sh index 9dc6ac0..78896f4 100644 --- a/library/20-func/let.sh +++ b/library/20-func/let.sh @@ -1,7 +1,7 @@ # Usage: -# func::let destination value +# func::let(string* destination, string value) # -# Assigns value into destination. +# Assigns value into *destination. func::let() { local __let_destination="$1" local __let_value="$2" diff --git a/library/20-func/str_replace.sh b/library/20-func/str_replace.sh new file mode 100644 index 0000000..e748c58 --- /dev/null +++ b/library/20-func/str_replace.sh @@ -0,0 +1,14 @@ +# Usage: +# void func::str_replace(string* subject, string search, string replace) +# +# Replace search with replace in *subject. +func::str_replace() { + if [ "$#" -ne 3 ]; then + LOG FATAL 'func::str_replace takes exactly 3 arguments.' + fi + local __str_replace_subject_variable="${1}" + local __str_replace_search="${2}" + local __str_replace_replace="${3}" + + eval "${__str_replace_subject_variable}=\"\${${__str_replace_subject_variable}//\${__str_replace_search}/\${__str_replace_replace}}\"" +} diff --git a/library/20-func/strval.sh b/library/20-func/strval.sh new file mode 100644 index 0000000..9f374d1 --- /dev/null +++ b/library/20-func/strval.sh @@ -0,0 +1,9 @@ +# Usage: +# func::strval variable +# +# Casts variable into string type. If it fails, returns 1. +func::strval() { + local __strval_variable="$1" + + eval "${__strval_variable}=\"\${${__strval_variable}}\"" +} diff --git a/test/func/floatval_test.sh b/test/func/floatval_test.sh new file mode 100644 index 0000000..24fbd8f --- /dev/null +++ b/test/func/floatval_test.sh @@ -0,0 +1,20 @@ +test::func_floatval() { + local variable + + variable=12345 + func::floatval variable + EXPECT_EQ 12345 "${variable}" + + variable=-12345678901234567890 + func::floatval variable + EXPECT_EQ -12345678901234567890 "${variable}" + + variable=' -123.456 ' + func::floatval variable + EXPECT_EQ -123.456 "${variable}" + + variable='abc' + if func::floatval variable; then + LOG FATAL 'abc cannot be cast to a float value.' + fi +} diff --git a/test/func/str_replace_test.sh b/test/func/str_replace_test.sh new file mode 100644 index 0000000..a24b688 --- /dev/null +++ b/test/func/str_replace_test.sh @@ -0,0 +1,31 @@ +test::func_str_replace() { + local variable + + variable='abc def ghi' + func::str_replace variable ' ' 'x' + EXPECT_EQ 'abcxdefxghi' "${variable}" + + variable='abc def ghi' + func::str_replace variable ' ' 'xyz' + EXPECT_EQ 'abcxyzdefxyzghi' "${variable}" + + variable='abcdefghi' + func::str_replace variable 'def' 'x' + EXPECT_EQ 'abcxghi' "${variable}" + + variable='aaaaaaaa' + func::str_replace variable 'aaa' 'bbb' + EXPECT_EQ 'bbbbbbaa' "${variable}" + + variable='abcdefghi' + func::str_replace variable 'x' 'y' + EXPECT_EQ 'abcdefghi' "${variable}" + + variable=$'abc\ndef' + func::str_replace variable $'\n' ' ' + EXPECT_EQ 'abc def' "${variable}" + + variable='abc/def/ghi' + func::str_replace variable '/' '//' + EXPECT_EQ 'abc//def//ghi' "${variable}" +} diff --git a/test/func/strval_test.sh b/test/func/strval_test.sh new file mode 100644 index 0000000..71939cf --- /dev/null +++ b/test/func/strval_test.sh @@ -0,0 +1,19 @@ +test::func_strval() { + local variable + + variable=12345 + func::strval variable + EXPECT_EQ 12345 "${variable}" + + variable=-12345678901234567890 + func::strval variable + EXPECT_EQ -12345678901234567890 "${variable}" + + variable=' -123.456 ' + func::strval variable + EXPECT_EQ ' -123.456 ' "${variable}" + + variable='abc' + func::strval variable + EXPECT_EQ 'abc' "${variable}" +} From fc15e9612e53ca045a1068004d0b33333eec4ecd Mon Sep 17 00:00:00 2001 From: imos Date: Sun, 21 Sep 2014 13:39:48 +0900 Subject: [PATCH 15/58] Add func::isset. --- imosh | 19 ++++++++++++++++++- library/20-func/isset.sh | 16 ++++++++++++++++ test/func/isset_test.sh | 22 ++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 library/20-func/isset.sh create mode 100644 test/func/isset_test.sh diff --git a/imosh b/imosh index 77ffba0..e8237bb 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-18 03:27:50 +0900 (58398f3)' +IMOSH_VERSION='2014-09-20 04:19:39 +0900 (838c2fc)' if ! shopt login_shell >/dev/null; then set -e -u @@ -1039,6 +1039,23 @@ func::intval() { fi } +# Usage: +# bool func::isset(variant* variable) +# +# Returns true iff variable exists. +# +# CAVEATS: func::isset returns true for uninitialized variables in BASH 3, and +# returns false for them in BASH 4. +func::isset() { + local __isset_variable="$1" + + eval "local __isset_state=\"\${${__isset_variable}+set}\"" + if [ "${__isset_state}" = 'set' ]; then + return 0 + fi + return 1 +} + # Usage: # func::let(string* destination, string value) # diff --git a/library/20-func/isset.sh b/library/20-func/isset.sh new file mode 100644 index 0000000..bb7048b --- /dev/null +++ b/library/20-func/isset.sh @@ -0,0 +1,16 @@ +# Usage: +# bool func::isset(variant* variable) +# +# Returns true iff variable exists. +# +# CAVEATS: func::isset returns true for uninitialized variables in BASH 3, and +# returns false for them in BASH 4. +func::isset() { + local __isset_variable="$1" + + eval "local __isset_state=\"\${${__isset_variable}+set}\"" + if [ "${__isset_state}" = 'set' ]; then + return 0 + fi + return 1 +} diff --git a/test/func/isset_test.sh b/test/func/isset_test.sh new file mode 100644 index 0000000..8e2d495 --- /dev/null +++ b/test/func/isset_test.sh @@ -0,0 +1,22 @@ +test::func_isset() { + if func::isset undefined_variable; then + LOG FATAL "undefined_variable should return false" + fi + local defined_variable=value + if ! func::isset defined_variable; then + LOG FATAL "defined_variable should return true" + fi + defined_variable= + if ! func::isset defined_variable; then + LOG FATAL "defined_variable should return true" + fi + local null_variable= + if ! func::isset null_variable; then + LOG FATAL "null_variable should return true" + fi + # isset's behavior for uninitialized variables is different in BASH versions. + # local uninitialized_variable + # if ! func::isset uninitialized_variable; then + # LOG FATAL "uninitialized_variable should return true" + # fi +} From 66329270b7513879f4c253470f02e4b68432a8df Mon Sep 17 00:00:00 2001 From: imos Date: Sun, 21 Sep 2014 14:27:45 +0900 Subject: [PATCH 16/58] Add func::bin2hex, func::print and func::println. --- imosh | 41 +++++++++++++++++++++++++++++++++++++- library/20-func/bin2hex.sh | 19 ++++++++++++++++++ library/20-func/print.sh | 8 ++++++++ library/20-func/println.sh | 9 +++++++++ test/func/bin2hex_test.sh | 4 ++++ test/func/print_test.sh | 5 +++++ test/func/println_test.sh | 5 +++++ 7 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 library/20-func/bin2hex.sh create mode 100644 library/20-func/print.sh create mode 100644 library/20-func/println.sh create mode 100644 test/func/bin2hex_test.sh create mode 100644 test/func/print_test.sh create mode 100644 test/func/println_test.sh diff --git a/imosh b/imosh index e8237bb..25316bd 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-20 04:19:39 +0900 (838c2fc)' +IMOSH_VERSION='2014-09-21 13:39:48 +0900 (fc15e96)' if ! shopt login_shell >/dev/null; then set -e -u @@ -995,6 +995,26 @@ IMOSH_COLOR_MAGENTA=$'\033[0;35m' IMOSH_COLOR_CYAN=$'\033[0;36m' IMOSH_COLOR_WHITE=$'\033[0;37m' +# Usage: +# func::bin2hex(string* destination, string data) +# func::bin2hex() < string > string +# +# Converts binary data into hexadecimal representation. +func::bin2hex() { + if [ "$#" -eq 0 ]; then + od -An -tx1 | tr -d ' \n' + return + fi + if [ "$#" -ne 2 ]; then + LOG FATAL "func::bin2hex requires two arguments, but $# arguments." + return 1 + fi + local __bin2hex_destination="$1" + local __bin2hex_data="$2" + + eval "${__bin2hex_destination}=\"\$(func::print \"${__bin2hex_data}\" | func::bin2hex)\"" +} + # Usage: # func::escapeshellarg variable # @@ -1067,6 +1087,25 @@ func::let() { eval "${__let_destination}=\"\${__let_value}\"" } +# Usage: +# func::print(string message...) > output +# +# Print message to the standard output. While "echo" consumes flags, +# func::print does not consume any flags, so this is theoretically safe. +func::print() { + printf "%s" "$*" +} + +# Usage: +# func::println(string message...) > output +# +# Print message to the standard output with a new line. While "echo" consumes +# flags, func::println does not consume any flags, so this is theoretically +# safe. +func::println() { + printf "%s\n" "$*" +} + # Usage: # void func::str_replace(string* subject, string search, string replace) # diff --git a/library/20-func/bin2hex.sh b/library/20-func/bin2hex.sh new file mode 100644 index 0000000..90314ed --- /dev/null +++ b/library/20-func/bin2hex.sh @@ -0,0 +1,19 @@ +# Usage: +# func::bin2hex(string* destination, string data) +# func::bin2hex() < string > string +# +# Converts binary data into hexadecimal representation. +func::bin2hex() { + if [ "$#" -eq 0 ]; then + od -An -tx1 | tr -d ' \n' + return + fi + if [ "$#" -ne 2 ]; then + LOG FATAL "func::bin2hex requires two arguments, but $# arguments." + return 1 + fi + local __bin2hex_destination="$1" + local __bin2hex_data="$2" + + eval "${__bin2hex_destination}=\"\$(func::print \"${__bin2hex_data}\" | func::bin2hex)\"" +} diff --git a/library/20-func/print.sh b/library/20-func/print.sh new file mode 100644 index 0000000..2f0c8de --- /dev/null +++ b/library/20-func/print.sh @@ -0,0 +1,8 @@ +# Usage: +# func::print(string message...) > output +# +# Print message to the standard output. While "echo" consumes flags, +# func::print does not consume any flags, so this is theoretically safe. +func::print() { + printf "%s" "$*" +} diff --git a/library/20-func/println.sh b/library/20-func/println.sh new file mode 100644 index 0000000..6d09561 --- /dev/null +++ b/library/20-func/println.sh @@ -0,0 +1,9 @@ +# Usage: +# func::println(string message...) > output +# +# Print message to the standard output with a new line. While "echo" consumes +# flags, func::println does not consume any flags, so this is theoretically +# safe. +func::println() { + printf "%s\n" "$*" +} diff --git a/test/func/bin2hex_test.sh b/test/func/bin2hex_test.sh new file mode 100644 index 0000000..93689b6 --- /dev/null +++ b/test/func/bin2hex_test.sh @@ -0,0 +1,4 @@ +test::func_bin2hex() { + EXPECT_EQ '686f6765' "$(print 'hoge' | php::bin2hex)" + EXPECT_EQ 'e697a5e69cace8aa9e' "$(print '日本語' | func::bin2hex)" +} diff --git a/test/func/print_test.sh b/test/func/print_test.sh new file mode 100644 index 0000000..a476061 --- /dev/null +++ b/test/func/print_test.sh @@ -0,0 +1,5 @@ +test::func_print() { + EXPECT_EQ '686f6765' "$(func::print 'hoge' | php::bin2hex)" + EXPECT_EQ '686f67650a' "$(func::print $'hoge\n' | php::bin2hex)" + EXPECT_EQ '01020304' "$(func::print $'\x01\x02\x03\x04' | php::bin2hex)" +} diff --git a/test/func/println_test.sh b/test/func/println_test.sh new file mode 100644 index 0000000..f390120 --- /dev/null +++ b/test/func/println_test.sh @@ -0,0 +1,5 @@ +test::func_println() { + EXPECT_EQ '686f67650a' "$(func::println 'hoge' | php::bin2hex)" + EXPECT_EQ '686f67650a0a' "$(func::println $'hoge\n' | php::bin2hex)" + EXPECT_EQ '010203040a' "$(func::println $'\x01\x02\x03\x04' | php::bin2hex)" +} From 0de166ea9ca8772b09b09b2880d2530bf641b639 Mon Sep 17 00:00:00 2001 From: imos Date: Sun, 21 Sep 2014 14:30:01 +0900 Subject: [PATCH 17/58] Use func::bin2hex instead of php::bin2hex. --- imosh | 2 +- test/func/bin2hex_test.sh | 6 +++++- test/func/print_test.sh | 6 +++--- test/func/println_test.sh | 6 +++--- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/imosh b/imosh index 25316bd..b076ac0 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-21 13:39:48 +0900 (fc15e96)' +IMOSH_VERSION='2014-09-21 14:27:45 +0900 (6632927)' if ! shopt login_shell >/dev/null; then set -e -u diff --git a/test/func/bin2hex_test.sh b/test/func/bin2hex_test.sh index 93689b6..d8dfddf 100644 --- a/test/func/bin2hex_test.sh +++ b/test/func/bin2hex_test.sh @@ -1,4 +1,8 @@ test::func_bin2hex() { - EXPECT_EQ '686f6765' "$(print 'hoge' | php::bin2hex)" + EXPECT_EQ '686f6765' "$(print 'hoge' | func::bin2hex)" EXPECT_EQ 'e697a5e69cace8aa9e' "$(print '日本語' | func::bin2hex)" + + local variable + func::bin2hex variable 'hoge' + EXPECT_EQ '686f6765' "${variable}" } diff --git a/test/func/print_test.sh b/test/func/print_test.sh index a476061..fa31922 100644 --- a/test/func/print_test.sh +++ b/test/func/print_test.sh @@ -1,5 +1,5 @@ test::func_print() { - EXPECT_EQ '686f6765' "$(func::print 'hoge' | php::bin2hex)" - EXPECT_EQ '686f67650a' "$(func::print $'hoge\n' | php::bin2hex)" - EXPECT_EQ '01020304' "$(func::print $'\x01\x02\x03\x04' | php::bin2hex)" + EXPECT_EQ '686f6765' "$(func::print 'hoge' | func::bin2hex)" + EXPECT_EQ '686f67650a' "$(func::print $'hoge\n' | func::bin2hex)" + EXPECT_EQ '01020304' "$(func::print $'\x01\x02\x03\x04' | func::bin2hex)" } diff --git a/test/func/println_test.sh b/test/func/println_test.sh index f390120..205c044 100644 --- a/test/func/println_test.sh +++ b/test/func/println_test.sh @@ -1,5 +1,5 @@ test::func_println() { - EXPECT_EQ '686f67650a' "$(func::println 'hoge' | php::bin2hex)" - EXPECT_EQ '686f67650a0a' "$(func::println $'hoge\n' | php::bin2hex)" - EXPECT_EQ '010203040a' "$(func::println $'\x01\x02\x03\x04' | php::bin2hex)" + EXPECT_EQ '686f67650a' "$(func::println 'hoge' | func::bin2hex)" + EXPECT_EQ '686f67650a0a' "$(func::println $'hoge\n' | func::bin2hex)" + EXPECT_EQ '010203040a' "$(func::println $'\x01\x02\x03\x04' | func::bin2hex)" } From 5bb905e9f2bcfcb4271807cba124afd343dbd82f Mon Sep 17 00:00:00 2001 From: imos Date: Sun, 21 Sep 2014 14:38:26 +0900 Subject: [PATCH 18/58] Update usage for func::*. --- imosh | 20 ++++++++++---------- library/20-func/bin2hex.sh | 4 ++-- library/20-func/escapeshellarg.sh | 2 +- library/20-func/floatval.sh | 2 +- library/20-func/intval.sh | 2 +- library/20-func/print.sh | 2 +- library/20-func/println.sh | 2 +- library/20-func/strcpy.sh | 2 +- library/20-func/strval.sh | 4 ++-- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/imosh b/imosh index b076ac0..fe42ded 100755 --- a/imosh +++ b/imosh @@ -996,8 +996,8 @@ IMOSH_COLOR_CYAN=$'\033[0;36m' IMOSH_COLOR_WHITE=$'\033[0;37m' # Usage: -# func::bin2hex(string* destination, string data) -# func::bin2hex() < string > string +# void func::bin2hex(string* destination, string data) +# void func::bin2hex() < string > string # # Converts binary data into hexadecimal representation. func::bin2hex() { @@ -1016,7 +1016,7 @@ func::bin2hex() { } # Usage: -# func::escapeshellarg variable +# void func::escapeshellarg(string* variable) # # Escapes variable's content. func::escapeshellarg() { @@ -1028,7 +1028,7 @@ func::escapeshellarg() { } # Usage: -# func::floatval variable +# bool func::floatval(string* variable) # # Casts variable into float type. If it fails, returns 1. func::floatval() { @@ -1044,7 +1044,7 @@ func::floatval() { } # Usage: -# func::intval variable +# bool func::intval(string* variable) # # Casts variable into integer type. If it fails, returns 1. func::intval() { @@ -1088,7 +1088,7 @@ func::let() { } # Usage: -# func::print(string message...) > output +# void func::print(string message...) > output # # Print message to the standard output. While "echo" consumes flags, # func::print does not consume any flags, so this is theoretically safe. @@ -1097,7 +1097,7 @@ func::print() { } # Usage: -# func::println(string message...) > output +# void func::println(string message...) > output # # Print message to the standard output with a new line. While "echo" consumes # flags, func::println does not consume any flags, so this is theoretically @@ -1122,7 +1122,7 @@ func::str_replace() { } # Usage: -# func::strcpy destination source +# void func::strcpy(string* destination, string *source) # # Assigns the content of a variable specified as source into destination. func::strcpy() { @@ -1133,9 +1133,9 @@ func::strcpy() { } # Usage: -# func::strval variable +# void func::strval(string* variable) # -# Casts variable into string type. If it fails, returns 1. +# Casts variable into string type. func::strval() { local __strval_variable="$1" diff --git a/library/20-func/bin2hex.sh b/library/20-func/bin2hex.sh index 90314ed..d8f63f4 100644 --- a/library/20-func/bin2hex.sh +++ b/library/20-func/bin2hex.sh @@ -1,6 +1,6 @@ # Usage: -# func::bin2hex(string* destination, string data) -# func::bin2hex() < string > string +# void func::bin2hex(string* destination, string data) +# void func::bin2hex() < string > string # # Converts binary data into hexadecimal representation. func::bin2hex() { diff --git a/library/20-func/escapeshellarg.sh b/library/20-func/escapeshellarg.sh index 20971db..da7d03e 100644 --- a/library/20-func/escapeshellarg.sh +++ b/library/20-func/escapeshellarg.sh @@ -1,5 +1,5 @@ # Usage: -# func::escapeshellarg variable +# void func::escapeshellarg(string* variable) # # Escapes variable's content. func::escapeshellarg() { diff --git a/library/20-func/floatval.sh b/library/20-func/floatval.sh index b763927..fd1fcd5 100644 --- a/library/20-func/floatval.sh +++ b/library/20-func/floatval.sh @@ -1,5 +1,5 @@ # Usage: -# func::floatval variable +# bool func::floatval(string* variable) # # Casts variable into float type. If it fails, returns 1. func::floatval() { diff --git a/library/20-func/intval.sh b/library/20-func/intval.sh index caf2317..e984565 100644 --- a/library/20-func/intval.sh +++ b/library/20-func/intval.sh @@ -1,5 +1,5 @@ # Usage: -# func::intval variable +# bool func::intval(string* variable) # # Casts variable into integer type. If it fails, returns 1. func::intval() { diff --git a/library/20-func/print.sh b/library/20-func/print.sh index 2f0c8de..b0dca68 100644 --- a/library/20-func/print.sh +++ b/library/20-func/print.sh @@ -1,5 +1,5 @@ # Usage: -# func::print(string message...) > output +# void func::print(string message...) > output # # Print message to the standard output. While "echo" consumes flags, # func::print does not consume any flags, so this is theoretically safe. diff --git a/library/20-func/println.sh b/library/20-func/println.sh index 6d09561..86d33a9 100644 --- a/library/20-func/println.sh +++ b/library/20-func/println.sh @@ -1,5 +1,5 @@ # Usage: -# func::println(string message...) > output +# void func::println(string message...) > output # # Print message to the standard output with a new line. While "echo" consumes # flags, func::println does not consume any flags, so this is theoretically diff --git a/library/20-func/strcpy.sh b/library/20-func/strcpy.sh index ba8d0c3..b083b3a 100644 --- a/library/20-func/strcpy.sh +++ b/library/20-func/strcpy.sh @@ -1,5 +1,5 @@ # Usage: -# func::strcpy destination source +# void func::strcpy(string* destination, string *source) # # Assigns the content of a variable specified as source into destination. func::strcpy() { diff --git a/library/20-func/strval.sh b/library/20-func/strval.sh index 9f374d1..eae09fc 100644 --- a/library/20-func/strval.sh +++ b/library/20-func/strval.sh @@ -1,7 +1,7 @@ # Usage: -# func::strval variable +# void func::strval(string* variable) # -# Casts variable into string type. If it fails, returns 1. +# Casts variable into string type. func::strval() { local __strval_variable="$1" From 10268d13694b8f850fd453ce064edcac0311eb9b Mon Sep 17 00:00:00 2001 From: imos Date: Mon, 22 Sep 2014 01:08:03 +0900 Subject: [PATCH 19/58] Remove php::array_map. --- imosh | 20 +------------------- library/20-php-array_map.sh | 17 ----------------- test/php_array_map_test.sh | 5 ----- 3 files changed, 1 insertion(+), 41 deletions(-) delete mode 100644 library/20-php-array_map.sh delete mode 100644 test/php_array_map_test.sh diff --git a/imosh b/imosh index fe42ded..e5829ff 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-21 14:27:45 +0900 (6632927)' +IMOSH_VERSION='2014-09-21 14:38:26 +0900 (5bb905e)' if ! shopt login_shell >/dev/null; then set -e -u @@ -356,24 +356,6 @@ php::addslashes() { print "${subject}" } -php::array_map() { - if [ "$#" -ne 2 ]; then - LOG FATAL 'php::array_map requires two arguments.' - fi - - local __array_map_callback="${1}" - local __array_map_name="${2}" - eval "local __array_map_values=(\"\${${__array_map_name}[@]}\")" - local __array_map_i=0 __array_map_size="${#__array_map_values[@]}" - while (( __array_map_i < __array_map_size )); do - local __array_map_value="${__array_map_values[${__array_map_i}]}" - __array_map_value="$("${__array_map_callback}" "${__array_map_value}")" - eval "${__array_map_name}[${__array_map_i}]='$( - php::addslashes "${__array_map_value}")'" - (( __array_map_i += 1 )) || true - done -} - php::array_unique() { if [ "$#" -ne 1 ]; then LOG FATAL 'php::array_unique requires one argument.' diff --git a/library/20-php-array_map.sh b/library/20-php-array_map.sh deleted file mode 100644 index fc43f5b..0000000 --- a/library/20-php-array_map.sh +++ /dev/null @@ -1,17 +0,0 @@ -php::array_map() { - if [ "$#" -ne 2 ]; then - LOG FATAL 'php::array_map requires two arguments.' - fi - - local __array_map_callback="${1}" - local __array_map_name="${2}" - eval "local __array_map_values=(\"\${${__array_map_name}[@]}\")" - local __array_map_i=0 __array_map_size="${#__array_map_values[@]}" - while (( __array_map_i < __array_map_size )); do - local __array_map_value="${__array_map_values[${__array_map_i}]}" - __array_map_value="$("${__array_map_callback}" "${__array_map_value}")" - eval "${__array_map_name}[${__array_map_i}]='$( - php::addslashes "${__array_map_value}")'" - (( __array_map_i += 1 )) || true - done -} diff --git a/test/php_array_map_test.sh b/test/php_array_map_test.sh deleted file mode 100644 index a0705bb..0000000 --- a/test/php_array_map_test.sh +++ /dev/null @@ -1,5 +0,0 @@ -test::php::array_map() { - local values=('abc' 'DEF' 'Ghi') - php::array_map php::strtolower values - EXPECT_EQ 'abc;def;ghi' "$(php::implode ';' values)" -} From 99a98455bbe74525bfa09c10b2d8d9b47b675ed7 Mon Sep 17 00:00:00 2001 From: imos Date: Mon, 22 Sep 2014 01:32:00 +0900 Subject: [PATCH 20/58] Add func::(r|l|)trim. --- imosh | 32 +++++++++++++++++++++++++++++++- library/20-func/ltrim.sh | 9 +++++++++ library/20-func/rtrim.sh | 9 +++++++++ library/20-func/trim.sh | 9 +++++++++ test/func/ltrim_test.sh | 31 +++++++++++++++++++++++++++++++ test/func/rtrim_test.sh | 31 +++++++++++++++++++++++++++++++ test/func/trim_test.sh | 31 +++++++++++++++++++++++++++++++ 7 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 library/20-func/ltrim.sh create mode 100644 library/20-func/rtrim.sh create mode 100644 library/20-func/trim.sh create mode 100644 test/func/ltrim_test.sh create mode 100644 test/func/rtrim_test.sh create mode 100644 test/func/trim_test.sh diff --git a/imosh b/imosh index e5829ff..3f5755a 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-21 14:38:26 +0900 (5bb905e)' +IMOSH_VERSION='2014-09-22 01:08:03 +0900 (10268d1)' if ! shopt login_shell >/dev/null; then set -e -u @@ -1069,6 +1069,16 @@ func::let() { eval "${__let_destination}=\"\${__let_value}\"" } +# Usage: +# void func::ltrim(string* variable) +# +# Strips whitespace (or other characters) from the beginning of a string. +func::ltrim() { + local __ltrim_variable="$1" + + eval "${__ltrim_variable}=\"\${${__ltrim_variable}#\"\${${__ltrim_variable}%%[![:space:]]*}\"}\"" +} + # Usage: # void func::print(string message...) > output # @@ -1088,6 +1098,16 @@ func::println() { printf "%s\n" "$*" } +# Usage: +# void func::rtrim(string* variable) +# +# Strips whitespace (or other characters) from the end of a string. +func::rtrim() { + local __rtrim_variable="$1" + + eval "${__rtrim_variable}=\"\${${__rtrim_variable}%\"\${${__rtrim_variable}##*[![:space:]]}\"}\"" +} + # Usage: # void func::str_replace(string* subject, string search, string replace) # @@ -1124,6 +1144,16 @@ func::strval() { eval "${__strval_variable}=\"\${${__strval_variable}}\"" } +# Usage: +# void func::trim(string* variable) +# +# Strips whitespace (or other characters) from the beginning and end of a +# string. +func::trim() { + func::rtrim "$1" + func::ltrim "$1" +} + imosh::internal::convert_type() { local type="$1"; shift local value="$1"; shift diff --git a/library/20-func/ltrim.sh b/library/20-func/ltrim.sh new file mode 100644 index 0000000..fced60b --- /dev/null +++ b/library/20-func/ltrim.sh @@ -0,0 +1,9 @@ +# Usage: +# void func::ltrim(string* variable) +# +# Strips whitespace (or other characters) from the beginning of a string. +func::ltrim() { + local __ltrim_variable="$1" + + eval "${__ltrim_variable}=\"\${${__ltrim_variable}#\"\${${__ltrim_variable}%%[![:space:]]*}\"}\"" +} diff --git a/library/20-func/rtrim.sh b/library/20-func/rtrim.sh new file mode 100644 index 0000000..50d2bb7 --- /dev/null +++ b/library/20-func/rtrim.sh @@ -0,0 +1,9 @@ +# Usage: +# void func::rtrim(string* variable) +# +# Strips whitespace (or other characters) from the end of a string. +func::rtrim() { + local __rtrim_variable="$1" + + eval "${__rtrim_variable}=\"\${${__rtrim_variable}%\"\${${__rtrim_variable}##*[![:space:]]}\"}\"" +} diff --git a/library/20-func/trim.sh b/library/20-func/trim.sh new file mode 100644 index 0000000..fe57b41 --- /dev/null +++ b/library/20-func/trim.sh @@ -0,0 +1,9 @@ +# Usage: +# void func::trim(string* variable) +# +# Strips whitespace (or other characters) from the beginning and end of a +# string. +func::trim() { + func::rtrim "$1" + func::ltrim "$1" +} diff --git a/test/func/ltrim_test.sh b/test/func/ltrim_test.sh new file mode 100644 index 0000000..1223bc5 --- /dev/null +++ b/test/func/ltrim_test.sh @@ -0,0 +1,31 @@ +test::func_ltrim() { + local variable='' + + variable=' abc def ' + func::ltrim variable + EXPECT_EQ 'abc def ' "${variable}" + + variable=$'\t\n\r \t\n\rabc def ' + func::ltrim variable + EXPECT_EQ 'abc def ' "${variable}" + + variable='abc def' + func::ltrim variable + EXPECT_EQ 'abc def' "${variable}" + + variable='' + func::ltrim variable + EXPECT_EQ '' "${variable}" + + variable=' ' + func::ltrim variable + EXPECT_EQ '' "${variable}" + + variable=' ' + func::ltrim variable + EXPECT_EQ '' "${variable}" + + variable=$'\t\n\r \t\n\r' + func::ltrim variable + EXPECT_EQ '' "${variable}" +} diff --git a/test/func/rtrim_test.sh b/test/func/rtrim_test.sh new file mode 100644 index 0000000..0591fd2 --- /dev/null +++ b/test/func/rtrim_test.sh @@ -0,0 +1,31 @@ +test::func_rtrim() { + local variable='' + + variable=' abc def ' + func::rtrim variable + EXPECT_EQ ' abc def' "${variable}" + + variable=$' abc def\t\n\r \t\n\r' + func::rtrim variable + EXPECT_EQ ' abc def' "${variable}" + + variable='abc def' + func::rtrim variable + EXPECT_EQ 'abc def' "${variable}" + + variable='' + func::rtrim variable + EXPECT_EQ '' "${variable}" + + variable=' ' + func::rtrim variable + EXPECT_EQ '' "${variable}" + + variable=' ' + func::rtrim variable + EXPECT_EQ '' "${variable}" + + variable=$'\t\n\r \t\n\r' + func::rtrim variable + EXPECT_EQ '' "${variable}" +} diff --git a/test/func/trim_test.sh b/test/func/trim_test.sh new file mode 100644 index 0000000..b715f8b --- /dev/null +++ b/test/func/trim_test.sh @@ -0,0 +1,31 @@ +test::func_trim() { + local variable='' + + variable=' abc def ' + func::trim variable + EXPECT_EQ 'abc def' "${variable}" + + variable=$'\t\n\r \t\n\rabc def ' + func::trim variable + EXPECT_EQ 'abc def' "${variable}" + + variable='abc def' + func::trim variable + EXPECT_EQ 'abc def' "${variable}" + + variable='' + func::trim variable + EXPECT_EQ '' "${variable}" + + variable=' ' + func::trim variable + EXPECT_EQ '' "${variable}" + + variable=' ' + func::trim variable + EXPECT_EQ '' "${variable}" + + variable=$'\t\n\r \t\n\r' + func::trim variable + EXPECT_EQ '' "${variable}" +} From a3f00ac9651e6acd93f7a90c647363f2c89c3f9c Mon Sep 17 00:00:00 2001 From: imos Date: Mon, 22 Sep 2014 01:32:37 +0900 Subject: [PATCH 21/58] Remove php::(l|r|)trim. --- imosh | 17 +---------------- library/20-php-ltrim.sh | 4 ---- library/20-php-rtrim.sh | 4 ---- library/20-php-trim.sh | 4 ---- test/php_ltrim_test.sh | 9 --------- test/php_rtrim_test.sh | 9 --------- test/php_trim_test.sh | 9 --------- 7 files changed, 1 insertion(+), 55 deletions(-) delete mode 100644 library/20-php-ltrim.sh delete mode 100644 library/20-php-rtrim.sh delete mode 100644 library/20-php-trim.sh delete mode 100644 test/php_ltrim_test.sh delete mode 100644 test/php_rtrim_test.sh delete mode 100644 test/php_trim_test.sh diff --git a/imosh b/imosh index 3f5755a..909f5ed 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-22 01:08:03 +0900 (10268d1)' +IMOSH_VERSION='2014-09-22 01:32:00 +0900 (99a9845)' if ! shopt login_shell >/dev/null; then set -e -u @@ -430,11 +430,6 @@ php::isset() { return 0 } -php::ltrim() { - local value="$*" - print "${value#"${value%%[![:space:]]*}"}" -} - php::md5() { if which openssl >/dev/null 2>/dev/null; then print "${1}" | openssl md5 -binary | php::bin2hex @@ -494,11 +489,6 @@ php::rand() { print "${rand}" } -php::rtrim() { - local value="$*" - print "${value%"${value##*[![:space:]]}"}" -} - php::internal::set_pivot() { local pivot_index=0 (( pivot_index = left + (right - left) / 2 )) || true @@ -578,11 +568,6 @@ php::strtoupper() { print "$1" | tr '[a-z]' '[A-Z]' } -php::trim() { - local value="$*" - print "$(php::ltrim "$(php::rtrim "${value}")")" -} - imosh::set_pid() { if php::isset BASHPID; then IMOSH_PID="${BASHPID}" diff --git a/library/20-php-ltrim.sh b/library/20-php-ltrim.sh deleted file mode 100644 index c97f82c..0000000 --- a/library/20-php-ltrim.sh +++ /dev/null @@ -1,4 +0,0 @@ -php::ltrim() { - local value="$*" - print "${value#"${value%%[![:space:]]*}"}" -} diff --git a/library/20-php-rtrim.sh b/library/20-php-rtrim.sh deleted file mode 100644 index 0ce06a6..0000000 --- a/library/20-php-rtrim.sh +++ /dev/null @@ -1,4 +0,0 @@ -php::rtrim() { - local value="$*" - print "${value%"${value##*[![:space:]]}"}" -} diff --git a/library/20-php-trim.sh b/library/20-php-trim.sh deleted file mode 100644 index 43e3782..0000000 --- a/library/20-php-trim.sh +++ /dev/null @@ -1,4 +0,0 @@ -php::trim() { - local value="$*" - print "$(php::ltrim "$(php::rtrim "${value}")")" -} diff --git a/test/php_ltrim_test.sh b/test/php_ltrim_test.sh deleted file mode 100644 index 88a5c36..0000000 --- a/test/php_ltrim_test.sh +++ /dev/null @@ -1,9 +0,0 @@ -test::php::ltrim() { - EXPECT_EQ 'abc def ' "$(php::ltrim ' abc def '; echo)" - EXPECT_EQ 'abc def ' "$(php::ltrim $'\t\n\r \t\n\rabc def '; echo)" - EXPECT_EQ 'abc def' "$(php::ltrim $'abc def')" - EXPECT_EQ '' "$(php::ltrim $'')" - EXPECT_EQ '' "$(php::ltrim $' ')" - EXPECT_EQ '' "$(php::ltrim $' ')" - EXPECT_EQ '' "$(php::ltrim $'\t\n\r \t\n\r')" -} diff --git a/test/php_rtrim_test.sh b/test/php_rtrim_test.sh deleted file mode 100644 index 337cacd..0000000 --- a/test/php_rtrim_test.sh +++ /dev/null @@ -1,9 +0,0 @@ -test::php::rtrim() { - EXPECT_EQ ' abc def' "$(php::rtrim ' abc def ')" - EXPECT_EQ ' abc def' "$(php::rtrim $' abc def\t\n\r \t\n\r')" - EXPECT_EQ 'abc def' "$(php::rtrim $'abc def')" - EXPECT_EQ '' "$(php::rtrim $'')" - EXPECT_EQ '' "$(php::rtrim $' ')" - EXPECT_EQ '' "$(php::rtrim $' ')" - EXPECT_EQ '' "$(php::rtrim $'\t\n\r \t\n\r')" -} diff --git a/test/php_trim_test.sh b/test/php_trim_test.sh deleted file mode 100644 index 0d0ba74..0000000 --- a/test/php_trim_test.sh +++ /dev/null @@ -1,9 +0,0 @@ -test::php::trim() { - EXPECT_EQ 'abc def' "$(php::trim ' abc def ')" - EXPECT_EQ 'abc def' "$(php::trim $'\t\n\r \t\n\rabc def\t\n\r \t\n\r')" - EXPECT_EQ 'abc def' "$(php::trim $'abc def')" - EXPECT_EQ '' "$(php::trim $'')" - EXPECT_EQ '' "$(php::trim $' ')" - EXPECT_EQ '' "$(php::trim $' ')" - EXPECT_EQ '' "$(php::trim $'\t\n\r \t\n\r')" -} From ff432b4afb5e83099ae3c31f24cd7fc500533f1e Mon Sep 17 00:00:00 2001 From: imos Date: Mon, 22 Sep 2014 02:35:32 +0900 Subject: [PATCH 22/58] Add func::implode and func::explode. --- imosh | 42 +++++++++++++++++++++++++++++++++++++- library/20-func/explode.sh | 16 +++++++++++++++ library/20-func/implode.sh | 22 ++++++++++++++++++++ test/func/explode_test.sh | 16 +++++++++++++++ test/func/implode_test.sh | 17 +++++++++++++++ 5 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 library/20-func/explode.sh create mode 100644 library/20-func/implode.sh create mode 100644 test/func/explode_test.sh create mode 100644 test/func/implode_test.sh diff --git a/imosh b/imosh index 909f5ed..b3f28a3 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-22 01:32:00 +0900 (99a9845)' +IMOSH_VERSION='2014-09-22 01:32:37 +0900 (a3f00ac)' if ! shopt login_shell >/dev/null; then set -e -u @@ -994,6 +994,23 @@ func::escapeshellarg() { eval "${__escapeshellarg_variable}=\"'\${${__escapeshellarg_variable}//\${__escapeshellarg_search}/\${__escapeshellarg_replace}}'\"" } +# Usage: +# void func::explode(string* variable, string delimiter, string value) +# +# Splits a string by string. +func::explode() { + local __explode_variable="${1}" + local __explode_delimiter="${2}" + local __explode_value="${3}" + local __explode_result=() + + func::str_replace __explode_value "${__explode_delimiter}" $'\x02' + while IFS='' read -r -d $'\x02' __explode_term; do + __explode_result+=("${__explode_term}") + done <<<"${__explode_value}"$'\x02' + eval "${__explode_variable}=(\"\${__explode_result[@]}\")" +} + # Usage: # bool func::floatval(string* variable) # @@ -1010,6 +1027,29 @@ func::floatval() { fi } +# Usage: +# func::implode(string* variable, string glue, array* pieces) +# +# Join array elements with a string. +func::implode() { + local __implode_variable="${1}" + local __implode_glue="${2}" + local __implode_pieces=() + eval "local __implode_pieces=(\"\${${3}[@]}\")" + + local __implode_size="${#__implode_pieces[@]}" + local __implode_i=0 + local __implode_result='' + while (( __implode_i < __implode_size )); do + if (( __implode_i != 0 )); then + __implode_result+="${__implode_glue}" + fi + __implode_result+="${__implode_pieces[${__implode_i}]}" + (( __implode_i += 1 )) || true + done + func::let "${__implode_variable}" "${__implode_result}" +} + # Usage: # bool func::intval(string* variable) # diff --git a/library/20-func/explode.sh b/library/20-func/explode.sh new file mode 100644 index 0000000..da961e4 --- /dev/null +++ b/library/20-func/explode.sh @@ -0,0 +1,16 @@ +# Usage: +# void func::explode(string* variable, string delimiter, string value) +# +# Splits a string by string. +func::explode() { + local __explode_variable="${1}" + local __explode_delimiter="${2}" + local __explode_value="${3}" + local __explode_result=() + + func::str_replace __explode_value "${__explode_delimiter}" $'\x02' + while IFS='' read -r -d $'\x02' __explode_term; do + __explode_result+=("${__explode_term}") + done <<<"${__explode_value}"$'\x02' + eval "${__explode_variable}=(\"\${__explode_result[@]}\")" +} diff --git a/library/20-func/implode.sh b/library/20-func/implode.sh new file mode 100644 index 0000000..cc1abda --- /dev/null +++ b/library/20-func/implode.sh @@ -0,0 +1,22 @@ +# Usage: +# func::implode(string* variable, string glue, array* pieces) +# +# Join array elements with a string. +func::implode() { + local __implode_variable="${1}" + local __implode_glue="${2}" + local __implode_pieces=() + eval "local __implode_pieces=(\"\${${3}[@]}\")" + + local __implode_size="${#__implode_pieces[@]}" + local __implode_i=0 + local __implode_result='' + while (( __implode_i < __implode_size )); do + if (( __implode_i != 0 )); then + __implode_result+="${__implode_glue}" + fi + __implode_result+="${__implode_pieces[${__implode_i}]}" + (( __implode_i += 1 )) || true + done + func::let "${__implode_variable}" "${__implode_result}" +} diff --git a/test/func/explode_test.sh b/test/func/explode_test.sh new file mode 100644 index 0000000..9041ae5 --- /dev/null +++ b/test/func/explode_test.sh @@ -0,0 +1,16 @@ +test::func_explode() { + local values=() + local actual='' + + func::explode values ' ' 'abc def ghi' + func::implode actual ',' values + EXPECT_EQ 'abc,def,ghi' "${actual}" + + func::explode values 'xyz' $'ab\ncxyzde\tfxyzgh i' + func::implode actual ',' values + EXPECT_EQ $'ab\nc,de\tf,gh i' "${actual}" + + func::explode values ';' '\\;*;?;' + func::implode actual ',' values + EXPECT_EQ '\\,*,?,' "${actual}" +} diff --git a/test/func/implode_test.sh b/test/func/implode_test.sh new file mode 100644 index 0000000..5163099 --- /dev/null +++ b/test/func/implode_test.sh @@ -0,0 +1,17 @@ +test::func_implode() { + local values=() + + values=(a b c) + func::implode variable ' ' values + EXPECT_EQ 'a b c' "${variable}" + + func::implode variable 'xxx' values + EXPECT_EQ 'axxxbxxxc' "${variable}" + + values=(';' ' ' $'\n' '\' '') + func::implode variable ' ' values + EXPECT_EQ $'; \n \\ ' "${variable}" + + func::implode variable 'xxx' values + EXPECT_EQ $';xxx xxx\nxxx\\xxx' "${variable}" +} From 60332ac7191ad0c2a90e84befb2329809edb2917 Mon Sep 17 00:00:00 2001 From: imos Date: Mon, 22 Sep 2014 02:42:01 +0900 Subject: [PATCH 23/58] Remove php::explode. --- imosh | 20 +++++--------------- library/20-func/implode.sh | 2 +- library/20-php-explode.sh | 9 --------- library/20-php-preg_match.sh | 2 +- library/30-flags.sh | 4 ++-- test/php_explode_test.sh | 8 -------- 6 files changed, 9 insertions(+), 36 deletions(-) delete mode 100644 library/20-php-explode.sh delete mode 100644 test/php_explode_test.sh diff --git a/imosh b/imosh index b3f28a3..181d8e8 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-22 01:32:37 +0900 (a3f00ac)' +IMOSH_VERSION='2014-09-22 02:35:32 +0900 (ff432b4)' if ! shopt login_shell >/dev/null; then set -e -u @@ -385,16 +385,6 @@ php::bin2hex() { fi } -php::explode() { - local __explode_name="${1}" - local __explode_delimiter="${2}" - local __explode_value="${3}" - - __explode_value="$( - php::str_replace "${__explode_delimiter}" $'\x02' "${__explode_value}")" - eval "IFS=\$'\\x02' ${__explode_name}=(\$__explode_value)" -} - php::hex2bin() { local message="$( print "$*" | tr -c -d '[0-9a-fA-F]' | fold -w 2 \ @@ -458,7 +448,7 @@ php::preg_match() { echo implode(\"\\x02\", \$match); return 0;" __preg_match_result; then return 1 else - php::explode "${__preg_match_name}" $'\x02' "${__preg_match_result}" + func::explode "${__preg_match_name}" $'\x02' "${__preg_match_result}" fi } @@ -702,7 +692,7 @@ imosh::internal::flag_groups() { local imosh_group_exists=0 for flag_name in "${__IMOSH_FLAGS[@]}"; do local parts=() - php::explode parts ':' "${flag_name}" + func::explode parts ':' "${flag_name}" group="${parts[0]}" local lower_group="$(php::strtolower "${group}")" if [ "${lower_group}" == 'main' ]; then @@ -734,7 +724,7 @@ imosh::internal::group_flags() { local flags=() for flag_name in "${__IMOSH_FLAGS[@]}"; do local parts=() - php::explode parts ':' "${flag_name}" + func::explode parts ':' "${flag_name}" if [ "${lower_group}" != "$(php::strtolower "${parts[0]}")" ]; then continue fi @@ -1030,7 +1020,7 @@ func::floatval() { # Usage: # func::implode(string* variable, string glue, array* pieces) # -# Join array elements with a string. +# Joins array elements with a string. func::implode() { local __implode_variable="${1}" local __implode_glue="${2}" diff --git a/library/20-func/implode.sh b/library/20-func/implode.sh index cc1abda..b5d100a 100644 --- a/library/20-func/implode.sh +++ b/library/20-func/implode.sh @@ -1,7 +1,7 @@ # Usage: # func::implode(string* variable, string glue, array* pieces) # -# Join array elements with a string. +# Joins array elements with a string. func::implode() { local __implode_variable="${1}" local __implode_glue="${2}" diff --git a/library/20-php-explode.sh b/library/20-php-explode.sh deleted file mode 100644 index 0e07b1e..0000000 --- a/library/20-php-explode.sh +++ /dev/null @@ -1,9 +0,0 @@ -php::explode() { - local __explode_name="${1}" - local __explode_delimiter="${2}" - local __explode_value="${3}" - - __explode_value="$( - php::str_replace "${__explode_delimiter}" $'\x02' "${__explode_value}")" - eval "IFS=\$'\\x02' ${__explode_name}=(\$__explode_value)" -} diff --git a/library/20-php-preg_match.sh b/library/20-php-preg_match.sh index 1da82a4..7490c6c 100644 --- a/library/20-php-preg_match.sh +++ b/library/20-php-preg_match.sh @@ -12,6 +12,6 @@ php::preg_match() { echo implode(\"\\x02\", \$match); return 0;" __preg_match_result; then return 1 else - php::explode "${__preg_match_name}" $'\x02' "${__preg_match_result}" + func::explode "${__preg_match_name}" $'\x02' "${__preg_match_result}" fi } diff --git a/library/30-flags.sh b/library/30-flags.sh index 857a5dc..e792661 100644 --- a/library/30-flags.sh +++ b/library/30-flags.sh @@ -104,7 +104,7 @@ imosh::internal::flag_groups() { local imosh_group_exists=0 for flag_name in "${__IMOSH_FLAGS[@]}"; do local parts=() - php::explode parts ':' "${flag_name}" + func::explode parts ':' "${flag_name}" group="${parts[0]}" local lower_group="$(php::strtolower "${group}")" if [ "${lower_group}" == 'main' ]; then @@ -136,7 +136,7 @@ imosh::internal::group_flags() { local flags=() for flag_name in "${__IMOSH_FLAGS[@]}"; do local parts=() - php::explode parts ':' "${flag_name}" + func::explode parts ':' "${flag_name}" if [ "${lower_group}" != "$(php::strtolower "${parts[0]}")" ]; then continue fi diff --git a/test/php_explode_test.sh b/test/php_explode_test.sh deleted file mode 100644 index 7a42ad2..0000000 --- a/test/php_explode_test.sh +++ /dev/null @@ -1,8 +0,0 @@ -test::php::explode() { - local values=() - php::explode values ' ' 'abc def ghi' - EXPECT_EQ 'abc,def,ghi' "$(php::implode ',' values)" - local values=() - php::explode values 'xyz' $'ab\ncxyzde\tfxyzgh i' - EXPECT_EQ $'ab\nc,de\tf,gh i' "$(php::implode ',' values)" -} From 1793a4ad17730153f73923cb2b5d7d2e4460bc29 Mon Sep 17 00:00:00 2001 From: imos Date: Mon, 22 Sep 2014 03:08:47 +0900 Subject: [PATCH 24/58] Remove php::implode. --- imosh | 26 +++++++++----------------- library/20-func/implode.sh | 8 ++++++++ library/20-php-implode.sh | 15 --------------- test/base_test.sh | 4 ++-- test/php_array_unique_test.sh | 4 ++-- test/php_implode_test.sh | 8 -------- test/php_preg_match_test.sh | 4 ++-- test/php_sort_test.sh | 4 ++-- 8 files changed, 25 insertions(+), 48 deletions(-) delete mode 100644 library/20-php-implode.sh delete mode 100644 test/php_implode_test.sh diff --git a/imosh b/imosh index 181d8e8..6d30afd 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-22 02:35:32 +0900 (ff432b4)' +IMOSH_VERSION='2014-09-22 02:42:01 +0900 (60332ac)' if ! shopt login_shell >/dev/null; then set -e -u @@ -392,22 +392,6 @@ php::hex2bin() { printf "${message}" } -php::implode() { - local __implode_delimiter="${1}" - local __implode_name="${2}" - - eval "local __implode_values=(\"\${${__implode_name}[@]}\")" - local __implode_size="${#__implode_values[@]}" - local i=0 - local output='' - while (( i < __implode_size )); do - if (( i != 0 )); then output+="${__implode_delimiter}"; fi - output+="${__implode_values[${i}]}" - (( i += 1 )) || true - done - print "${output}" -} - # CAVEATS: # isset returns true for uninitialized variables in BASH 3, and returns # false for them in BASH 4. @@ -1019,9 +1003,17 @@ func::floatval() { # Usage: # func::implode(string* variable, string glue, array* pieces) +# func::implode(string glue, array* pieces) > result # # Joins array elements with a string. func::implode() { + if [ "$#" -eq 2 ]; then + local __implode_output='' + func::implode __implode_output "$1" "$2" + func::print "${__implode_output}" + return + fi + local __implode_variable="${1}" local __implode_glue="${2}" local __implode_pieces=() diff --git a/library/20-func/implode.sh b/library/20-func/implode.sh index b5d100a..cb7394d 100644 --- a/library/20-func/implode.sh +++ b/library/20-func/implode.sh @@ -1,8 +1,16 @@ # Usage: # func::implode(string* variable, string glue, array* pieces) +# func::implode(string glue, array* pieces) > result # # Joins array elements with a string. func::implode() { + if [ "$#" -eq 2 ]; then + local __implode_output='' + func::implode __implode_output "$1" "$2" + func::print "${__implode_output}" + return + fi + local __implode_variable="${1}" local __implode_glue="${2}" local __implode_pieces=() diff --git a/library/20-php-implode.sh b/library/20-php-implode.sh deleted file mode 100644 index a23f6c7..0000000 --- a/library/20-php-implode.sh +++ /dev/null @@ -1,15 +0,0 @@ -php::implode() { - local __implode_delimiter="${1}" - local __implode_name="${2}" - - eval "local __implode_values=(\"\${${__implode_name}[@]}\")" - local __implode_size="${#__implode_values[@]}" - local i=0 - local output='' - while (( i < __implode_size )); do - if (( i != 0 )); then output+="${__implode_delimiter}"; fi - output+="${__implode_values[${i}]}" - (( i += 1 )) || true - done - print "${output}" -} diff --git a/test/base_test.sh b/test/base_test.sh index 1df8991..e112e2b 100644 --- a/test/base_test.sh +++ b/test/base_test.sh @@ -33,8 +33,8 @@ test::compare_string() { test::soh_in_array() { local values=($'\x01') local expected='01' - if [ "${expected}" != "$(php::bin2hex "$(php::implode '' values)")" ]; then + if [ "${expected}" != "$(php::bin2hex "$(func::implode '' values)")" ]; then LOG ERROR 'soh cannot be treated in array correctly:' \ - "$(php::bin2hex "$(php::implode '' values)")" + "$(php::bin2hex "$(func::implode '' values)")" fi } diff --git a/test/php_array_unique_test.sh b/test/php_array_unique_test.sh index 91771e7..ee0cb65 100644 --- a/test/php_array_unique_test.sh +++ b/test/php_array_unique_test.sh @@ -25,10 +25,10 @@ test::php::array_unique() { expected+=$'\x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 ' expected+=$'\x19 \x1a \x1b \x1c \x1d \x1e \x1f \x20' EXPECT_EQ "$(php::bin2hex "${expected}")" \ - "$(php::bin2hex "$(php::implode ' ' values)")" + "$(php::bin2hex "$(func::implode ' ' values)")" php::array_unique values EXPECT_EQ "$(php::bin2hex "${expected}")" \ - "$(php::bin2hex "$(php::implode ' ' values)")" + "$(php::bin2hex "$(func::implode ' ' values)")" local values=($'\x1a' $'\x11' "${c1}" $'\x16' $'\x09' $'\x03' $'\x1c' $'\x05' $'\x1d' $'\x1b' $'\x0a' $'\x19' $'\x1e' $'\x0e' $'\x15' $'\x0f' $'\x0d' $'\x08' $'\x04' $'\x13' $'\x02' $'\x07' $'\x1f' $'\x0c' diff --git a/test/php_implode_test.sh b/test/php_implode_test.sh deleted file mode 100644 index 8f42eb3..0000000 --- a/test/php_implode_test.sh +++ /dev/null @@ -1,8 +0,0 @@ -test::php::implode() { - local values=(a b c) - EXPECT_EQ 'a b c' "$(php::implode ' ' values)" - EXPECT_EQ 'axxxbxxxc' "$(php::implode 'xxx' values)" - local values=(';' ' ' $'\n' '') - EXPECT_EQ $'; \n ' "$(php::implode ' ' values)" - EXPECT_EQ $';xxx xxx\nxxx' "$(php::implode 'xxx' values)" -} diff --git a/test/php_preg_match_test.sh b/test/php_preg_match_test.sh index 9e251be..285c4c5 100644 --- a/test/php_preg_match_test.sh +++ b/test/php_preg_match_test.sh @@ -1,9 +1,9 @@ test::php::preg_match() { local match php::preg_match '%\d+%' 'abc012def345ghi' match - EXPECT_EQ '012' "$(php::implode ',' match)" + EXPECT_EQ '012' "$(func::implode ',' match)" php::preg_match '%(\d{4})-(\d{2})-(\d{2})%' 'date: 2014-08-04 12:13:14' match - EXPECT_EQ '2014-08-04,2014,08,04' "$(php::implode ',' match)" + EXPECT_EQ '2014-08-04,2014,08,04' "$(func::implode ',' match)" if php::preg_match '%\d+%' 'abcdefghi' match; then LOG FATAL 'abcdefghi should not match \d+.' fi diff --git a/test/php_sort_test.sh b/test/php_sort_test.sh index e84b659..06ec7a3 100644 --- a/test/php_sort_test.sh +++ b/test/php_sort_test.sh @@ -20,8 +20,8 @@ test::php::sort() { expected+=$'\x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 ' expected+=$'\x19 \x1a \x1b \x1c \x1d \x1e \x1f \x20' EXPECT_EQ "$(php::bin2hex "${expected}")" \ - "$(php::bin2hex "$(php::implode ' ' values)")" + "$(php::bin2hex "$(func::implode ' ' values)")" IFS= php::sort values EXPECT_EQ "$(php::bin2hex "${expected}")" \ - "$(php::bin2hex "$(php::implode ' ' values)")" + "$(php::bin2hex "$(func::implode ' ' values)")" } From 75aa50cf02fc88e44c8c61e4c18be341f12fadbd Mon Sep 17 00:00:00 2001 From: imos Date: Mon, 22 Sep 2014 03:15:37 +0900 Subject: [PATCH 25/58] Remove php::bin2hex. --- imosh | 25 ++++++++++--------------- library/20-func/bin2hex.sh | 11 +++++++---- library/20-php-bin2hex.sh | 7 ------- library/20-php-md5.sh | 4 ++-- test/base_test.sh | 4 ++-- test/php_array_unique_test.sh | 8 ++++---- test/php_bin2hex_test.sh | 4 ---- test/php_sort_test.sh | 8 ++++---- 8 files changed, 29 insertions(+), 42 deletions(-) delete mode 100644 library/20-php-bin2hex.sh delete mode 100644 test/php_bin2hex_test.sh diff --git a/imosh b/imosh index 6d30afd..9816681 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-22 02:42:01 +0900 (60332ac)' +IMOSH_VERSION='2014-09-22 03:08:47 +0900 (1793a4a)' if ! shopt login_shell >/dev/null; then set -e -u @@ -377,14 +377,6 @@ php::array_unique() { eval "${__array_unique_name}=(\"\${__array_unique_values[@]}\")" } -php::bin2hex() { - if [ "$#" -eq 0 ]; then - od -An -tx1 | tr -d ' \n' - else - print "$*" | php::bin2hex - fi -} - php::hex2bin() { local message="$( print "$*" | tr -c -d '[0-9a-fA-F]' | fold -w 2 \ @@ -406,9 +398,9 @@ php::isset() { php::md5() { if which openssl >/dev/null 2>/dev/null; then - print "${1}" | openssl md5 -binary | php::bin2hex + print "${1}" | openssl md5 -binary | func::bin2hex elif which md5sum >/dev/null 2>/dev/null; then - print "${1}" | md5sum -b | php::bin2hex + print "${1}" | md5sum -b | func::bin2hex else LOG FATAL 'no command for md5 is found.' fi @@ -937,16 +929,19 @@ IMOSH_COLOR_CYAN=$'\033[0;36m' IMOSH_COLOR_WHITE=$'\033[0;37m' # Usage: -# void func::bin2hex(string* destination, string data) -# void func::bin2hex() < string > string +# void func::bin2hex(string* hexadecimal_output, string binary_input) +# void func::bin2hex(string binary_input) > hexadecimal_output +# void func::bin2hex() < binary_input > hexadecimal_output # # Converts binary data into hexadecimal representation. func::bin2hex() { if [ "$#" -eq 0 ]; then od -An -tx1 | tr -d ' \n' return - fi - if [ "$#" -ne 2 ]; then + elif [ "$#" -eq 1 ]; then + func::bin2hex <<<"$1" + return + elif [ "$#" -ne 2 ]; then LOG FATAL "func::bin2hex requires two arguments, but $# arguments." return 1 fi diff --git a/library/20-func/bin2hex.sh b/library/20-func/bin2hex.sh index d8f63f4..568bde1 100644 --- a/library/20-func/bin2hex.sh +++ b/library/20-func/bin2hex.sh @@ -1,14 +1,17 @@ # Usage: -# void func::bin2hex(string* destination, string data) -# void func::bin2hex() < string > string +# void func::bin2hex(string* hexadecimal_output, string binary_input) +# void func::bin2hex(string binary_input) > hexadecimal_output +# void func::bin2hex() < binary_input > hexadecimal_output # # Converts binary data into hexadecimal representation. func::bin2hex() { if [ "$#" -eq 0 ]; then od -An -tx1 | tr -d ' \n' return - fi - if [ "$#" -ne 2 ]; then + elif [ "$#" -eq 1 ]; then + func::bin2hex <<<"$1" + return + elif [ "$#" -ne 2 ]; then LOG FATAL "func::bin2hex requires two arguments, but $# arguments." return 1 fi diff --git a/library/20-php-bin2hex.sh b/library/20-php-bin2hex.sh deleted file mode 100644 index 2b9fccb..0000000 --- a/library/20-php-bin2hex.sh +++ /dev/null @@ -1,7 +0,0 @@ -php::bin2hex() { - if [ "$#" -eq 0 ]; then - od -An -tx1 | tr -d ' \n' - else - print "$*" | php::bin2hex - fi -} diff --git a/library/20-php-md5.sh b/library/20-php-md5.sh index b97dcc2..a749391 100644 --- a/library/20-php-md5.sh +++ b/library/20-php-md5.sh @@ -1,8 +1,8 @@ php::md5() { if which openssl >/dev/null 2>/dev/null; then - print "${1}" | openssl md5 -binary | php::bin2hex + print "${1}" | openssl md5 -binary | func::bin2hex elif which md5sum >/dev/null 2>/dev/null; then - print "${1}" | md5sum -b | php::bin2hex + print "${1}" | md5sum -b | func::bin2hex else LOG FATAL 'no command for md5 is found.' fi diff --git a/test/base_test.sh b/test/base_test.sh index e112e2b..7f27078 100644 --- a/test/base_test.sh +++ b/test/base_test.sh @@ -33,8 +33,8 @@ test::compare_string() { test::soh_in_array() { local values=($'\x01') local expected='01' - if [ "${expected}" != "$(php::bin2hex "$(func::implode '' values)")" ]; then + if [ "${expected}" != "$(func::bin2hex "$(func::implode '' values)")" ]; then LOG ERROR 'soh cannot be treated in array correctly:' \ - "$(php::bin2hex "$(func::implode '' values)")" + "$(func::bin2hex "$(func::implode '' values)")" fi } diff --git a/test/php_array_unique_test.sh b/test/php_array_unique_test.sh index ee0cb65..9b62337 100644 --- a/test/php_array_unique_test.sh +++ b/test/php_array_unique_test.sh @@ -24,11 +24,11 @@ test::php::array_unique() { expected+=$'\x09 \x0a \x0b \x0c \x0d \x0e \x0f \x10 ' expected+=$'\x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 ' expected+=$'\x19 \x1a \x1b \x1c \x1d \x1e \x1f \x20' - EXPECT_EQ "$(php::bin2hex "${expected}")" \ - "$(php::bin2hex "$(func::implode ' ' values)")" + EXPECT_EQ "$(func::bin2hex "${expected}")" \ + "$(func::bin2hex "$(func::implode ' ' values)")" php::array_unique values - EXPECT_EQ "$(php::bin2hex "${expected}")" \ - "$(php::bin2hex "$(func::implode ' ' values)")" + EXPECT_EQ "$(func::bin2hex "${expected}")" \ + "$(func::bin2hex "$(func::implode ' ' values)")" local values=($'\x1a' $'\x11' "${c1}" $'\x16' $'\x09' $'\x03' $'\x1c' $'\x05' $'\x1d' $'\x1b' $'\x0a' $'\x19' $'\x1e' $'\x0e' $'\x15' $'\x0f' $'\x0d' $'\x08' $'\x04' $'\x13' $'\x02' $'\x07' $'\x1f' $'\x0c' diff --git a/test/php_bin2hex_test.sh b/test/php_bin2hex_test.sh deleted file mode 100644 index 13a023e..0000000 --- a/test/php_bin2hex_test.sh +++ /dev/null @@ -1,4 +0,0 @@ -test::php::bin2hex() { - EXPECT_EQ '686f6765' "$(php::bin2hex 'hoge')" - EXPECT_EQ 'e697a5e69cace8aa9e' "$(php::bin2hex '日本語')" -} diff --git a/test/php_sort_test.sh b/test/php_sort_test.sh index 06ec7a3..a9059ad 100644 --- a/test/php_sort_test.sh +++ b/test/php_sort_test.sh @@ -19,9 +19,9 @@ test::php::sort() { expected+=$'\x09 \x0a \x0b \x0c \x0d \x0e \x0f \x10 ' expected+=$'\x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 ' expected+=$'\x19 \x1a \x1b \x1c \x1d \x1e \x1f \x20' - EXPECT_EQ "$(php::bin2hex "${expected}")" \ - "$(php::bin2hex "$(func::implode ' ' values)")" + EXPECT_EQ "$(func::bin2hex "${expected}")" \ + "$(func::bin2hex "$(func::implode ' ' values)")" IFS= php::sort values - EXPECT_EQ "$(php::bin2hex "${expected}")" \ - "$(php::bin2hex "$(func::implode ' ' values)")" + EXPECT_EQ "$(func::bin2hex "${expected}")" \ + "$(func::bin2hex "$(func::implode ' ' values)")" } From c3fbafa6ea1cace44505f98e48ea4dee047d0e5a Mon Sep 17 00:00:00 2001 From: imos Date: Mon, 22 Sep 2014 03:27:25 +0900 Subject: [PATCH 26/58] Fix a bug of func::str_replace. --- imosh | 4 ++-- library/20-func/str_replace.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imosh b/imosh index 9816681..9080dac 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-22 03:08:47 +0900 (1793a4a)' +IMOSH_VERSION='2014-09-22 03:15:37 +0900 (75aa50c)' if ! shopt login_shell >/dev/null; then set -e -u @@ -1122,7 +1122,7 @@ func::str_replace() { local __str_replace_search="${2}" local __str_replace_replace="${3}" - eval "${__str_replace_subject_variable}=\"\${${__str_replace_subject_variable}//\${__str_replace_search}/\${__str_replace_replace}}\"" + eval "${__str_replace_subject_variable}=\"\${${__str_replace_subject_variable}//\"\${__str_replace_search}\"/\${__str_replace_replace}}\"" } # Usage: diff --git a/library/20-func/str_replace.sh b/library/20-func/str_replace.sh index e748c58..bcd1aa3 100644 --- a/library/20-func/str_replace.sh +++ b/library/20-func/str_replace.sh @@ -10,5 +10,5 @@ func::str_replace() { local __str_replace_search="${2}" local __str_replace_replace="${3}" - eval "${__str_replace_subject_variable}=\"\${${__str_replace_subject_variable}//\${__str_replace_search}/\${__str_replace_replace}}\"" + eval "${__str_replace_subject_variable}=\"\${${__str_replace_subject_variable}//\"\${__str_replace_search}\"/\${__str_replace_replace}}\"" } From 98572a4124ffaf19ce015da582841767c96955c5 Mon Sep 17 00:00:00 2001 From: imos Date: Mon, 22 Sep 2014 03:28:19 +0900 Subject: [PATCH 27/58] Update imosh. --- imosh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imosh b/imosh index 9080dac..7e3e11a 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-22 03:15:37 +0900 (75aa50c)' +IMOSH_VERSION='2014-09-22 03:27:25 +0900 (c3fbafa)' if ! shopt login_shell >/dev/null; then set -e -u From c4e5b3d9da1fb950c7fed4bc1d0650060e5eb449 Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 03:18:25 +0900 Subject: [PATCH 28/58] Add func::greg_match, func::greg_replace, EXPECT_TRUE and EXPECT_FALSE. --- imosh | 84 +++++++++++++++++++++++++++++++++ library/20-func/greg_match.sh | 25 ++++++++++ library/20-func/greg_replace.sh | 21 +++++++++ library/90-testing/assert.sh | 9 ++++ library/90-testing/boolean.sh | 25 ++++++++++ test/func/greg_match_test.sh | 6 +++ test/func/greg_replace_test.sh | 19 ++++++++ 7 files changed, 189 insertions(+) create mode 100644 library/20-func/greg_match.sh create mode 100644 library/20-func/greg_replace.sh create mode 100644 library/90-testing/assert.sh create mode 100644 library/90-testing/boolean.sh create mode 100644 test/func/greg_match_test.sh create mode 100644 test/func/greg_replace_test.sh diff --git a/imosh b/imosh index 7e3e11a..a5677e9 100755 --- a/imosh +++ b/imosh @@ -996,6 +996,54 @@ func::floatval() { fi } +# Usage: +# void func::greg_match(string pattern, string subject) +# +# Replace pattern with replace in *subject. +func::greg_match() { + if ! shopt extglob >/dev/null; then + shopt -s extglob + func::greg_match "$@" + local result="$?" + shopt -u extglob + return "${result}" + fi + + if [ "$#" -ne 2 ]; then + LOG FATAL 'func::greg_match takes exactly 2 arguments.' + fi + local __greg_match_pattern="${1}" + local __greg_match_subject="${2}" + + if [[ "${__greg_match_subject}" = ${__greg_match_pattern} ]]; then + return 0 + else + return 1 + fi +} + +# Usage: +# void func::greg_replace(string* subject, string pattern, string replace) +# +# Replace pattern with replace in *subject. +func::greg_replace() { + if ! shopt extglob >/dev/null; then + shopt -s extglob + func::greg_replace "$@" + shopt -u extglob + return "$?" + fi + + if [ "$#" -ne 3 ]; then + LOG FATAL 'func::greg_replace takes exactly 3 arguments.' + fi + local __greg_replace_subject_variable="${1}" + local __greg_replace_search="${2}" + local __greg_replace_replace="${3}" + + eval "${__greg_replace_subject_variable}=\"\${${__greg_replace_subject_variable}//\${__greg_replace_search}/\${__greg_replace_replace}}\"" +} + # Usage: # func::implode(string* variable, string glue, array* pieces) # func::implode(string glue, array* pieces) > result @@ -1200,5 +1248,41 @@ DEFINE_bool --group=imosh 'help_groff' false \ DEFINE_bool --group=imosh disown_php false 'Disown a PHP process.' +ASSERT() { + local last_state="${IMOSH_TEST_IS_FAILED}" + IMOSH_TEST_IS_FAILED=0 + "$@" + if (( IMOSH_TEST_IS_FAILED )); then + exit 1 + fi + IMOSH_TEST_IS_FAILED="${last_state}" +} + +EXPECT_TRUE() { + if ! "$@"; then + echo ' Actual: false' >&2 + echo 'Expected: true' >&2 + IMOSH_TEST_IS_FAILED=1 + return 1 + fi +} + +EXPECT_FALSE() { + if "$@"; then + echo ' Actual: true' >&2 + echo 'Expected: false' >&2 + IMOSH_TEST_IS_FAILED=1 + return 1 + fi +} + +ASSERT_TRUE() { + ASSERT EXPECT_TRUE "$@" +} + +ASSERT_FALSE() { + ASSERT EXPECT_FALSE "$@" +} + LOG INFO 'imosh is ready.' diff --git a/library/20-func/greg_match.sh b/library/20-func/greg_match.sh new file mode 100644 index 0000000..e40c1ca --- /dev/null +++ b/library/20-func/greg_match.sh @@ -0,0 +1,25 @@ +# Usage: +# void func::greg_match(string pattern, string subject) +# +# Replace pattern with replace in *subject. +func::greg_match() { + if ! shopt extglob >/dev/null; then + shopt -s extglob + func::greg_match "$@" + local result="$?" + shopt -u extglob + return "${result}" + fi + + if [ "$#" -ne 2 ]; then + LOG FATAL 'func::greg_match takes exactly 2 arguments.' + fi + local __greg_match_pattern="${1}" + local __greg_match_subject="${2}" + + if [[ "${__greg_match_subject}" = ${__greg_match_pattern} ]]; then + return 0 + else + return 1 + fi +} diff --git a/library/20-func/greg_replace.sh b/library/20-func/greg_replace.sh new file mode 100644 index 0000000..3a9870d --- /dev/null +++ b/library/20-func/greg_replace.sh @@ -0,0 +1,21 @@ +# Usage: +# void func::greg_replace(string* subject, string pattern, string replace) +# +# Replace pattern with replace in *subject. +func::greg_replace() { + if ! shopt extglob >/dev/null; then + shopt -s extglob + func::greg_replace "$@" + shopt -u extglob + return "$?" + fi + + if [ "$#" -ne 3 ]; then + LOG FATAL 'func::greg_replace takes exactly 3 arguments.' + fi + local __greg_replace_subject_variable="${1}" + local __greg_replace_search="${2}" + local __greg_replace_replace="${3}" + + eval "${__greg_replace_subject_variable}=\"\${${__greg_replace_subject_variable}//\${__greg_replace_search}/\${__greg_replace_replace}}\"" +} diff --git a/library/90-testing/assert.sh b/library/90-testing/assert.sh new file mode 100644 index 0000000..f9427c1 --- /dev/null +++ b/library/90-testing/assert.sh @@ -0,0 +1,9 @@ +ASSERT() { + local last_state="${IMOSH_TEST_IS_FAILED}" + IMOSH_TEST_IS_FAILED=0 + "$@" + if (( IMOSH_TEST_IS_FAILED )); then + exit 1 + fi + IMOSH_TEST_IS_FAILED="${last_state}" +} diff --git a/library/90-testing/boolean.sh b/library/90-testing/boolean.sh new file mode 100644 index 0000000..f184a0b --- /dev/null +++ b/library/90-testing/boolean.sh @@ -0,0 +1,25 @@ +EXPECT_TRUE() { + if ! "$@"; then + echo ' Actual: false' >&2 + echo 'Expected: true' >&2 + IMOSH_TEST_IS_FAILED=1 + return 1 + fi +} + +EXPECT_FALSE() { + if "$@"; then + echo ' Actual: true' >&2 + echo 'Expected: false' >&2 + IMOSH_TEST_IS_FAILED=1 + return 1 + fi +} + +ASSERT_TRUE() { + ASSERT EXPECT_TRUE "$@" +} + +ASSERT_FALSE() { + ASSERT EXPECT_FALSE "$@" +} diff --git a/test/func/greg_match_test.sh b/test/func/greg_match_test.sh new file mode 100644 index 0000000..7f7adbd --- /dev/null +++ b/test/func/greg_match_test.sh @@ -0,0 +1,6 @@ +test::func_greg_match() { + EXPECT_TRUE func::greg_match '*def*' 'abcdefghi' + EXPECT_FALSE func::greg_match '*xyz*' 'abcdefghi' + EXPECT_TRUE func::greg_match '*([a-z])' 'abcdefghi' + EXPECT_FALSE func::greg_match '*([a-z])' 'abc123ghi' +} diff --git a/test/func/greg_replace_test.sh b/test/func/greg_replace_test.sh new file mode 100644 index 0000000..7b0be29 --- /dev/null +++ b/test/func/greg_replace_test.sh @@ -0,0 +1,19 @@ +test::func_greg_replace() { + local variable + + variable='abc def ghi' + func::greg_replace variable '[[:space:]]' 'x' + EXPECT_EQ 'abcxdefxghi' "${variable}" + + variable='abc def ghi' + func::greg_replace variable '+( )' 'xyz' + EXPECT_EQ 'abcxyzdefxyzghi' "${variable}" + + variable='abcdefghi' + func::greg_replace variable '[beh]' 'x' + EXPECT_EQ 'axcdxfgxi' "${variable}" + + variable=$'abc\tdef\nghi' + func::greg_replace variable '[[:cntrl:][:print:]]' 'x' + EXPECT_EQ 'xxxxxxxxxxx' "${variable}" +} From 205db9415de3ee0fe207e50fde00b9756f0466c3 Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 03:54:44 +0900 Subject: [PATCH 29/58] Add CHECK. --- imosh | 65 +++++++++++++------ library/20-imosh/CHECK.sh | 5 ++ .../stack_trace.sh} | 12 ++++ library/20-php-preg_match.sh | 17 ----- library/90-testing/base.sh | 4 ++ library/90-testing/boolean.sh | 4 +- test/php_preg_match_test.sh | 10 --- 7 files changed, 67 insertions(+), 50 deletions(-) create mode 100644 library/20-imosh/CHECK.sh rename library/{20-stack_trace.sh => 20-imosh/stack_trace.sh} (63%) delete mode 100644 library/20-php-preg_match.sh create mode 100644 library/90-testing/base.sh delete mode 100644 test/php_preg_match_test.sh diff --git a/imosh b/imosh index a5677e9..905cee6 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-22 03:27:25 +0900 (c3fbafa)' +IMOSH_VERSION='2014-09-23 03:18:25 +0900 (c4e5b3d)' if ! shopt login_shell >/dev/null; then set -e -u @@ -544,24 +544,6 @@ imosh::set_pid() { fi } -# Shows a stack trace. Arguments are used as a message. -imosh::stack_trace() { - local max_depth="${#BASH_LINENO[@]}" - local i=0 - if [ "$*" = '' ]; then - echo 'imosh::stack_trace is called' >&2 - else - echo "$*" >&2 - fi - while (( i < max_depth - 1 )); do - local lineno="${BASH_LINENO[$((i))]}" - local file="${BASH_SOURCE[$((i+1))]}" - local function="${FUNCNAME[$((i+1))]}" - echo " at ${function} (${file}:${lineno})" >&2 - (( i += 1 )) || true - done -} - # __IMOSH_FLAGS_TYPE_= # __IMOSH_FLAGS_DESCRIPTION_= # __IMOSH_FLAGS_ALIASES=(from:to ...) @@ -1204,6 +1186,42 @@ func::trim() { func::ltrim "$1" } +CHECK() { + if ! "$@"; then + IFS=' ' eval 'imosh::stack_trace "*** Check failure: $* ***"' + fi +} + +# Usage: +# imosh::stack_trace [--skip_imosh] [message...] +# +# Shows a stack trace. Arguments are used as a message. +imosh::stack_trace() { + local ARGS_skip_imosh=0 + eval "${IMOSH_PARSE_ARGUMENTS}" + + local max_depth="${#BASH_LINENO[@]}" + local i=0 + if [ "$*" = '' ]; then + echo 'imosh::stack_trace is called' >&2 + else + echo "$*" >&2 + fi + while (( i < max_depth - 1 )); do + if [ "${BASH_SOURCE[$((i+1))]}" != "${BASH_SOURCE[0]}" ]; then + break + fi + (( i += 1 )) || true + done + while (( i < max_depth - 1 )); do + local lineno="${BASH_LINENO[$((i))]}" + local file="${BASH_SOURCE[$((i+1))]}" + local function="${FUNCNAME[$((i+1))]}" + echo " at ${function} (${file}:${lineno})" >&2 + (( i += 1 )) || true + done +} + imosh::internal::convert_type() { local type="$1"; shift local value="$1"; shift @@ -1258,11 +1276,16 @@ ASSERT() { IMOSH_TEST_IS_FAILED="${last_state}" } +FAILURE() { + IMOSH_TEST_IS_FAILED=1 + imosh::stack_trace --skip_imosh '*** Check failure ***' +} + EXPECT_TRUE() { if ! "$@"; then echo ' Actual: false' >&2 echo 'Expected: true' >&2 - IMOSH_TEST_IS_FAILED=1 + FAILURE return 1 fi } @@ -1271,7 +1294,7 @@ EXPECT_FALSE() { if "$@"; then echo ' Actual: true' >&2 echo 'Expected: false' >&2 - IMOSH_TEST_IS_FAILED=1 + FAILURE return 1 fi } diff --git a/library/20-imosh/CHECK.sh b/library/20-imosh/CHECK.sh new file mode 100644 index 0000000..d2f97b0 --- /dev/null +++ b/library/20-imosh/CHECK.sh @@ -0,0 +1,5 @@ +CHECK() { + if ! "$@"; then + IFS=' ' eval 'imosh::stack_trace "*** Check failure: $* ***"' + fi +} diff --git a/library/20-stack_trace.sh b/library/20-imosh/stack_trace.sh similarity index 63% rename from library/20-stack_trace.sh rename to library/20-imosh/stack_trace.sh index bd69922..2e9a947 100644 --- a/library/20-stack_trace.sh +++ b/library/20-imosh/stack_trace.sh @@ -1,5 +1,11 @@ +# Usage: +# imosh::stack_trace [--skip_imosh] [message...] +# # Shows a stack trace. Arguments are used as a message. imosh::stack_trace() { + local ARGS_skip_imosh=0 + eval "${IMOSH_PARSE_ARGUMENTS}" + local max_depth="${#BASH_LINENO[@]}" local i=0 if [ "$*" = '' ]; then @@ -7,6 +13,12 @@ imosh::stack_trace() { else echo "$*" >&2 fi + while (( i < max_depth - 1 )); do + if [ "${BASH_SOURCE[$((i+1))]}" != "${BASH_SOURCE[0]}" ]; then + break + fi + (( i += 1 )) || true + done while (( i < max_depth - 1 )); do local lineno="${BASH_LINENO[$((i))]}" local file="${BASH_SOURCE[$((i+1))]}" diff --git a/library/20-php-preg_match.sh b/library/20-php-preg_match.sh deleted file mode 100644 index 7490c6c..0000000 --- a/library/20-php-preg_match.sh +++ /dev/null @@ -1,17 +0,0 @@ -php::preg_match() { - local __preg_match_pattern="${1}" - local __preg_match_subject="${2}" - local __preg_match_name='' - - if [ "$#" -ge 3 ]; then __preg_match_name="${3}"; fi - local __preg_match_result - if ! php::internal::run " - if (!preg_match('$(php::addslashes "${__preg_match_pattern}")', - '$(php::addslashes "${__preg_match_subject}")', - \$match)) { return 1; } - echo implode(\"\\x02\", \$match); return 0;" __preg_match_result; then - return 1 - else - func::explode "${__preg_match_name}" $'\x02' "${__preg_match_result}" - fi -} diff --git a/library/90-testing/base.sh b/library/90-testing/base.sh new file mode 100644 index 0000000..2af22de --- /dev/null +++ b/library/90-testing/base.sh @@ -0,0 +1,4 @@ +FAILURE() { + IMOSH_TEST_IS_FAILED=1 + imosh::stack_trace --skip_imosh '*** Check failure ***' +} diff --git a/library/90-testing/boolean.sh b/library/90-testing/boolean.sh index f184a0b..73a2ab9 100644 --- a/library/90-testing/boolean.sh +++ b/library/90-testing/boolean.sh @@ -2,7 +2,7 @@ EXPECT_TRUE() { if ! "$@"; then echo ' Actual: false' >&2 echo 'Expected: true' >&2 - IMOSH_TEST_IS_FAILED=1 + FAILURE return 1 fi } @@ -11,7 +11,7 @@ EXPECT_FALSE() { if "$@"; then echo ' Actual: true' >&2 echo 'Expected: false' >&2 - IMOSH_TEST_IS_FAILED=1 + FAILURE return 1 fi } diff --git a/test/php_preg_match_test.sh b/test/php_preg_match_test.sh deleted file mode 100644 index 285c4c5..0000000 --- a/test/php_preg_match_test.sh +++ /dev/null @@ -1,10 +0,0 @@ -test::php::preg_match() { - local match - php::preg_match '%\d+%' 'abc012def345ghi' match - EXPECT_EQ '012' "$(func::implode ',' match)" - php::preg_match '%(\d{4})-(\d{2})-(\d{2})%' 'date: 2014-08-04 12:13:14' match - EXPECT_EQ '2014-08-04,2014,08,04' "$(func::implode ',' match)" - if php::preg_match '%\d+%' 'abcdefghi' match; then - LOG FATAL 'abcdefghi should not match \d+.' - fi -} From a107aec078c60bd490c65dff41958e31e604d437 Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 04:57:28 +0900 Subject: [PATCH 30/58] Remove php::isset. --- imosh | 52 ++++++++--------------------------- library/20-log.sh | 6 ++-- library/20-parse_arguments.sh | 8 +++--- library/20-php-isset.sh | 11 -------- library/20-pid.sh | 2 +- library/30-flags.sh | 4 +-- test/php_isset_test.sh | 22 --------------- 7 files changed, 21 insertions(+), 84 deletions(-) delete mode 100644 library/20-php-isset.sh delete mode 100644 test/php_isset_test.sh diff --git a/imosh b/imosh index 905cee6..623bc01 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-23 03:18:25 +0900 (c4e5b3d)' +IMOSH_VERSION='2014-09-23 03:54:44 +0900 (205db94)' if ! shopt login_shell >/dev/null; then set -e -u @@ -189,7 +189,7 @@ LOG() { datetime="${datetime/.N/.000000}" datetime="${datetime:0:20}" local pid - if php::isset __IMOSH_LOG_PID; then + if func::isset __IMOSH_LOG_PID; then pid="${__IMOSH_LOG_PID}" else imosh::set_pid @@ -209,11 +209,11 @@ LOG() { message+="$(imosh::stack_trace "*** LOG ${level} stack trace: ***" 2>&1)" fi local logtostderr=0 - if php::isset FLAGS_logtostderr; then + if func::isset FLAGS_logtostderr; then logtostderr="${FLAGS_logtostderr}" fi local alsologtostderr=0 - if php::isset FLAGS_alsologtostderr; then + if func::isset FLAGS_alsologtostderr; then alsologtostderr="${FLAGS_alsologtostderr}" fi case "${level}" in @@ -289,7 +289,7 @@ imosh::internal::parse_args() { arg_value="${arg:${#arg_name}}" if [ "${arg_value:0:1}" != '=' ]; then if [ "${arg_name:0:2}" = 'no' ]; then - if php::isset "${upper_class_name}S_${arg_name:2}"; then + if func::isset "${upper_class_name}S_${arg_name:2}"; then if [ "${class_name}" != 'flag' ] || \ [ "$(imosh::internal::flag_type "${arg_name:2}")" = 'bool' ]; then IMOSH_ARGS+=("${upper_class_name}S_${arg_name:2}=0") @@ -297,14 +297,14 @@ imosh::internal::parse_args() { fi fi fi - if php::isset "${upper_class_name}S_${arg_name}"; then + if func::isset "${upper_class_name}S_${arg_name}"; then if [ "${class_name}" != 'flag' ] || [ "$(imosh::internal::flag_type "${arg_name}")" = 'bool' ]; then IMOSH_ARGS+=("${upper_class_name}S_${arg_name}=1") continue fi fi - if ! php::isset "${upper_class_name}S_${arg_name}"; then + if ! func::isset "${upper_class_name}S_${arg_name}"; then LOG FATAL "no such bool ${class_name} is defined:" \ "(${upper_class_name}S_)${arg_name}" fi @@ -315,7 +315,7 @@ imosh::internal::parse_args() { shift fi arg_value="${arg_value:1}" - if php::isset "${upper_class_name}S_${arg_name}"; then + if func::isset "${upper_class_name}S_${arg_name}"; then if [ "${class_name}" = 'flag' ]; then if ! imosh::internal::convert_type \ "$(imosh::internal::flag_type "${arg_name}")" \ @@ -384,18 +384,6 @@ php::hex2bin() { printf "${message}" } -# CAVEATS: -# isset returns true for uninitialized variables in BASH 3, and returns -# false for them in BASH 4. -php::isset() { - local variable_name="$1" - - if [ "$(eval echo '${'"${variable_name}"'+set}')" = '' ]; then - return 1 - fi - return 0 -} - php::md5() { if which openssl >/dev/null 2>/dev/null; then print "${1}" | openssl md5 -binary | func::bin2hex @@ -410,24 +398,6 @@ php::ord() { printf '%d' \'"${1}" } -php::preg_match() { - local __preg_match_pattern="${1}" - local __preg_match_subject="${2}" - local __preg_match_name='' - - if [ "$#" -ge 3 ]; then __preg_match_name="${3}"; fi - local __preg_match_result - if ! php::internal::run " - if (!preg_match('$(php::addslashes "${__preg_match_pattern}")', - '$(php::addslashes "${__preg_match_subject}")', - \$match)) { return 1; } - echo implode(\"\\x02\", \$match); return 0;" __preg_match_result; then - return 1 - else - func::explode "${__preg_match_name}" $'\x02' "${__preg_match_result}" - fi -} - php::rand() { if [ "$#" -eq 0 ]; then php::rand 0 2147483647 @@ -535,7 +505,7 @@ php::strtoupper() { } imosh::set_pid() { - if php::isset BASHPID; then + if func::isset BASHPID; then IMOSH_PID="${BASHPID}" else local pid_file="$(mktemp "${__IMOSH_CORE_TMPDIR}/pid.XXXXXX")" @@ -572,7 +542,7 @@ imosh::internal::define_flag() { local group="$(php::strtoupper "${ARGS_group}")" # Change the default value based on its corresponding environment variable. - if php::isset "IMOSH_FLAGS_${name}"; then + if func::isset "IMOSH_FLAGS_${name}"; then default_value="$(eval print "\${IMOSH_FLAGS_${name}}")" fi if ! imosh::internal::convert_type \ @@ -580,7 +550,7 @@ imosh::internal::define_flag() { LOG FATAL "${type}'s default value should be ${type}: ${default_value}" fi default_value="$(imosh::internal::convert_type "${type}" "${default_value}")" - if php::isset "__IMOSH_FLAGS_TYPE_${name}"; then + if func::isset "__IMOSH_FLAGS_TYPE_${name}"; then LOG FATAL "already defined flag: ${name}" fi func::strcpy "FLAGS_${name}" 'default_value' diff --git a/library/20-log.sh b/library/20-log.sh index 8cd776c..685f742 100644 --- a/library/20-log.sh +++ b/library/20-log.sh @@ -23,7 +23,7 @@ LOG() { datetime="${datetime/.N/.000000}" datetime="${datetime:0:20}" local pid - if php::isset __IMOSH_LOG_PID; then + if func::isset __IMOSH_LOG_PID; then pid="${__IMOSH_LOG_PID}" else imosh::set_pid @@ -43,11 +43,11 @@ LOG() { message+="$(imosh::stack_trace "*** LOG ${level} stack trace: ***" 2>&1)" fi local logtostderr=0 - if php::isset FLAGS_logtostderr; then + if func::isset FLAGS_logtostderr; then logtostderr="${FLAGS_logtostderr}" fi local alsologtostderr=0 - if php::isset FLAGS_alsologtostderr; then + if func::isset FLAGS_alsologtostderr; then alsologtostderr="${FLAGS_alsologtostderr}" fi case "${level}" in diff --git a/library/20-parse_arguments.sh b/library/20-parse_arguments.sh index 3c80dd7..cd1f9e9 100644 --- a/library/20-parse_arguments.sh +++ b/library/20-parse_arguments.sh @@ -32,7 +32,7 @@ imosh::internal::parse_args() { arg_value="${arg:${#arg_name}}" if [ "${arg_value:0:1}" != '=' ]; then if [ "${arg_name:0:2}" = 'no' ]; then - if php::isset "${upper_class_name}S_${arg_name:2}"; then + if func::isset "${upper_class_name}S_${arg_name:2}"; then if [ "${class_name}" != 'flag' ] || \ [ "$(imosh::internal::flag_type "${arg_name:2}")" = 'bool' ]; then IMOSH_ARGS+=("${upper_class_name}S_${arg_name:2}=0") @@ -40,14 +40,14 @@ imosh::internal::parse_args() { fi fi fi - if php::isset "${upper_class_name}S_${arg_name}"; then + if func::isset "${upper_class_name}S_${arg_name}"; then if [ "${class_name}" != 'flag' ] || [ "$(imosh::internal::flag_type "${arg_name}")" = 'bool' ]; then IMOSH_ARGS+=("${upper_class_name}S_${arg_name}=1") continue fi fi - if ! php::isset "${upper_class_name}S_${arg_name}"; then + if ! func::isset "${upper_class_name}S_${arg_name}"; then LOG FATAL "no such bool ${class_name} is defined:" \ "(${upper_class_name}S_)${arg_name}" fi @@ -58,7 +58,7 @@ imosh::internal::parse_args() { shift fi arg_value="${arg_value:1}" - if php::isset "${upper_class_name}S_${arg_name}"; then + if func::isset "${upper_class_name}S_${arg_name}"; then if [ "${class_name}" = 'flag' ]; then if ! imosh::internal::convert_type \ "$(imosh::internal::flag_type "${arg_name}")" \ diff --git a/library/20-php-isset.sh b/library/20-php-isset.sh deleted file mode 100644 index 43193bb..0000000 --- a/library/20-php-isset.sh +++ /dev/null @@ -1,11 +0,0 @@ -# CAVEATS: -# isset returns true for uninitialized variables in BASH 3, and returns -# false for them in BASH 4. -php::isset() { - local variable_name="$1" - - if [ "$(eval echo '${'"${variable_name}"'+set}')" = '' ]; then - return 1 - fi - return 0 -} diff --git a/library/20-pid.sh b/library/20-pid.sh index 8f14e9f..d62b535 100644 --- a/library/20-pid.sh +++ b/library/20-pid.sh @@ -1,5 +1,5 @@ imosh::set_pid() { - if php::isset BASHPID; then + if func::isset BASHPID; then IMOSH_PID="${BASHPID}" else local pid_file="$(mktemp "${__IMOSH_CORE_TMPDIR}/pid.XXXXXX")" diff --git a/library/30-flags.sh b/library/30-flags.sh index e792661..afeaaba 100644 --- a/library/30-flags.sh +++ b/library/30-flags.sh @@ -26,7 +26,7 @@ imosh::internal::define_flag() { local group="$(php::strtoupper "${ARGS_group}")" # Change the default value based on its corresponding environment variable. - if php::isset "IMOSH_FLAGS_${name}"; then + if func::isset "IMOSH_FLAGS_${name}"; then default_value="$(eval print "\${IMOSH_FLAGS_${name}}")" fi if ! imosh::internal::convert_type \ @@ -34,7 +34,7 @@ imosh::internal::define_flag() { LOG FATAL "${type}'s default value should be ${type}: ${default_value}" fi default_value="$(imosh::internal::convert_type "${type}" "${default_value}")" - if php::isset "__IMOSH_FLAGS_TYPE_${name}"; then + if func::isset "__IMOSH_FLAGS_TYPE_${name}"; then LOG FATAL "already defined flag: ${name}" fi func::strcpy "FLAGS_${name}" 'default_value' diff --git a/test/php_isset_test.sh b/test/php_isset_test.sh deleted file mode 100644 index 623e57d..0000000 --- a/test/php_isset_test.sh +++ /dev/null @@ -1,22 +0,0 @@ -test::php::isset() { - if php::isset undefined_variable; then - LOG FATAL "undefined_variable should return false" - fi - local defined_variable=value - if ! php::isset defined_variable; then - LOG FATAL "defined_variable should return true" - fi - defined_variable= - if ! php::isset defined_variable; then - LOG FATAL "defined_variable should return true" - fi - local null_variable= - if ! php::isset null_variable; then - LOG FATAL "null_variable should return true" - fi - # isset's behavior for uninitialized variables is different in BASH versions. - # local uninitialized_variable - # if ! php::isset uninitialized_variable; then - # LOG FATAL "uninitialized_variable should return true" - # fi -} From 8a9cecfdcc1b34a3833ab89494f2a06fcaa56863 Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 05:06:24 +0900 Subject: [PATCH 31/58] Add func::addslashes. --- imosh | 13 ++++++++++++- library/20-func/addslashes.sh | 10 ++++++++++ test/func/addslashes_test.sh | 23 +++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 library/20-func/addslashes.sh create mode 100644 test/func/addslashes_test.sh diff --git a/imosh b/imosh index 623bc01..b42f1b5 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-23 03:54:44 +0900 (205db94)' +IMOSH_VERSION='2014-09-23 04:57:28 +0900 (a107aec)' if ! shopt login_shell >/dev/null; then set -e -u @@ -880,6 +880,17 @@ IMOSH_COLOR_MAGENTA=$'\033[0;35m' IMOSH_COLOR_CYAN=$'\033[0;36m' IMOSH_COLOR_WHITE=$'\033[0;37m' +# Usage: +# void func::addslashes(string* subject) +# +# Quotes string with backslashes. Single quote, double quote and backslash in +# subject are escaped. +func::addslashes() { + func::str_replace "${1}" '\' '\\' + func::str_replace "${1}" "'" "\\'" + func::str_replace "${1}" '"' '\"' +} + # Usage: # void func::bin2hex(string* hexadecimal_output, string binary_input) # void func::bin2hex(string binary_input) > hexadecimal_output diff --git a/library/20-func/addslashes.sh b/library/20-func/addslashes.sh new file mode 100644 index 0000000..285543c --- /dev/null +++ b/library/20-func/addslashes.sh @@ -0,0 +1,10 @@ +# Usage: +# void func::addslashes(string* subject) +# +# Quotes string with backslashes. Single quote, double quote and backslash in +# subject are escaped. +func::addslashes() { + func::str_replace "${1}" '\' '\\' + func::str_replace "${1}" "'" "\\'" + func::str_replace "${1}" '"' '\"' +} diff --git a/test/func/addslashes_test.sh b/test/func/addslashes_test.sh new file mode 100644 index 0000000..3bb85e1 --- /dev/null +++ b/test/func/addslashes_test.sh @@ -0,0 +1,23 @@ +test::func_addslashes() { + local variable + + variable="abc\"def\\ghi'jkl" + func::addslashes variable + EXPECT_EQ "abc\\\"def\\\\ghi\\'jkl" "${variable}" + + variable='abcdef' + func::addslashes variable + EXPECT_EQ 'abcdef' "${variable}" + + variable='' + func::addslashes variable + EXPECT_EQ '' "${variable}" + + variable=' ' + func::addslashes variable + EXPECT_EQ ' ' "${variable}" + + variable=$'abc\tdef\nghi' + func::addslashes variable + EXPECT_EQ $'abc\tdef\nghi' "${variable}" +} From bd767744c253ff7247d8914cf506ca0a00726878 Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 05:07:05 +0900 Subject: [PATCH 32/58] Remove php::addslashes. --- imosh | 13 +------------ library/20-php-add_slashes.sh | 10 ---------- 2 files changed, 1 insertion(+), 22 deletions(-) delete mode 100644 library/20-php-add_slashes.sh diff --git a/imosh b/imosh index b42f1b5..d4a2e66 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-23 04:57:28 +0900 (a107aec)' +IMOSH_VERSION='2014-09-23 05:06:24 +0900 (8a9cecf)' if ! shopt login_shell >/dev/null; then set -e -u @@ -345,17 +345,6 @@ readonly IMOSH_PARSE_ARGUMENTS=' set -- "${IMOSH_ARGV[@]}" fi' -php::addslashes() { - if [ "$#" -ne 1 ]; then - LOG FATAL 'php::addslashes requires one argument.' - fi - - local subject="${1}" - subject="$(php::str_replace '\' '\\' "${subject}")" - subject="$(php::str_replace "'" "\\'" "${subject}")" - print "${subject}" -} - php::array_unique() { if [ "$#" -ne 1 ]; then LOG FATAL 'php::array_unique requires one argument.' diff --git a/library/20-php-add_slashes.sh b/library/20-php-add_slashes.sh deleted file mode 100644 index dfd1eb5..0000000 --- a/library/20-php-add_slashes.sh +++ /dev/null @@ -1,10 +0,0 @@ -php::addslashes() { - if [ "$#" -ne 1 ]; then - LOG FATAL 'php::addslashes requires one argument.' - fi - - local subject="${1}" - subject="$(php::str_replace '\' '\\' "${subject}")" - subject="$(php::str_replace "'" "\\'" "${subject}")" - print "${subject}" -} From 0c3fd4d18fb0d9b69b913d46d0bd47d24633790b Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 17:37:42 +0900 Subject: [PATCH 33/58] Add func::sort. --- imosh | 41 ++++++++++++++++++++++++++++++++++++++++- library/20-func/sort.sh | 38 ++++++++++++++++++++++++++++++++++++++ test/func/sort_test.sh | 27 +++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 library/20-func/sort.sh create mode 100644 test/func/sort_test.sh diff --git a/imosh b/imosh index d4a2e66..9765776 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-23 05:06:24 +0900 (8a9cecf)' +IMOSH_VERSION='2014-09-23 05:07:05 +0900 (bd76774)' if ! shopt login_shell >/dev/null; then set -e -u @@ -1110,6 +1110,45 @@ func::rtrim() { eval "${__rtrim_variable}=\"\${${__rtrim_variable}%\"\${${__rtrim_variable}##*[![:space:]]}\"}\"" } +__func::quick_sort() { + local size="${#__sort_values[@]}" + local pivot="${__sort_values[$(( size / 2 ))]}" + local values1=() values2=() values3=() + + for value in "${__sort_values[@]}"; do + if [ "${value}" \< "${pivot}" ]; then + values1+=("${value}") + elif [ "${value}" \> "${pivot}" ]; then + values3+=("${value}") + else + values2+=("${value}") + fi + done + func::sort values1 + func::sort values3 + __sort_values=() + if [ "${#values1[*]}" -ne 0 ]; then + __sort_values+=("${values1[@]}") + fi + if [ "${#values2[*]}" -ne 0 ]; then + __sort_values+=("${values2[@]}") + fi + if [ "${#values3[*]}" -ne 0 ]; then + __sort_values+=("${values3[@]}") + fi +} + +func::sort() { + local __sort_name="${1}" + eval "local __sort_size=\"\${#${__sort_name}[*]}\"" + if [ "${__sort_size}" -lt 2 ]; then + return + fi + eval "local __sort_values=(\"\${${__sort_name}[@]}\")" + __func::quick_sort + eval "${__sort_name}=(\"\${__sort_values[@]}\")" +} + # Usage: # void func::str_replace(string* subject, string search, string replace) # diff --git a/library/20-func/sort.sh b/library/20-func/sort.sh new file mode 100644 index 0000000..9f6a6ca --- /dev/null +++ b/library/20-func/sort.sh @@ -0,0 +1,38 @@ +__func::quick_sort() { + local size="${#__sort_values[@]}" + local pivot="${__sort_values[$(( size / 2 ))]}" + local values1=() values2=() values3=() + + for value in "${__sort_values[@]}"; do + if [ "${value}" \< "${pivot}" ]; then + values1+=("${value}") + elif [ "${value}" \> "${pivot}" ]; then + values3+=("${value}") + else + values2+=("${value}") + fi + done + func::sort values1 + func::sort values3 + __sort_values=() + if [ "${#values1[*]}" -ne 0 ]; then + __sort_values+=("${values1[@]}") + fi + if [ "${#values2[*]}" -ne 0 ]; then + __sort_values+=("${values2[@]}") + fi + if [ "${#values3[*]}" -ne 0 ]; then + __sort_values+=("${values3[@]}") + fi +} + +func::sort() { + local __sort_name="${1}" + eval "local __sort_size=\"\${#${__sort_name}[*]}\"" + if [ "${__sort_size}" -lt 2 ]; then + return + fi + eval "local __sort_values=(\"\${${__sort_name}[@]}\")" + __func::quick_sort + eval "${__sort_name}=(\"\${__sort_values[@]}\")" +} diff --git a/test/func/sort_test.sh b/test/func/sort_test.sh new file mode 100644 index 0000000..6700d83 --- /dev/null +++ b/test/func/sort_test.sh @@ -0,0 +1,27 @@ +test::func_sort() { + local values=(w a c m d i n v y u q j g r x t z k h s e l o f b p) + func::sort values + EXPECT_EQ "a b c d e f g h i j k l m n o p q r s t u v w x y z" \ + "$(echo "${values[@]}")" + local values=(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20) + func::sort values + EXPECT_EQ "1 10 11 12 13 14 15 16 17 18 19 2 20 3 4 5 6 7 8 9" \ + "$(echo "${values[@]}")" + local i=1 + local c1=$'\x01' + local values=($'\x1a' $'\x11' "${c1}" $'\x16' $'\x09' $'\x03' $'\x1c' $'\x05' + $'\x1d' $'\x1b' $'\x0a' $'\x19' $'\x1e' $'\x0e' $'\x15' $'\x0f' + $'\x0d' $'\x08' $'\x04' $'\x13' $'\x02' $'\x07' $'\x1f' $'\x0c' + $'\x17' $'\x18' $'\x20' $'\x10' $'\x06' $'\x0b' $'\x12' $'\x14') + IFS= func::sort values + local expected='' + expected+=$'\x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 ' + expected+=$'\x09 \x0a \x0b \x0c \x0d \x0e \x0f \x10 ' + expected+=$'\x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 ' + expected+=$'\x19 \x1a \x1b \x1c \x1d \x1e \x1f \x20' + EXPECT_EQ "$(func::bin2hex "${expected}")" \ + "$(func::bin2hex "$(func::implode ' ' values)")" + IFS= func::sort values + EXPECT_EQ "$(func::bin2hex "${expected}")" \ + "$(func::bin2hex "$(func::implode ' ' values)")" +} From 4aed618024f1384ac6fc4ab1de89c8611f240f2a Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 17:41:00 +0900 Subject: [PATCH 34/58] Update tests for func::sort. --- imosh | 2 +- test/func/sort_test.sh | 22 ++++++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/imosh b/imosh index 9765776..282faf6 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-23 05:07:05 +0900 (bd76774)' +IMOSH_VERSION='2014-09-23 17:37:42 +0900 (0c3fd4d)' if ! shopt login_shell >/dev/null; then set -e -u diff --git a/test/func/sort_test.sh b/test/func/sort_test.sh index 6700d83..a9f2f65 100644 --- a/test/func/sort_test.sh +++ b/test/func/sort_test.sh @@ -1,19 +1,32 @@ test::func_sort() { + local values=() + EXPECT_TRUE func::sort values + + local values=('a') + EXPECT_TRUE func::sort values + EXPECT_EQ "a" "$(echo "${values[@]}")" + + local values=('b' 'a') + EXPECT_TRUE func::sort values + EXPECT_EQ "a b" "$(echo "${values[@]}")" + local values=(w a c m d i n v y u q j g r x t z k h s e l o f b p) - func::sort values + EXPECT_TRUE func::sort values EXPECT_EQ "a b c d e f g h i j k l m n o p q r s t u v w x y z" \ "$(echo "${values[@]}")" + local values=(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20) - func::sort values + EXPECT_TRUE func::sort values EXPECT_EQ "1 10 11 12 13 14 15 16 17 18 19 2 20 3 4 5 6 7 8 9" \ "$(echo "${values[@]}")" + local i=1 local c1=$'\x01' local values=($'\x1a' $'\x11' "${c1}" $'\x16' $'\x09' $'\x03' $'\x1c' $'\x05' $'\x1d' $'\x1b' $'\x0a' $'\x19' $'\x1e' $'\x0e' $'\x15' $'\x0f' $'\x0d' $'\x08' $'\x04' $'\x13' $'\x02' $'\x07' $'\x1f' $'\x0c' $'\x17' $'\x18' $'\x20' $'\x10' $'\x06' $'\x0b' $'\x12' $'\x14') - IFS= func::sort values + IFS= EXPECT_TRUE func::sort values local expected='' expected+=$'\x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 ' expected+=$'\x09 \x0a \x0b \x0c \x0d \x0e \x0f \x10 ' @@ -21,7 +34,8 @@ test::func_sort() { expected+=$'\x19 \x1a \x1b \x1c \x1d \x1e \x1f \x20' EXPECT_EQ "$(func::bin2hex "${expected}")" \ "$(func::bin2hex "$(func::implode ' ' values)")" - IFS= func::sort values + + IFS= EXPECT_TRUE func::sort values EXPECT_EQ "$(func::bin2hex "${expected}")" \ "$(func::bin2hex "$(func::implode ' ' values)")" } From 6afdbf62e370794fe6d4cbfcc5ea4dd1416ef234 Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 18:11:11 +0900 Subject: [PATCH 35/58] Replace php::strtolower and php::strtoupper with func::strtolower and func::strtoupper. --- imosh | 118 +++++++++++++++++++++++++++++----- library/20-func/strtolower.sh | 42 ++++++++++++ library/20-func/strtoupper.sh | 42 ++++++++++++ library/20-parse_arguments.sh | 3 +- library/20-php-strtolower.sh | 3 - library/20-php-strtoupper.sh | 3 - library/30-flags.sh | 21 ++++-- test/func/strtolower_test.sh | 26 ++++++++ test/func/strtoupper_test.sh | 26 ++++++++ test/php_strtolower_test.sh | 4 -- test/php_strtoupper_test.sh | 4 -- 11 files changed, 256 insertions(+), 36 deletions(-) create mode 100644 library/20-func/strtolower.sh create mode 100644 library/20-func/strtoupper.sh delete mode 100644 library/20-php-strtolower.sh delete mode 100644 library/20-php-strtoupper.sh create mode 100644 test/func/strtolower_test.sh create mode 100644 test/func/strtoupper_test.sh delete mode 100644 test/php_strtolower_test.sh delete mode 100644 test/php_strtoupper_test.sh diff --git a/imosh b/imosh index 282faf6..0b8a79e 100755 --- a/imosh +++ b/imosh @@ -259,7 +259,8 @@ LOG() { imosh::internal::parse_args() { local class_name="$1"; shift - local upper_class_name="$(php::strtoupper "${class_name}")" + local upper_class_name="${class_name}" + func::strtoupper upper_class_name local arg arg_name arg_value IMOSH_ARGV=() IMOSH_ARGS=() @@ -485,14 +486,6 @@ php::str_replace() { print "${subject//${search}/${replace}}" } -php::strtolower() { - print "$1" | tr '[A-Z]' '[a-z]' -} - -php::strtoupper() { - print "$1" | tr '[a-z]' '[A-Z]' -} - imosh::set_pid() { if func::isset BASHPID; then IMOSH_PID="${BASHPID}" @@ -528,7 +521,8 @@ imosh::internal::define_flag() { local name="$1"; shift local default_value="$1"; shift local description="$*" - local group="$(php::strtoupper "${ARGS_group}")" + local group="${ARGS_group}" + func::strtoupper group # Change the default value based on its corresponding environment variable. if func::isset "IMOSH_FLAGS_${name}"; then @@ -611,7 +605,8 @@ imosh::internal::flag_groups() { local parts=() func::explode parts ':' "${flag_name}" group="${parts[0]}" - local lower_group="$(php::strtolower "${group}")" + local lower_group="${group}" + func::strtolower lower_group if [ "${lower_group}" == 'main' ]; then main_group_exists=1 elif [ "${lower_group}" == 'imosh' ]; then @@ -636,13 +631,16 @@ imosh::internal::flag_groups() { imosh::internal::group_flags() { local group="$1" - local lower_group="$(php::strtolower "${group}")" + local lower_group="${group}" + func::strtolower lower_group local flags=() for flag_name in "${__IMOSH_FLAGS[@]}"; do local parts=() func::explode parts ':' "${flag_name}" - if [ "${lower_group}" != "$(php::strtolower "${parts[0]}")" ]; then + local lower_part="${parts[0]}" + func::strtolower lower_part + if [ "${lower_group}" != "${lower_part}" ]; then continue fi flags+=("${parts[1]}") @@ -663,7 +661,9 @@ imosh::internal::man() { echo '.SH OPTIONS' for flag_group in $(imosh::internal::flag_groups); do - echo ".SS $(php::strtoupper "${flag_group}") OPTIONS" + local upper_flag_group="${flag_group}" + func::strtoupper upper_flag_group + echo ".SS ${upper_flag_group} OPTIONS" for flag_name in $(imosh::internal::group_flags "${flag_group}"); do echo '.TP' echo -n '\fB' @@ -686,7 +686,9 @@ imosh::internal::help() { echo echo "OPTIONS:" for flag_group in $(imosh::internal::flag_groups); do - echo " $(php::strtoupper "${flag_group}") OPTIONS:" + local upper_flag_group="${flag_group}" + func::strtoupper upper_flag_group + echo " ${upper_flag_group} OPTIONS:" for flag_name in $(imosh::internal::group_flags "${flag_group}"); do eval "echo -n \" \${__IMOSH_FLAGS_DEFAULT_${flag_name}}:\"" eval "echo \" \${__IMOSH_FLAGS_DESCRIPTION_${flag_name}}\"" @@ -1175,6 +1177,92 @@ func::strcpy() { eval "${__strcpy_destination}=\"\${${__strcpy_source}}\"" } +# Usage: +# void func::strtolower(string* variable) +# void func::strtolower() < input > output +# +# Makes variable lowercase. +func::strtolower() { + if [ "$#" -eq 0 ]; then + tr '[A-Z]' '[a-z]' + return + fi + local __strtolower_variable="$1" + eval "local __strtolower_value=\"\${${__strtolower_variable}}\"" + # This is faster than tr for short strings. + # TODO(imos): Use ${variable,,} instead once Mac OSX supports BASH 4. + __strtolower_value="${__strtolower_value//A/a}" + __strtolower_value="${__strtolower_value//B/b}" + __strtolower_value="${__strtolower_value//C/c}" + __strtolower_value="${__strtolower_value//D/d}" + __strtolower_value="${__strtolower_value//E/e}" + __strtolower_value="${__strtolower_value//F/f}" + __strtolower_value="${__strtolower_value//G/g}" + __strtolower_value="${__strtolower_value//H/h}" + __strtolower_value="${__strtolower_value//I/i}" + __strtolower_value="${__strtolower_value//J/j}" + __strtolower_value="${__strtolower_value//K/k}" + __strtolower_value="${__strtolower_value//L/l}" + __strtolower_value="${__strtolower_value//M/m}" + __strtolower_value="${__strtolower_value//N/n}" + __strtolower_value="${__strtolower_value//O/o}" + __strtolower_value="${__strtolower_value//P/p}" + __strtolower_value="${__strtolower_value//Q/q}" + __strtolower_value="${__strtolower_value//R/r}" + __strtolower_value="${__strtolower_value//S/s}" + __strtolower_value="${__strtolower_value//T/t}" + __strtolower_value="${__strtolower_value//U/u}" + __strtolower_value="${__strtolower_value//V/v}" + __strtolower_value="${__strtolower_value//W/w}" + __strtolower_value="${__strtolower_value//X/x}" + __strtolower_value="${__strtolower_value//Y/y}" + __strtolower_value="${__strtolower_value//Z/z}" + eval "${__strtolower_variable}=\"\${__strtolower_value}\"" +} + +# Usage: +# void func::strtoupper(string* variable) +# void func::strtoupper() < input > output +# +# Makes variable uppercase. +func::strtoupper() { + if [ "$#" -eq 0 ]; then + tr '[a-z]' '[A-Z]' + return + fi + local __strtoupper_variable="$1" + eval "local __strtoupper_value=\"\${${__strtoupper_variable}}\"" + # This is faster than tr for short strings. + # TODO(imos): Use ${variable^^} instead once Mac OSX supports BASH 4. + __strtoupper_value="${__strtoupper_value//a/A}" + __strtoupper_value="${__strtoupper_value//b/B}" + __strtoupper_value="${__strtoupper_value//c/C}" + __strtoupper_value="${__strtoupper_value//d/D}" + __strtoupper_value="${__strtoupper_value//e/E}" + __strtoupper_value="${__strtoupper_value//f/F}" + __strtoupper_value="${__strtoupper_value//g/G}" + __strtoupper_value="${__strtoupper_value//h/H}" + __strtoupper_value="${__strtoupper_value//i/I}" + __strtoupper_value="${__strtoupper_value//j/J}" + __strtoupper_value="${__strtoupper_value//k/K}" + __strtoupper_value="${__strtoupper_value//l/L}" + __strtoupper_value="${__strtoupper_value//m/M}" + __strtoupper_value="${__strtoupper_value//n/N}" + __strtoupper_value="${__strtoupper_value//o/O}" + __strtoupper_value="${__strtoupper_value//p/P}" + __strtoupper_value="${__strtoupper_value//q/Q}" + __strtoupper_value="${__strtoupper_value//r/R}" + __strtoupper_value="${__strtoupper_value//s/S}" + __strtoupper_value="${__strtoupper_value//t/T}" + __strtoupper_value="${__strtoupper_value//u/U}" + __strtoupper_value="${__strtoupper_value//v/V}" + __strtoupper_value="${__strtoupper_value//w/W}" + __strtoupper_value="${__strtoupper_value//x/X}" + __strtoupper_value="${__strtoupper_value//y/Y}" + __strtoupper_value="${__strtoupper_value//z/Z}" + eval "${__strtoupper_variable}=\"\${__strtoupper_value}\"" +} + # Usage: # void func::strval(string* variable) # diff --git a/library/20-func/strtolower.sh b/library/20-func/strtolower.sh new file mode 100644 index 0000000..0e325c5 --- /dev/null +++ b/library/20-func/strtolower.sh @@ -0,0 +1,42 @@ +# Usage: +# void func::strtolower(string* variable) +# void func::strtolower() < input > output +# +# Makes variable lowercase. +func::strtolower() { + if [ "$#" -eq 0 ]; then + tr '[A-Z]' '[a-z]' + return + fi + local __strtolower_variable="$1" + eval "local __strtolower_value=\"\${${__strtolower_variable}}\"" + # This is faster than tr for short strings. + # TODO(imos): Use ${variable,,} instead once Mac OSX supports BASH 4. + __strtolower_value="${__strtolower_value//A/a}" + __strtolower_value="${__strtolower_value//B/b}" + __strtolower_value="${__strtolower_value//C/c}" + __strtolower_value="${__strtolower_value//D/d}" + __strtolower_value="${__strtolower_value//E/e}" + __strtolower_value="${__strtolower_value//F/f}" + __strtolower_value="${__strtolower_value//G/g}" + __strtolower_value="${__strtolower_value//H/h}" + __strtolower_value="${__strtolower_value//I/i}" + __strtolower_value="${__strtolower_value//J/j}" + __strtolower_value="${__strtolower_value//K/k}" + __strtolower_value="${__strtolower_value//L/l}" + __strtolower_value="${__strtolower_value//M/m}" + __strtolower_value="${__strtolower_value//N/n}" + __strtolower_value="${__strtolower_value//O/o}" + __strtolower_value="${__strtolower_value//P/p}" + __strtolower_value="${__strtolower_value//Q/q}" + __strtolower_value="${__strtolower_value//R/r}" + __strtolower_value="${__strtolower_value//S/s}" + __strtolower_value="${__strtolower_value//T/t}" + __strtolower_value="${__strtolower_value//U/u}" + __strtolower_value="${__strtolower_value//V/v}" + __strtolower_value="${__strtolower_value//W/w}" + __strtolower_value="${__strtolower_value//X/x}" + __strtolower_value="${__strtolower_value//Y/y}" + __strtolower_value="${__strtolower_value//Z/z}" + eval "${__strtolower_variable}=\"\${__strtolower_value}\"" +} diff --git a/library/20-func/strtoupper.sh b/library/20-func/strtoupper.sh new file mode 100644 index 0000000..3c76ccf --- /dev/null +++ b/library/20-func/strtoupper.sh @@ -0,0 +1,42 @@ +# Usage: +# void func::strtoupper(string* variable) +# void func::strtoupper() < input > output +# +# Makes variable uppercase. +func::strtoupper() { + if [ "$#" -eq 0 ]; then + tr '[a-z]' '[A-Z]' + return + fi + local __strtoupper_variable="$1" + eval "local __strtoupper_value=\"\${${__strtoupper_variable}}\"" + # This is faster than tr for short strings. + # TODO(imos): Use ${variable^^} instead once Mac OSX supports BASH 4. + __strtoupper_value="${__strtoupper_value//a/A}" + __strtoupper_value="${__strtoupper_value//b/B}" + __strtoupper_value="${__strtoupper_value//c/C}" + __strtoupper_value="${__strtoupper_value//d/D}" + __strtoupper_value="${__strtoupper_value//e/E}" + __strtoupper_value="${__strtoupper_value//f/F}" + __strtoupper_value="${__strtoupper_value//g/G}" + __strtoupper_value="${__strtoupper_value//h/H}" + __strtoupper_value="${__strtoupper_value//i/I}" + __strtoupper_value="${__strtoupper_value//j/J}" + __strtoupper_value="${__strtoupper_value//k/K}" + __strtoupper_value="${__strtoupper_value//l/L}" + __strtoupper_value="${__strtoupper_value//m/M}" + __strtoupper_value="${__strtoupper_value//n/N}" + __strtoupper_value="${__strtoupper_value//o/O}" + __strtoupper_value="${__strtoupper_value//p/P}" + __strtoupper_value="${__strtoupper_value//q/Q}" + __strtoupper_value="${__strtoupper_value//r/R}" + __strtoupper_value="${__strtoupper_value//s/S}" + __strtoupper_value="${__strtoupper_value//t/T}" + __strtoupper_value="${__strtoupper_value//u/U}" + __strtoupper_value="${__strtoupper_value//v/V}" + __strtoupper_value="${__strtoupper_value//w/W}" + __strtoupper_value="${__strtoupper_value//x/X}" + __strtoupper_value="${__strtoupper_value//y/Y}" + __strtoupper_value="${__strtoupper_value//z/Z}" + eval "${__strtoupper_variable}=\"\${__strtoupper_value}\"" +} diff --git a/library/20-parse_arguments.sh b/library/20-parse_arguments.sh index cd1f9e9..fb994ea 100644 --- a/library/20-parse_arguments.sh +++ b/library/20-parse_arguments.sh @@ -2,7 +2,8 @@ imosh::internal::parse_args() { local class_name="$1"; shift - local upper_class_name="$(php::strtoupper "${class_name}")" + local upper_class_name="${class_name}" + func::strtoupper upper_class_name local arg arg_name arg_value IMOSH_ARGV=() IMOSH_ARGS=() diff --git a/library/20-php-strtolower.sh b/library/20-php-strtolower.sh deleted file mode 100644 index 98062f0..0000000 --- a/library/20-php-strtolower.sh +++ /dev/null @@ -1,3 +0,0 @@ -php::strtolower() { - print "$1" | tr '[A-Z]' '[a-z]' -} diff --git a/library/20-php-strtoupper.sh b/library/20-php-strtoupper.sh deleted file mode 100644 index d6b92c4..0000000 --- a/library/20-php-strtoupper.sh +++ /dev/null @@ -1,3 +0,0 @@ -php::strtoupper() { - print "$1" | tr '[a-z]' '[A-Z]' -} diff --git a/library/30-flags.sh b/library/30-flags.sh index afeaaba..847dcb0 100644 --- a/library/30-flags.sh +++ b/library/30-flags.sh @@ -23,7 +23,8 @@ imosh::internal::define_flag() { local name="$1"; shift local default_value="$1"; shift local description="$*" - local group="$(php::strtoupper "${ARGS_group}")" + local group="${ARGS_group}" + func::strtoupper group # Change the default value based on its corresponding environment variable. if func::isset "IMOSH_FLAGS_${name}"; then @@ -106,7 +107,8 @@ imosh::internal::flag_groups() { local parts=() func::explode parts ':' "${flag_name}" group="${parts[0]}" - local lower_group="$(php::strtolower "${group}")" + local lower_group="${group}" + func::strtolower lower_group if [ "${lower_group}" == 'main' ]; then main_group_exists=1 elif [ "${lower_group}" == 'imosh' ]; then @@ -131,13 +133,16 @@ imosh::internal::flag_groups() { imosh::internal::group_flags() { local group="$1" - local lower_group="$(php::strtolower "${group}")" + local lower_group="${group}" + func::strtolower lower_group local flags=() for flag_name in "${__IMOSH_FLAGS[@]}"; do local parts=() func::explode parts ':' "${flag_name}" - if [ "${lower_group}" != "$(php::strtolower "${parts[0]}")" ]; then + local lower_part="${parts[0]}" + func::strtolower lower_part + if [ "${lower_group}" != "${lower_part}" ]; then continue fi flags+=("${parts[1]}") @@ -158,7 +163,9 @@ imosh::internal::man() { echo '.SH OPTIONS' for flag_group in $(imosh::internal::flag_groups); do - echo ".SS $(php::strtoupper "${flag_group}") OPTIONS" + local upper_flag_group="${flag_group}" + func::strtoupper upper_flag_group + echo ".SS ${upper_flag_group} OPTIONS" for flag_name in $(imosh::internal::group_flags "${flag_group}"); do echo '.TP' echo -n '\fB' @@ -181,7 +188,9 @@ imosh::internal::help() { echo echo "OPTIONS:" for flag_group in $(imosh::internal::flag_groups); do - echo " $(php::strtoupper "${flag_group}") OPTIONS:" + local upper_flag_group="${flag_group}" + func::strtoupper upper_flag_group + echo " ${upper_flag_group} OPTIONS:" for flag_name in $(imosh::internal::group_flags "${flag_group}"); do eval "echo -n \" \${__IMOSH_FLAGS_DEFAULT_${flag_name}}:\"" eval "echo \" \${__IMOSH_FLAGS_DESCRIPTION_${flag_name}}\"" diff --git a/test/func/strtolower_test.sh b/test/func/strtolower_test.sh new file mode 100644 index 0000000..172b56b --- /dev/null +++ b/test/func/strtolower_test.sh @@ -0,0 +1,26 @@ +test::func_strtolower() { + local variable='' + + variable='ABC def Ghi 123 ひらがな 漢字 カタカナ' + func::strtolower variable + EXPECT_EQ 'abc def ghi 123 ひらがな 漢字 カタカナ' "${variable}" + + variable='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' + func::strtolower variable + EXPECT_EQ 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789' \ + "${variable}" + + variable=$' !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' + func::strtolower variable + EXPECT_EQ $' !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' "${variable}" + + variable=$'\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0e\x0f\x10' + func::strtolower variable + EXPECT_EQ $'\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0e\x0f\x10' \ + "${variable}" + + variable=$'\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1e\x1f\x7f' + func::strtolower variable + EXPECT_EQ $'\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1e\x1f\x7f' \ + "${variable}" +} diff --git a/test/func/strtoupper_test.sh b/test/func/strtoupper_test.sh new file mode 100644 index 0000000..b136d1f --- /dev/null +++ b/test/func/strtoupper_test.sh @@ -0,0 +1,26 @@ +test::func_strtoupper() { + local variable='' + + variable='ABC def Ghi 123 ひらがな 漢字 カタカナ' + func::strtoupper variable + EXPECT_EQ 'ABC DEF GHI 123 ひらがな 漢字 カタカナ' "${variable}" + + variable='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' + func::strtoupper variable + EXPECT_EQ 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' \ + "${variable}" + + variable=$' !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' + func::strtoupper variable + EXPECT_EQ $' !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' "${variable}" + + variable=$'\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0e\x0f\x10' + func::strtoupper variable + EXPECT_EQ $'\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0e\x0f\x10' \ + "${variable}" + + variable=$'\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1e\x1f\x7f' + func::strtoupper variable + EXPECT_EQ $'\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1e\x1f\x7f' \ + "${variable}" +} diff --git a/test/php_strtolower_test.sh b/test/php_strtolower_test.sh deleted file mode 100644 index e247728..0000000 --- a/test/php_strtolower_test.sh +++ /dev/null @@ -1,4 +0,0 @@ -test::php::strtoupper() { - EXPECT_EQ 'abc def ghi 123 ひらがな 漢字 カタカナ' \ - "$(php::strtolower 'ABC def Ghi 123 ひらがな 漢字 カタカナ')" -} diff --git a/test/php_strtoupper_test.sh b/test/php_strtoupper_test.sh deleted file mode 100644 index 21e899e..0000000 --- a/test/php_strtoupper_test.sh +++ /dev/null @@ -1,4 +0,0 @@ -test::php::strtoupper() { - EXPECT_EQ 'ABC DEF GHI 123 ひらがな 漢字 カタカナ' \ - "$(php::strtoupper 'ABC def Ghi 123 ひらがな 漢字 カタカナ')" -} From f754fa73b7754ad193c746297e7ad360bb21afde Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 18:11:25 +0900 Subject: [PATCH 36/58] Update imosh. --- imosh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imosh b/imosh index 0b8a79e..88e7442 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-23 17:37:42 +0900 (0c3fd4d)' +IMOSH_VERSION='2014-09-23 18:11:11 +0900 (6afdbf6)' if ! shopt login_shell >/dev/null; then set -e -u From 3363bb63cdd6f842c9afa8853c672001246e7436 Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 18:13:30 +0900 Subject: [PATCH 37/58] Remove php::str_replace. --- imosh | 10 ---------- library/20-php-str_replace.sh | 9 --------- test/php_str_replace_test.sh | 10 ---------- 3 files changed, 29 deletions(-) delete mode 100644 library/20-php-str_replace.sh delete mode 100644 test/php_str_replace_test.sh diff --git a/imosh b/imosh index 88e7442..b2530e0 100755 --- a/imosh +++ b/imosh @@ -476,16 +476,6 @@ php::sort() { eval "${__sort_name}=(\"\${__sort_values[@]}\")" } -# Usage: -# php::str_replace -php::str_replace() { - local search="${1}" - local replace="${2}" - local subject="${3}" - - print "${subject//${search}/${replace}}" -} - imosh::set_pid() { if func::isset BASHPID; then IMOSH_PID="${BASHPID}" diff --git a/library/20-php-str_replace.sh b/library/20-php-str_replace.sh deleted file mode 100644 index d28d771..0000000 --- a/library/20-php-str_replace.sh +++ /dev/null @@ -1,9 +0,0 @@ -# Usage: -# php::str_replace -php::str_replace() { - local search="${1}" - local replace="${2}" - local subject="${3}" - - print "${subject//${search}/${replace}}" -} diff --git a/test/php_str_replace_test.sh b/test/php_str_replace_test.sh deleted file mode 100644 index 08aeb46..0000000 --- a/test/php_str_replace_test.sh +++ /dev/null @@ -1,10 +0,0 @@ -test::php::str_replace() { - EXPECT_EQ 'abcxdefxghi' "$(php::str_replace ' ' 'x' 'abc def ghi')" - EXPECT_EQ 'abcxyzdefxyzghi' "$(php::str_replace ' ' 'xyz' 'abc def ghi')" - EXPECT_EQ 'abcxghi' "$(php::str_replace 'def' 'x' 'abcdefghi')" - EXPECT_EQ 'abcxyzghi' "$(php::str_replace 'def' 'xyz' 'abcdefghi')" - EXPECT_EQ 'bbbbbbaa' "$(php::str_replace 'aaa' 'bbb' 'aaaaaaaa')" - EXPECT_EQ 'abcdefghi' "$(php::str_replace 'x' 'y' 'abcdefghi')" - EXPECT_EQ 'abc def' "$(php::str_replace $'\n' ' ' $'abc\ndef')" - EXPECT_EQ 'abc//def//ghi' "$(php::str_replace '/' '//' 'abc/def/ghi')" -} From 996309ece772ae60a61b817ac8e15f2e0262b6ae Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 18:46:33 +0900 Subject: [PATCH 38/58] Replace php::ord with func::ord. --- imosh | 17 ++++++++++++----- library/20-func/ord.sh | 10 ++++++++++ library/20-php-ord.sh | 3 --- test/func/ord_test.sh | 16 ++++++++++++++++ test/php_ord_test.sh | 5 ----- 5 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 library/20-func/ord.sh delete mode 100644 library/20-php-ord.sh create mode 100644 test/func/ord_test.sh delete mode 100644 test/php_ord_test.sh diff --git a/imosh b/imosh index b2530e0..e4b3ade 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-23 18:11:11 +0900 (6afdbf6)' +IMOSH_VERSION='2014-09-23 18:13:30 +0900 (3363bb6)' if ! shopt login_shell >/dev/null; then set -e -u @@ -384,10 +384,6 @@ php::md5() { fi } -php::ord() { - printf '%d' \'"${1}" -} - php::rand() { if [ "$#" -eq 0 ]; then php::rand 0 2147483647 @@ -1073,6 +1069,17 @@ func::ltrim() { eval "${__ltrim_variable}=\"\${${__ltrim_variable}#\"\${${__ltrim_variable}%%[![:space:]]*}\"}\"" } +# Usage: +# func::ord(string* variable, string character) +# +# Sets ASCII value of character to variable. +func::ord() { + local __ord_variable="$1" + local __ord_character="$2" + local __ord_result="$(printf '%d' \'"${__ord_character}")" + eval "${__ord_variable}=\"\${__ord_result}\"" +} + # Usage: # void func::print(string message...) > output # diff --git a/library/20-func/ord.sh b/library/20-func/ord.sh new file mode 100644 index 0000000..002e363 --- /dev/null +++ b/library/20-func/ord.sh @@ -0,0 +1,10 @@ +# Usage: +# func::ord(string* variable, string character) +# +# Sets ASCII value of character to variable. +func::ord() { + local __ord_variable="$1" + local __ord_character="$2" + local __ord_result="$(printf '%d' \'"${__ord_character}")" + eval "${__ord_variable}=\"\${__ord_result}\"" +} diff --git a/library/20-php-ord.sh b/library/20-php-ord.sh deleted file mode 100644 index 50d9a53..0000000 --- a/library/20-php-ord.sh +++ /dev/null @@ -1,3 +0,0 @@ -php::ord() { - printf '%d' \'"${1}" -} diff --git a/test/func/ord_test.sh b/test/func/ord_test.sh new file mode 100644 index 0000000..ce06429 --- /dev/null +++ b/test/func/ord_test.sh @@ -0,0 +1,16 @@ +test::func_ord() { + local variable='A' + local result='' + + variable='A' + func::ord result "${variable}" + EXPECT_EQ 65 "${result}" + + variable='ABC' + func::ord result "${variable}" + EXPECT_EQ 65 "${result}" + + variable=$'\n' + func::ord result "${variable}" + EXPECT_EQ 10 "${result}" +} diff --git a/test/php_ord_test.sh b/test/php_ord_test.sh deleted file mode 100644 index e71e945..0000000 --- a/test/php_ord_test.sh +++ /dev/null @@ -1,5 +0,0 @@ -test::php::ord() { - EXPECT_EQ 65 "$(php::ord A)" - EXPECT_EQ 65 "$(php::ord ABC)" - EXPECT_EQ 10 "$(php::ord $'\n')" -} From 827377bce5ec7ed6c07c86dffa742a68b94e9abc Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 19:19:26 +0900 Subject: [PATCH 39/58] Replace php::rand with func::rand. --- imosh | 62 +++++++++++--------- library/20-func/rand.sh | 32 ++++++++++ library/20-php-rand.sh | 26 -------- test/{php_rand_test.sh => func/rand_test.sh} | 14 ++--- 4 files changed, 73 insertions(+), 61 deletions(-) create mode 100644 library/20-func/rand.sh delete mode 100644 library/20-php-rand.sh rename test/{php_rand_test.sh => func/rand_test.sh} (58%) diff --git a/imosh b/imosh index e4b3ade..4e25689 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-23 18:13:30 +0900 (3363bb6)' +IMOSH_VERSION='2014-09-23 18:46:33 +0900 (996309e)' if ! shopt login_shell >/dev/null; then set -e -u @@ -384,33 +384,6 @@ php::md5() { fi } -php::rand() { - if [ "$#" -eq 0 ]; then - php::rand 0 2147483647 - return - fi - if [ "$#" -ne 2 ]; then - LOG FATAL 'php::rand requires zero or two arguments.' - fi - - local min="${1}" max="${2}" range=0 - (( range = max - min + 1 )) || true - if [ "${range}" -lt 1 ]; then - LOG FATAL "min must be larger than max: min=${min}, max=${max}" - fi - if [ "${range}" -eq 1 ]; then - print "${min}" - return - fi - local rand=0 - (( rand = RANDOM ^ (RANDOM << 8) ^ - (RANDOM << 16) ^ (RANDOM << 24) ^ - (RANDOM << 32) ^ (RANDOM << 40) ^ - (RANDOM << 48) ^ (RANDOM << 56) )) || true - (( rand = min + ( rand % range + range ) % range )) || true - print "${rand}" -} - php::internal::set_pivot() { local pivot_index=0 (( pivot_index = left + (right - left) / 2 )) || true @@ -1099,6 +1072,39 @@ func::println() { printf "%s\n" "$*" } +# Usage: +# void func::rand(int* variable) +# void func::rand(int* variable, int minimum, int maximum) +# +# Generates a random integer. +func::rand() { + if [ "$#" -eq 1 ]; then + func::rand "$1" 0 2147483647 + return + fi + if [ "$#" -ne 3 ]; then + LOG FATAL 'func::rand requires one or three arguments.' + fi + + local __rand_variable="$1" + local __rand_minimum="$2" + local __rand_maximum="$3" + local __rand_range=0 __rand_value=0 + if (( __rand_minimum > __rand_maximum )); then + LOG FATAL "minimum must be larger than maximum:" \ + "minimum=${__rand_minimum}, maximum=${__rand_maximum}" + fi + (( __rand_value = RANDOM ^ (RANDOM << 8) ^ + (RANDOM << 16) ^ (RANDOM << 24) ^ + (RANDOM << 32) ^ (RANDOM << 40) ^ + (RANDOM << 48) ^ (RANDOM << 56), + __rand_range = __rand_maximum - __rand_minimum + 1, + __rand_value = __rand_minimum + + ( __rand_value % __rand_range + __rand_range ) % __rand_range, + 1 )) + func::let "${__rand_variable}" "${__rand_value}" +} + # Usage: # void func::rtrim(string* variable) # diff --git a/library/20-func/rand.sh b/library/20-func/rand.sh new file mode 100644 index 0000000..b5da288 --- /dev/null +++ b/library/20-func/rand.sh @@ -0,0 +1,32 @@ +# Usage: +# void func::rand(int* variable) +# void func::rand(int* variable, int minimum, int maximum) +# +# Generates a random integer. +func::rand() { + if [ "$#" -eq 1 ]; then + func::rand "$1" 0 2147483647 + return + fi + if [ "$#" -ne 3 ]; then + LOG FATAL 'func::rand requires one or three arguments.' + fi + + local __rand_variable="$1" + local __rand_minimum="$2" + local __rand_maximum="$3" + local __rand_range=0 __rand_value=0 + if (( __rand_minimum > __rand_maximum )); then + LOG FATAL "minimum must be larger than maximum:" \ + "minimum=${__rand_minimum}, maximum=${__rand_maximum}" + fi + (( __rand_value = RANDOM ^ (RANDOM << 8) ^ + (RANDOM << 16) ^ (RANDOM << 24) ^ + (RANDOM << 32) ^ (RANDOM << 40) ^ + (RANDOM << 48) ^ (RANDOM << 56), + __rand_range = __rand_maximum - __rand_minimum + 1, + __rand_value = __rand_minimum + + ( __rand_value % __rand_range + __rand_range ) % __rand_range, + 1 )) + func::let "${__rand_variable}" "${__rand_value}" +} diff --git a/library/20-php-rand.sh b/library/20-php-rand.sh deleted file mode 100644 index 8b9ca88..0000000 --- a/library/20-php-rand.sh +++ /dev/null @@ -1,26 +0,0 @@ -php::rand() { - if [ "$#" -eq 0 ]; then - php::rand 0 2147483647 - return - fi - if [ "$#" -ne 2 ]; then - LOG FATAL 'php::rand requires zero or two arguments.' - fi - - local min="${1}" max="${2}" range=0 - (( range = max - min + 1 )) || true - if [ "${range}" -lt 1 ]; then - LOG FATAL "min must be larger than max: min=${min}, max=${max}" - fi - if [ "${range}" -eq 1 ]; then - print "${min}" - return - fi - local rand=0 - (( rand = RANDOM ^ (RANDOM << 8) ^ - (RANDOM << 16) ^ (RANDOM << 24) ^ - (RANDOM << 32) ^ (RANDOM << 40) ^ - (RANDOM << 48) ^ (RANDOM << 56) )) || true - (( rand = min + ( rand % range + range ) % range )) || true - print "${rand}" -} diff --git a/test/php_rand_test.sh b/test/func/rand_test.sh similarity index 58% rename from test/php_rand_test.sh rename to test/func/rand_test.sh index d8fe038..28c9f45 100644 --- a/test/php_rand_test.sh +++ b/test/func/rand_test.sh @@ -1,30 +1,30 @@ -test::php::rand() { +test::func_rand() { local values=() value=0 for i in {1..100}; do - value="$(php::rand)" + func::rand value if [ 0 -le "${value}" -a "${value}" -le 2147483647 ]; then values+=("${value}") else - LOG FATAL 'php::rand should be between 0 and 2147483647 inclusive:' \ + LOG FATAL 'func::rand should be between 0 and 2147483647 inclusive:' \ "${value}" fi done php::array_unique values if [ "${#values[@]}" -lt 98 ]; then - LOG FATAL "php::rand's performance may be bad: ${#values[@]}" + LOG FATAL "func::rand's distribution may be bad: ${#values[@]}" fi values=() for i in {1..100}; do - value="$(php::rand 0 4)" + func::rand value 0 4 if [ 0 -le "${value}" -a "${value}" -le 4 ]; then values+=("${value}") else - LOG FATAL "php::rand(0, 4) should be between 0 and 4 inclusive: ${value}" + LOG FATAL "func::rand(0, 4) should be between 0 and 4 inclusive: ${value}" fi done php::array_unique values # This should pass in 99.999999898148%. if [ "${#values[@]}" -ne 5 ]; then - LOG FATAL "php::rand's performance may be bad: ${#values[@]}" + LOG FATAL "func::rand's distribution may be bad: ${#values[@]}" fi } From ecf9064600f1b99079168b9500c450446511c1e3 Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 20:26:57 +0900 Subject: [PATCH 40/58] Add func::hex2bin. --- imosh | 40 +++++++++++++++++++++++++++++++++++++- library/20-func/hex2bin.sh | 37 +++++++++++++++++++++++++++++++++++ test/func/hex2bin_test.sh | 32 ++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 library/20-func/hex2bin.sh create mode 100644 test/func/hex2bin_test.sh diff --git a/imosh b/imosh index 4e25689..1d6ef14 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-23 18:46:33 +0900 (996309e)' +IMOSH_VERSION='2014-09-23 19:19:26 +0900 (827377b)' if ! shopt login_shell >/dev/null; then set -e -u @@ -957,6 +957,44 @@ func::greg_replace() { eval "${__greg_replace_subject_variable}=\"\${${__greg_replace_subject_variable}//\${__greg_replace_search}/\${__greg_replace_replace}}\"" } +# Usage: +# void func::hex2bin(string* output, string input) +# void func::hex2bin(string* variable) +# void func::hex2bin() < input > output +# +# Decodes a hexadecimally encoded binary string. +func::hex2bin() { + if [ "$#" -eq 0 ]; then + local __hex2bin_variable='' + __func::hex2bin + elif [ "$#" -eq 2 ]; then + local __hex2bin_variable="$1" __hex2bin_data="$2" __hex2bin_result='' + __func::hex2bin <<<"${__hex2bin_data}" + func::let "${__hex2bin_variable}" "${__hex2bin_result}" + elif [ "$#" -eq 1 ]; then + local __hex2bin_variable="$1" __hex2bin_result='' + eval "func::hex2bin \"\${__hex2bin_variable}\" \"\${${__hex2bin_variable}}\"" + fi +} + +__func::hex2bin() { + local __hex2bin_char='' __hex2bin_buffer='' + while read -n 1 __hex2bin_char; do + case "${__hex2bin_char}" in + [0-9a-fA-F]) __hex2bin_buffer+="${__hex2bin_char}";; + *) continue;; + esac + if [ "${#__hex2bin_buffer}" -eq 2 ]; then + if [ "${__hex2bin_variable}" = '' ]; then + printf "\\x${__hex2bin_buffer}" + else + eval "__hex2bin_result+=\$'\\x${__hex2bin_buffer}'" + fi + __hex2bin_buffer='' + fi + done +} + # Usage: # func::implode(string* variable, string glue, array* pieces) # func::implode(string glue, array* pieces) > result diff --git a/library/20-func/hex2bin.sh b/library/20-func/hex2bin.sh new file mode 100644 index 0000000..8844163 --- /dev/null +++ b/library/20-func/hex2bin.sh @@ -0,0 +1,37 @@ +# Usage: +# void func::hex2bin(string* output, string input) +# void func::hex2bin(string* variable) +# void func::hex2bin() < input > output +# +# Decodes a hexadecimally encoded binary string. +func::hex2bin() { + if [ "$#" -eq 0 ]; then + local __hex2bin_variable='' + __func::hex2bin + elif [ "$#" -eq 2 ]; then + local __hex2bin_variable="$1" __hex2bin_data="$2" __hex2bin_result='' + __func::hex2bin <<<"${__hex2bin_data}" + func::let "${__hex2bin_variable}" "${__hex2bin_result}" + elif [ "$#" -eq 1 ]; then + local __hex2bin_variable="$1" __hex2bin_result='' + eval "func::hex2bin \"\${__hex2bin_variable}\" \"\${${__hex2bin_variable}}\"" + fi +} + +__func::hex2bin() { + local __hex2bin_char='' __hex2bin_buffer='' + while read -n 1 __hex2bin_char; do + case "${__hex2bin_char}" in + [0-9a-fA-F]) __hex2bin_buffer+="${__hex2bin_char}";; + *) continue;; + esac + if [ "${#__hex2bin_buffer}" -eq 2 ]; then + if [ "${__hex2bin_variable}" = '' ]; then + printf "\\x${__hex2bin_buffer}" + else + eval "__hex2bin_result+=\$'\\x${__hex2bin_buffer}'" + fi + __hex2bin_buffer='' + fi + done +} diff --git a/test/func/hex2bin_test.sh b/test/func/hex2bin_test.sh new file mode 100644 index 0000000..94556a6 --- /dev/null +++ b/test/func/hex2bin_test.sh @@ -0,0 +1,32 @@ +test::func_hex2bin() { + local variable='' + + # void func::hex2bin(string* output, string input) + func::hex2bin variable '686f6765' + EXPECT_EQ 'hoge' "${variable}" + + # void func::hex2bin(string* variable) + variable='686f6765' + func::hex2bin variable + EXPECT_EQ 'hoge' "${variable}" + + # void func::hex2bin() < input > output + EXPECT_EQ 'hoge' "$(echo '686f6765' | func::hex2bin)" + + # Japanese characters. + variable='e697a5e69cace8aa9e' + func::hex2bin variable + EXPECT_EQ '日本語' "${variable}" + + # Spaces are ignored. + variable='e6 97 a5 e6 9c ac e8 aa 9e' + func::hex2bin variable + EXPECT_EQ '日本語' "${variable}" + + # Spaces including new lines are also ignored. + variable='e6 97 a5 + e6 9c ac + e8 aa 9e' + func::hex2bin variable + EXPECT_EQ '日本語' "${variable}" +} From eac3f8fe949b24bc89a9629e6af42deaca399029 Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 20:27:32 +0900 Subject: [PATCH 41/58] Remove php::hex2bin. --- imosh | 9 +-------- library/20-php-hex2bin.sh | 6 ------ test/php_hex2bin_test.sh | 8 -------- 3 files changed, 1 insertion(+), 22 deletions(-) delete mode 100644 library/20-php-hex2bin.sh delete mode 100644 test/php_hex2bin_test.sh diff --git a/imosh b/imosh index 1d6ef14..f58f704 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-23 19:19:26 +0900 (827377b)' +IMOSH_VERSION='2014-09-23 20:26:57 +0900 (ecf9064)' if ! shopt login_shell >/dev/null; then set -e -u @@ -367,13 +367,6 @@ php::array_unique() { eval "${__array_unique_name}=(\"\${__array_unique_values[@]}\")" } -php::hex2bin() { - local message="$( - print "$*" | tr -c -d '[0-9a-fA-F]' | fold -w 2 \ - | sed -e 's/^/\\x/' | tr -d '[:space:]')" - printf "${message}" -} - php::md5() { if which openssl >/dev/null 2>/dev/null; then print "${1}" | openssl md5 -binary | func::bin2hex diff --git a/library/20-php-hex2bin.sh b/library/20-php-hex2bin.sh deleted file mode 100644 index feb2339..0000000 --- a/library/20-php-hex2bin.sh +++ /dev/null @@ -1,6 +0,0 @@ -php::hex2bin() { - local message="$( - print "$*" | tr -c -d '[0-9a-fA-F]' | fold -w 2 \ - | sed -e 's/^/\\x/' | tr -d '[:space:]')" - printf "${message}" -} diff --git a/test/php_hex2bin_test.sh b/test/php_hex2bin_test.sh deleted file mode 100644 index 438238b..0000000 --- a/test/php_hex2bin_test.sh +++ /dev/null @@ -1,8 +0,0 @@ -test::php::hex2bin() { - EXPECT_EQ 'hoge' "$(php::hex2bin '686f6765')" - EXPECT_EQ '日本語' "$(php::hex2bin 'e697a5e69cace8aa9e')" - EXPECT_EQ '日本語' "$(php::hex2bin 'e6 97 a5 e6 9c ac e8 aa 9e')" - EXPECT_EQ '日本語' "$(php::hex2bin 'e6 97 a5 - e6 9c ac - e8 aa 9e')" -} From f5d37ab22f9c33dc86470844338534161872a410 Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 20:46:57 +0900 Subject: [PATCH 42/58] Replace php::array_unique with func::array_unique. --- imosh | 42 +++++++++---------- library/20-func/array_unique.sh | 18 ++++++++ library/20-php-array_unique.sh | 20 --------- .../array_unique_test.sh} | 22 ++++++---- test/func/rand_test.sh | 4 +- 5 files changed, 55 insertions(+), 51 deletions(-) create mode 100644 library/20-func/array_unique.sh delete mode 100644 library/20-php-array_unique.sh rename test/{php_array_unique_test.sh => func/array_unique_test.sh} (88%) diff --git a/imosh b/imosh index f58f704..a84b5f9 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-23 20:26:57 +0900 (ecf9064)' +IMOSH_VERSION='2014-09-23 20:27:32 +0900 (eac3f8f)' if ! shopt login_shell >/dev/null; then set -e -u @@ -346,27 +346,6 @@ readonly IMOSH_PARSE_ARGUMENTS=' set -- "${IMOSH_ARGV[@]}" fi' -php::array_unique() { - if [ "$#" -ne 1 ]; then - LOG FATAL 'php::array_unique requires one argument.' - fi - - local __array_unique_name="${1}" - eval "local __array_unique_values=(\"\${${__array_unique_name}[@]}\")" - php::sort __array_unique_values - local __array_unique_i=1 __array_unique_size="${#__array_unique_values[@]}" - while (( __array_unique_i < __array_unique_size )); do - local __array_unique_last_i=0 - (( __array_unique_last_i = __array_unique_i - 1 )) || true - if [ "${__array_unique_values[${__array_unique_i}]}" == \ - "${__array_unique_values[${__array_unique_last_i}]}" ]; then - unset __array_unique_values["${__array_unique_last_i}"] - fi - (( __array_unique_i += 1 )) || true - done - eval "${__array_unique_name}=(\"\${__array_unique_values[@]}\")" -} - php::md5() { if which openssl >/dev/null 2>/dev/null; then print "${1}" | openssl md5 -binary | func::bin2hex @@ -834,6 +813,25 @@ func::addslashes() { func::str_replace "${1}" '"' '\"' } +func::array_unique() { + local __array_unique_variable="${1}" + if eval "[ \"\${#${__array_unique_variable}[*]}\" -eq 0 ]"; then + return + fi + eval "local __array_unique_values=(\"\${${__array_unique_variable}[@]}\")" + func::sort __array_unique_values + local __array_unique_i=0 + local __array_unique_size="${#__array_unique_values[*]}" + local __array_unique_result=("${__array_unique_values[0]}") + while (( __array_unique_i += 1, __array_unique_i < __array_unique_size )); do + if [ "${__array_unique_values[$(( __array_unique_i - 1 ))]}" != \ + "${__array_unique_values[${__array_unique_i}]}" ]; then + __array_unique_result+=("${__array_unique_values[${__array_unique_i}]}") + fi + done + eval "${__array_unique_variable}=(\"\${__array_unique_result[@]}\")" +} + # Usage: # void func::bin2hex(string* hexadecimal_output, string binary_input) # void func::bin2hex(string binary_input) > hexadecimal_output diff --git a/library/20-func/array_unique.sh b/library/20-func/array_unique.sh new file mode 100644 index 0000000..1d7e0eb --- /dev/null +++ b/library/20-func/array_unique.sh @@ -0,0 +1,18 @@ +func::array_unique() { + local __array_unique_variable="${1}" + if eval "[ \"\${#${__array_unique_variable}[*]}\" -eq 0 ]"; then + return + fi + eval "local __array_unique_values=(\"\${${__array_unique_variable}[@]}\")" + func::sort __array_unique_values + local __array_unique_i=0 + local __array_unique_size="${#__array_unique_values[*]}" + local __array_unique_result=("${__array_unique_values[0]}") + while (( __array_unique_i += 1, __array_unique_i < __array_unique_size )); do + if [ "${__array_unique_values[$(( __array_unique_i - 1 ))]}" != \ + "${__array_unique_values[${__array_unique_i}]}" ]; then + __array_unique_result+=("${__array_unique_values[${__array_unique_i}]}") + fi + done + eval "${__array_unique_variable}=(\"\${__array_unique_result[@]}\")" +} diff --git a/library/20-php-array_unique.sh b/library/20-php-array_unique.sh deleted file mode 100644 index c76f913..0000000 --- a/library/20-php-array_unique.sh +++ /dev/null @@ -1,20 +0,0 @@ -php::array_unique() { - if [ "$#" -ne 1 ]; then - LOG FATAL 'php::array_unique requires one argument.' - fi - - local __array_unique_name="${1}" - eval "local __array_unique_values=(\"\${${__array_unique_name}[@]}\")" - php::sort __array_unique_values - local __array_unique_i=1 __array_unique_size="${#__array_unique_values[@]}" - while (( __array_unique_i < __array_unique_size )); do - local __array_unique_last_i=0 - (( __array_unique_last_i = __array_unique_i - 1 )) || true - if [ "${__array_unique_values[${__array_unique_i}]}" == \ - "${__array_unique_values[${__array_unique_last_i}]}" ]; then - unset __array_unique_values["${__array_unique_last_i}"] - fi - (( __array_unique_i += 1 )) || true - done - eval "${__array_unique_name}=(\"\${__array_unique_values[@]}\")" -} diff --git a/test/php_array_unique_test.sh b/test/func/array_unique_test.sh similarity index 88% rename from test/php_array_unique_test.sh rename to test/func/array_unique_test.sh index 9b62337..f64e2a0 100644 --- a/test/php_array_unique_test.sh +++ b/test/func/array_unique_test.sh @@ -1,24 +1,30 @@ -test::php::array_unique() { +test::func_array_unique() { + local values=() + EXPECT_TRUE func::array_unique values + local values=(w a c m d i n v y u q j g r x t z k h s e l o f b p) - php::array_unique values + func::array_unique values EXPECT_EQ "a b c d e f g h i j k l m n o p q r s t u v w x y z" \ "$(echo "${values[@]}")" + local values=(w a c m d i n v y u q j g r x t z k h s e l o f b p a b c d e e e e e e e e e e e e e e e e e e e e e e) - php::array_unique values + func::array_unique values EXPECT_EQ "a b c d e f g h i j k l m n o p q r s t u v w x y z" \ "$(echo "${values[@]}")" + local values=(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20) - php::array_unique values + func::array_unique values EXPECT_EQ "1 10 11 12 13 14 15 16 17 18 19 2 20 3 4 5 6 7 8 9" \ "$(echo "${values[@]}")" + local i=1 local c1=$'\x01' local values=($'\x1a' $'\x11' "${c1}" $'\x16' $'\x09' $'\x03' $'\x1c' $'\x05' $'\x1d' $'\x1b' $'\x0a' $'\x19' $'\x1e' $'\x0e' $'\x15' $'\x0f' $'\x0d' $'\x08' $'\x04' $'\x13' $'\x02' $'\x07' $'\x1f' $'\x0c' $'\x17' $'\x18' $'\x20' $'\x10' $'\x06' $'\x0b' $'\x12' $'\x14') - php::array_unique values + func::array_unique values local expected='' expected+=$'\x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 ' expected+=$'\x09 \x0a \x0b \x0c \x0d \x0e \x0f \x10 ' @@ -26,9 +32,11 @@ test::php::array_unique() { expected+=$'\x19 \x1a \x1b \x1c \x1d \x1e \x1f \x20' EXPECT_EQ "$(func::bin2hex "${expected}")" \ "$(func::bin2hex "$(func::implode ' ' values)")" - php::array_unique values + + func::array_unique values EXPECT_EQ "$(func::bin2hex "${expected}")" \ "$(func::bin2hex "$(func::implode ' ' values)")" + local values=($'\x1a' $'\x11' "${c1}" $'\x16' $'\x09' $'\x03' $'\x1c' $'\x05' $'\x1d' $'\x1b' $'\x0a' $'\x19' $'\x1e' $'\x0e' $'\x15' $'\x0f' $'\x0d' $'\x08' $'\x04' $'\x13' $'\x02' $'\x07' $'\x1f' $'\x0c' @@ -37,5 +45,5 @@ test::php::array_unique() { $'\x1d' $'\x1b' $'\x0a' $'\x19' $'\x1e' $'\x0e' $'\x15' $'\x0f' $'\x0d' $'\x08' $'\x04' $'\x13' $'\x02' $'\x07' $'\x1f' $'\x0c' $'\x17' $'\x18' $'\x20' $'\x10' $'\x06' $'\x0b' $'\x12' $'\x14') - php::array_unique values + func::array_unique values } diff --git a/test/func/rand_test.sh b/test/func/rand_test.sh index 28c9f45..e2c3274 100644 --- a/test/func/rand_test.sh +++ b/test/func/rand_test.sh @@ -9,7 +9,7 @@ test::func_rand() { "${value}" fi done - php::array_unique values + func::array_unique values if [ "${#values[@]}" -lt 98 ]; then LOG FATAL "func::rand's distribution may be bad: ${#values[@]}" fi @@ -22,7 +22,7 @@ test::func_rand() { LOG FATAL "func::rand(0, 4) should be between 0 and 4 inclusive: ${value}" fi done - php::array_unique values + func::array_unique values # This should pass in 99.999999898148%. if [ "${#values[@]}" -ne 5 ]; then LOG FATAL "func::rand's distribution may be bad: ${#values[@]}" From 22e9fdb39ff6f750979ee422830c55e6dbc0db13 Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 20:48:18 +0900 Subject: [PATCH 43/58] Remove php::sort. --- imosh | 65 ++---------------------------------------- library/20-php-sort.sh | 60 -------------------------------------- library/30-flags.sh | 2 +- test/php_sort_test.sh | 27 ------------------ 4 files changed, 3 insertions(+), 151 deletions(-) delete mode 100644 library/20-php-sort.sh delete mode 100644 test/php_sort_test.sh diff --git a/imosh b/imosh index a84b5f9..1818802 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-23 20:27:32 +0900 (eac3f8f)' +IMOSH_VERSION='2014-09-23 20:46:57 +0900 (f5d37ab)' if ! shopt login_shell >/dev/null; then set -e -u @@ -356,67 +356,6 @@ php::md5() { fi } -php::internal::set_pivot() { - local pivot_index=0 - (( pivot_index = left + (right - left) / 2 )) || true - local x="${__sort_values[${left}]}" - local y="${__sort_values[${pivot_index}]}" - local z="${__sort_values[${right}]}" - - if [ "${x}" \< "${y}" ]; then - if [ "${y}" \< "${z}" ]; then - pivot="${y}" - elif [ "${z}" \< "${x}" ]; then - pivot="${x}" - else - pivot="${z}" - fi - else - if [ "${z}" \< "${y}" ]; then - pivot="${y}" - elif [ "${x}" \< "${z}" ]; then - pivot="${x}" - else - pivot="${z}" - fi - fi -} - -php::internal::quick_sort() { - local left="${1}" right="${2}" - local i="${left}" j="${right}" - if [ "${left}" -ge "${right}" ]; then return; fi - local pivot='' - php::internal::set_pivot - while :; do - while [ "${__sort_values[${i}]}" \< "${pivot}" ]; do - (( i += 1 )) || true - done - while [ "${pivot}" \< "${__sort_values[${j}]}" ]; do - (( j -= 1 )) || true - done - if [ "${i}" -ge "${j}" ]; then break; fi - local value="${__sort_values[${i}]}" - __sort_values["${i}"]="${__sort_values[${j}]}" - __sort_values["${j}"]="${value}" - (( i += 1 )) || true - (( j -= 1 )) || true - done - (( i -= 1 )) || true - (( j += 1 )) || true - php::internal::quick_sort "${left}" "${i}" - php::internal::quick_sort "${j}" "${right}" -} - -php::sort() { - local __sort_name="${1}" - eval "local __sort_values=(\"\${${__sort_name}[@]}\")" - local __sort_size="${#__sort_values[@]}" - (( __sort_size -= 1 )) || true - php::internal::quick_sort 0 "${__sort_size}" - eval "${__sort_name}=(\"\${__sort_values[@]}\")" -} - imosh::set_pid() { if func::isset BASHPID; then IMOSH_PID="${BASHPID}" @@ -576,7 +515,7 @@ imosh::internal::group_flags() { fi flags+=("${parts[1]}") done - php::sort flags + func::sort flags for flag in "${flags[@]}"; do echo "${flag}" done diff --git a/library/20-php-sort.sh b/library/20-php-sort.sh deleted file mode 100644 index 7392e72..0000000 --- a/library/20-php-sort.sh +++ /dev/null @@ -1,60 +0,0 @@ -php::internal::set_pivot() { - local pivot_index=0 - (( pivot_index = left + (right - left) / 2 )) || true - local x="${__sort_values[${left}]}" - local y="${__sort_values[${pivot_index}]}" - local z="${__sort_values[${right}]}" - - if [ "${x}" \< "${y}" ]; then - if [ "${y}" \< "${z}" ]; then - pivot="${y}" - elif [ "${z}" \< "${x}" ]; then - pivot="${x}" - else - pivot="${z}" - fi - else - if [ "${z}" \< "${y}" ]; then - pivot="${y}" - elif [ "${x}" \< "${z}" ]; then - pivot="${x}" - else - pivot="${z}" - fi - fi -} - -php::internal::quick_sort() { - local left="${1}" right="${2}" - local i="${left}" j="${right}" - if [ "${left}" -ge "${right}" ]; then return; fi - local pivot='' - php::internal::set_pivot - while :; do - while [ "${__sort_values[${i}]}" \< "${pivot}" ]; do - (( i += 1 )) || true - done - while [ "${pivot}" \< "${__sort_values[${j}]}" ]; do - (( j -= 1 )) || true - done - if [ "${i}" -ge "${j}" ]; then break; fi - local value="${__sort_values[${i}]}" - __sort_values["${i}"]="${__sort_values[${j}]}" - __sort_values["${j}"]="${value}" - (( i += 1 )) || true - (( j -= 1 )) || true - done - (( i -= 1 )) || true - (( j += 1 )) || true - php::internal::quick_sort "${left}" "${i}" - php::internal::quick_sort "${j}" "${right}" -} - -php::sort() { - local __sort_name="${1}" - eval "local __sort_values=(\"\${${__sort_name}[@]}\")" - local __sort_size="${#__sort_values[@]}" - (( __sort_size -= 1 )) || true - php::internal::quick_sort 0 "${__sort_size}" - eval "${__sort_name}=(\"\${__sort_values[@]}\")" -} diff --git a/library/30-flags.sh b/library/30-flags.sh index 847dcb0..de8894e 100644 --- a/library/30-flags.sh +++ b/library/30-flags.sh @@ -147,7 +147,7 @@ imosh::internal::group_flags() { fi flags+=("${parts[1]}") done - php::sort flags + func::sort flags for flag in "${flags[@]}"; do echo "${flag}" done diff --git a/test/php_sort_test.sh b/test/php_sort_test.sh deleted file mode 100644 index a9059ad..0000000 --- a/test/php_sort_test.sh +++ /dev/null @@ -1,27 +0,0 @@ -test::php::sort() { - local values=(w a c m d i n v y u q j g r x t z k h s e l o f b p) - php::sort values - EXPECT_EQ "a b c d e f g h i j k l m n o p q r s t u v w x y z" \ - "$(echo "${values[@]}")" - local values=(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20) - php::sort values - EXPECT_EQ "1 10 11 12 13 14 15 16 17 18 19 2 20 3 4 5 6 7 8 9" \ - "$(echo "${values[@]}")" - local i=1 - local c1=$'\x01' - local values=($'\x1a' $'\x11' "${c1}" $'\x16' $'\x09' $'\x03' $'\x1c' $'\x05' - $'\x1d' $'\x1b' $'\x0a' $'\x19' $'\x1e' $'\x0e' $'\x15' $'\x0f' - $'\x0d' $'\x08' $'\x04' $'\x13' $'\x02' $'\x07' $'\x1f' $'\x0c' - $'\x17' $'\x18' $'\x20' $'\x10' $'\x06' $'\x0b' $'\x12' $'\x14') - IFS= php::sort values - local expected='' - expected+=$'\x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 ' - expected+=$'\x09 \x0a \x0b \x0c \x0d \x0e \x0f \x10 ' - expected+=$'\x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 ' - expected+=$'\x19 \x1a \x1b \x1c \x1d \x1e \x1f \x20' - EXPECT_EQ "$(func::bin2hex "${expected}")" \ - "$(func::bin2hex "$(func::implode ' ' values)")" - IFS= php::sort values - EXPECT_EQ "$(func::bin2hex "${expected}")" \ - "$(func::bin2hex "$(func::implode ' ' values)")" -} From 7376c5c4ff9726f09fe64a70097b9912563e1535 Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 20:48:27 +0900 Subject: [PATCH 44/58] Update imosh. --- imosh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imosh b/imosh index 1818802..b01a599 100755 --- a/imosh +++ b/imosh @@ -1,7 +1,7 @@ #!/bin/bash # imos is a utility library for BASH. -IMOSH_VERSION='2014-09-23 20:46:57 +0900 (f5d37ab)' +IMOSH_VERSION='2014-09-23 20:48:18 +0900 (22e9fdb)' if ! shopt login_shell >/dev/null; then set -e -u From ce9248d5350548bbf4b5537c9e74d6b94e15c95f Mon Sep 17 00:00:00 2001 From: imos Date: Tue, 23 Sep 2014 20:58:17 +0900 Subject: [PATCH 45/58] Replace php::md5 with func::md5. --- imosh | 22 ++++++++++++---------- library/20-func/md5.sh | 11 +++++++++++ library/20-php-md5.sh | 9 --------- test/func/md5_test.sh | 5 +++++ test/php_md5_test.sh | 5 ----- 5 files changed, 28 insertions(+), 24 deletions(-) create mode 100644 library/20-func/md5.sh delete mode 100644 library/20-php-md5.sh create mode 100644 test/func/md5_test.sh delete mode 100644 test/php_md5_test.sh diff --git a/imosh b/imosh index b01a599..6f08a12 100755 --- a/imosh +++ b/imosh @@ -346,16 +346,6 @@ readonly IMOSH_PARSE_ARGUMENTS=' set -- "${IMOSH_ARGV[@]}" fi' -php::md5() { - if which openssl >/dev/null 2>/dev/null; then - print "${1}" | openssl md5 -binary | func::bin2hex - elif which md5sum >/dev/null 2>/dev/null; then - print "${1}" | md5sum -b | func::bin2hex - else - LOG FATAL 'no command for md5 is found.' - fi -} - imosh::set_pid() { if func::isset BASHPID; then IMOSH_PID="${BASHPID}" @@ -1010,6 +1000,18 @@ func::ltrim() { eval "${__ltrim_variable}=\"\${${__ltrim_variable}#\"\${${__ltrim_variable}%%[![:space:]]*}\"}\"" } +func::md5() { + if [ "$#" -eq 0 ]; then + openssl md5 -binary | func::bin2hex + elif [ "$#" -eq 1 ]; then + func::print "${1}" | func::md5 + elif [ "$#" -eq 2 ]; then + local __md5_variable="$1" + local __md5_data="$2" + eval "${__md5_variable}=\"\$(func::md5 \"\${__md5_data}\")\"" + fi +} + # Usage: # func::ord(string* variable, string character) # diff --git a/library/20-func/md5.sh b/library/20-func/md5.sh new file mode 100644 index 0000000..acb55a7 --- /dev/null +++ b/library/20-func/md5.sh @@ -0,0 +1,11 @@ +func::md5() { + if [ "$#" -eq 0 ]; then + openssl md5 -binary | func::bin2hex + elif [ "$#" -eq 1 ]; then + func::print "${1}" | func::md5 + elif [ "$#" -eq 2 ]; then + local __md5_variable="$1" + local __md5_data="$2" + eval "${__md5_variable}=\"\$(func::md5 \"\${__md5_data}\")\"" + fi +} diff --git a/library/20-php-md5.sh b/library/20-php-md5.sh deleted file mode 100644 index a749391..0000000 --- a/library/20-php-md5.sh +++ /dev/null @@ -1,9 +0,0 @@ -php::md5() { - if which openssl >/dev/null 2>/dev/null; then - print "${1}" | openssl md5 -binary | func::bin2hex - elif which md5sum >/dev/null 2>/dev/null; then - print "${1}" | md5sum -b | func::bin2hex - else - LOG FATAL 'no command for md5 is found.' - fi -} diff --git a/test/func/md5_test.sh b/test/func/md5_test.sh new file mode 100644 index 0000000..a3ecd23 --- /dev/null +++ b/test/func/md5_test.sh @@ -0,0 +1,5 @@ +test::func_md5() { + EXPECT_EQ 'd41d8cd98f00b204e9800998ecf8427e' "$(func::md5 '')" + EXPECT_EQ 'acbd18db4cc2f85cedef654fccc4a4d8' "$(func::md5 'foo')" + EXPECT_EQ '68b329da9893e34099c7d8ad5cb9c940' "$(func::md5 $'\n')" +} diff --git a/test/php_md5_test.sh b/test/php_md5_test.sh deleted file mode 100644 index 0f51f93..0000000 --- a/test/php_md5_test.sh +++ /dev/null @@ -1,5 +0,0 @@ -test::php::md5() { - EXPECT_EQ 'd41d8cd98f00b204e9800998ecf8427e' "$(php::md5 '')" - EXPECT_EQ 'acbd18db4cc2f85cedef654fccc4a4d8' "$(php::md5 'foo')" - EXPECT_EQ '68b329da9893e34099c7d8ad5cb9c940' "$(php::md5 $'\n')" -} From 0e243ba53c104b27013449224d45126bf0ee58af Mon Sep 17 00:00:00 2001 From: imos Date: Wed, 24 Sep 2014 00:21:16 +0900 Subject: [PATCH 46/58] Add a marker to generate README.md automatically. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f9a0f71..5297e90 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ Path to Output imosh outputs log files to `${TMPDIR}/.....