From 5696bd8088b8e44a33237c94a0ce18ed0313693a Mon Sep 17 00:00:00 2001
From: Egor Tensin <Egor.Tensin@gmail.com>
Date: Mon, 7 Nov 2016 04:52:38 +0300
Subject: bugfix & code style

Add missing '--'s, make arrays and nounset play well, etc.
---
 %HOME%/.bash_utils/cxx.sh   | 106 ++++++++++++++++++++++++++++++++------------
 %HOME%/.bash_utils/distr.sh |  19 +++++---
 %HOME%/.bash_utils/file.sh  |   2 +-
 %HOME%/.bash_utils/git.sh   |  44 +++++++++---------
 %HOME%/.bash_utils/path.sh  |  32 ++++++-------
 %HOME%/.bash_utils/text.sh  |  61 +++++++++++--------------
 6 files changed, 156 insertions(+), 108 deletions(-)

(limited to '%HOME%/.bash_utils')

diff --git a/%HOME%/.bash_utils/cxx.sh b/%HOME%/.bash_utils/cxx.sh
index 5d1a438..4ff81f4 100644
--- a/%HOME%/.bash_utils/cxx.sh
+++ b/%HOME%/.bash_utils/cxx.sh
@@ -7,52 +7,76 @@
 
 runc_flags=('-Wall' '-Wextra')
 
+_runc_usage() (
+    set -o errexit -o nounset -o pipefail
+
+    local msg
+    for msg; do
+        echo "${FUNCNAME[1]}: $msg"
+    done
+
+    echo "usage: ${FUNCNAME[1]} [-h|--help] [-c|--comp-arg ARG]... C_PATH... [-- [PROG_ARG]...]"
+)
+
 runc() (
     set -o errexit -o nounset -o pipefail
 
     local -a c_flags=(${runc_flags[@]+"${runc_flags[@]}"})
-    local -a src_files
+    local -a src_files=()
     local -a prog_args
 
     while [ "$#" -gt 0 ]; do
-        case "$1" in
+        local key="$1"
+        shift
+
+        case "$key" in
+            -h|--help)
+                _runc_usage
+                return 0
+                ;;
+
             -c|--comp-arg)
-                if [ "$#" -le 1 ]; then
-                    echo "${FUNCNAME[0]}: missing argument for parameter: $1" >&2
+                if [ "$#" -eq 0 ]; then
+                    _runc_usage "missing argument for parameter: $key" >&2
                     return 1
                 fi
-                shift
                 c_flags+=("$1")
                 shift
                 ;;
 
-            -h|--help)
-                echo "usage: ${FUNCNAME[0]} [-h|--help] [-c|--comp-arg ARG]... C_PATH... [-- [PROG_ARG]...]"
-                return 0
-                ;;
-
             --)
-                shift
                 break
                 ;;
 
             *)
-                src_files+=("$( realpath "$1" )")
-                shift
+                src_files+=("$key")
                 ;;
         esac
     done
 
     prog_args=("$@")
 
+    if [ "${#src_files[@]}" -eq 0 ]; then
+        _runc_usage 'requires at least one source file path' >&2
+        return 1
+    fi
+
+    local -a _src_files=(${src_files[@]+"${src_files[@]}"})
+    src_files=()
+
+    local src_file
+    while IFS= read -d '' -r src_file; do
+        src_files+=("$src_file")
+    done < <( readlink -z --canonicalize-missing -- ${_src_files[@]+"${_src_files[@]}"} )
+
     local build_dir
     build_dir="$( mktemp --directory )"
 
-    trap "$( printf 'popd > /dev/null && rm -rf %q' "$build_dir" )" 0
+    trap "$( printf 'popd > /dev/null && rm -rf -- %q' "$build_dir" )" 0
     pushd "$build_dir" > /dev/null
 
     local output_name
-    output_name="$( mktemp --tmpdir=. "${FUNCNAME[0]}XXX.exe" )"
+    output_name="$( mktemp --tmpdir=. -- "${FUNCNAME[0]}XXX.exe" )"
 
     gcc -o "$output_name" \
         ${c_flags[@]+"${c_flags[@]}"} \
@@ -63,52 +87,76 @@ runc() (
 
 runcxx_flags=('-Wall' '-Wextra' '-std=c++14')
 
+_runcxx_usage() (
+    set -o errexit -o nounset -o pipefail
+
+    local msg
+    for msg; do
+        echo "${FUNCNAME[1]}: $msg"
+    done
+
+    echo "usage: ${FUNCNAME[1]} [-h|--help] [-c|--comp-arg ARG]... CPP_PATH... [-- [PROG_ARG]...]"
+)
+
 runcxx() (
     set -o errexit -o nounset -o pipefail
 
     local -a cxx_flags=(${runcxx_flags[@]+"${runcxx_flags[@]}"})
-    local -a src_files
+    local -a src_files=()
     local -a prog_args
 
     while [ "$#" -gt 0 ]; do
-        case "$1" in
+        local key="$1"
+        shift
+
+        case "$key" in
+            -h|--help)
+                _runcxx_usage
+                return 0
+                ;;
+
             -c|--comp-arg)
                 if [ "$#" -le 1 ]; then
-                    echo "${FUNCNAME[0]}: missing argument for parameter: $1" >&2
+                    _runcxx_usage "missing argument for parameter: $key" >&2
                     return 1
                 fi
-                shift
                 cxx_flags+=("$1")
                 shift
                 ;;
 
-            -h|--help)
-                echo "usage: ${FUNCNAME[0]} [-h|--help] [-c|--comp-arg ARG]... CPP_PATH... [-- [PROG_ARG]...]"
-                return 0
-                ;;
-
             --)
-                shift
                 break
                 ;;
 
             *)
-                src_files+=("$( realpath "$1" )")
-                shift
+                src_files+=("$key")
                 ;;
         esac
     done
 
     prog_args=("$@")
 
+    if [ "${#src_files[@]}" -eq 0 ]; then
+        _runcxx_usage 'requires at least one source file path' >&2
+        return 1
+    fi
+
+    local -a _src_files=(${src_files[@]+"${src_files[@]}"})
+    src_files=()
+
+    local src_file
+    while IFS= read -d '' -r src_file; do
+        src_files+=("$src_file")
+    done < <( readlink -z --canonicalize-missing -- ${_src_files[@]+"${_src_files[@]}"} )
+
     local build_dir
     build_dir="$( mktemp --directory )"
 
-    trap "$( printf 'popd > /dev/null && rm -rf %q' "$build_dir" )" 0
+    trap "$( printf 'popd > /dev/null && rm -rf -- %q' "$build_dir" )" 0
     pushd "$build_dir" > /dev/null
 
     local output_name
-    output_name="$( mktemp --tmpdir=. "${FUNCNAME[0]}XXX.exe" )"
+    output_name="$( mktemp --tmpdir=. -- "${FUNCNAME[0]}XXX.exe" )"
 
     g++ -o "$output_name" \
         ${cxx_flags[@]+"${cxx_flags[@]}"} \
diff --git a/%HOME%/.bash_utils/distr.sh b/%HOME%/.bash_utils/distr.sh
index ba92031..799f52f 100644
--- a/%HOME%/.bash_utils/distr.sh
+++ b/%HOME%/.bash_utils/distr.sh
@@ -20,11 +20,9 @@ sums_list_paths() (
                 echo "usage: ${FUNCNAME[0]} [-h|--help] [-0|-z]"
                 return 0
                 ;;
-
             -0|-z)
                 fmt='%s\0'
                 ;;
-
             *)
                 echo "${FUNCNAME[0]}: unrecognized parameter: $key" >&2
                 return 1
@@ -34,29 +32,38 @@ sums_list_paths() (
 
     [ -f "$sums_path" ] || return 0
 
+    local -a paths=()
+
     local path
     while IFS= read -r path; do
-        printf "$fmt" "$path"
-    done < <( sed --binary 's/^\\\?[[:alnum:]]\+ [ *]//' "$sums_path" )
+        paths+=("$path")
+    done < <( sed --binary -- 's/^\\\?[[:alnum:]]\+ [ *]//' "$sums_path" )
+
+    [ "${#paths[@]}" -eq 0 ] && return 0
+
+    printf -- "$fmt" ${paths[@]+"${paths[@]}"}
 )
 
 sums_update() (
     set -o errexit -o nounset -o pipefail
 
+    local -A existing
+    local -a missing=()
+
     local path
 
-    local -A existing
     while IFS= read -d '' -r path; do
         existing[$path]=1
     done < <( sums_list_paths -z )
 
-    local -a missing
     for path in "$@"; do
         if [ -z "${existing[$path]+x}" ]; then
             missing+=("$path")
         fi
     done
 
+    [ "${#missing[@]}" -eq 0 ] && return 0
+
     sha1sum -- ${missing[@]+"${missing[@]}"} >> "$sums_path"
 )
 
diff --git a/%HOME%/.bash_utils/file.sh b/%HOME%/.bash_utils/file.sh
index 0321833..6741067 100644
--- a/%HOME%/.bash_utils/file.sh
+++ b/%HOME%/.bash_utils/file.sh
@@ -27,7 +27,7 @@ swap_files() (
     fi
 
     local tmp_path
-    tmp_path="$( mktemp "$( dirname "$path1" )/XXX" )"
+    tmp_path="$( mktemp -- "$( dirname -- "$path1" )/XXX" )"
 
     mv "$path1" "$tmp_path"
     mv "$path2" "$path1"
diff --git a/%HOME%/.bash_utils/git.sh b/%HOME%/.bash_utils/git.sh
index 7b6c22c..5d74f39 100644
--- a/%HOME%/.bash_utils/git.sh
+++ b/%HOME%/.bash_utils/git.sh
@@ -10,49 +10,49 @@ source "$HOME/.bash_utils/text.sh"
 list_repo_files() (
     set -o errexit -o nounset -o pipefail
 
-    local -a cmd=(git ls-files)
+    local -a cmd=(git ls-tree -r)
 
     while [ "$#" -gt 0 ]; do
-        case "$1" in
-            -0|-z)
-                cmd+=(-z)
-                shift
-                ;;
-
+        local key="$1"
+        shift
+        case "$key" in
             -h|--help)
                 echo "usage: ${FUNCNAME[0]} [-h|--help] [-0|-z]"
                 return 0
                 ;;
-
+            -0|-z)
+                cmd+=(-z)
+                ;;
             *)
-                echo "${FUNCNAME[0]}: unrecognized parameter: $1" >&2
+                echo "${FUNCNAME[0]}: unrecognized parameter: $key" >&2
                 return 1
                 ;;
         esac
     done
 
+    cmd+=(--name-only HEAD)
+
     eval ${cmd[@]+"${cmd[@]}"}
 )
 
 list_repo_dirs() (
     set -o errexit -o nounset -o pipefail
 
-    local -a cmd=(git ls-tree -d -r)
+    local -a cmd=(git ls-tree -r -d)
 
     while [ "$#" -gt 0 ]; do
-        case "$1" in
-            -z|-0)
-                cmd+=(-z)
-                shift
-                ;;
-
+        local key="$1"
+        shift
+        case "$key" in
             -h|--help)
                 echo "usage: ${FUNCNAME[0]} [-h|--help] [-z|-0]"
                 return 0
                 ;;
-
+            -z|-0)
+                cmd+=(-z)
+                ;;
             *)
-                echo "${FUNCNAME[0]}: unrecognized parameter: $1" >&2
+                echo "${FUNCNAME[0]}: unrecognized parameter: $key" >&2
                 return 1
                 ;;
         esac
@@ -66,8 +66,8 @@ list_repo_dirs() (
 tighten_repo_security() (
     set -o errexit -o nounset -o pipefail
 
-    list_repo_files -z | xargs -0 chmod 0600
-    list_repo_dirs  -z | xargs -0 chmod 0700
+    list_repo_files -z | xargs -0 -- chmod 0600 --
+    list_repo_dirs  -z | xargs -0 -- chmod 0700 --
     chmod 0700 .git
 )
 
@@ -101,9 +101,9 @@ backup_repo() (
     set -o errexit -o nounset -o pipefail
 
     local repo_dir
-    repo_dir="$( realpath . )"
+    repo_dir="$( pwd )"
     local repo_name
-    repo_name="$( basename "$repo_dir" )"
+    repo_name="$( basename -- "$repo_dir" )"
     local backup_dir="$repo_dir"
 
     if [ $# -eq 1 ]; then
diff --git a/%HOME%/.bash_utils/path.sh b/%HOME%/.bash_utils/path.sh
index 7982427..4aff550 100644
--- a/%HOME%/.bash_utils/path.sh
+++ b/%HOME%/.bash_utils/path.sh
@@ -12,12 +12,12 @@ add_missing_path() (
 
     [ "$#" -eq 0 ] && return 0
 
-    local -a new_paths
+    local -a new_list
     local path
 
     while IFS= read -d '' -r path; do
-        new_paths+=("$path")
-    done < <( readlink --zero --canonicalize-missing -- "$@" )
+        new_list+=("$path")
+    done < <( readlink -z --canonicalize-missing -- "$@" )
 
     for path; do
         if str_contains "$path" ':'; then
@@ -26,21 +26,23 @@ add_missing_path() (
         fi
     done
 
-    local -A old_paths_dict
-    local -a old_paths_list
+    local -A old_dict
+    local -a old_list
 
-    while IFS= read -d '' -r path; do
-        old_paths_dict[$path]=1
-        old_paths_list+=("$path")
-    done < <( str_split -z -- "${PATH-}" ':' | xargs -0 readlink --zero --canonicalize-missing -- )
-
-    for path in ${new_paths[@]+"${new_paths[@]}"}; do
-        [ -n "${old_paths_dict[$path]+x}" ] && continue
-        old_paths_dict[$path]=1
-        old_paths_list+=("$path")
+    if [ -n "${PATH-}" ]; then
+        while IFS= read -d '' -r path; do
+            old_dict[$path]=1
+            old_list+=("$path")
+        done < <( str_split -z -- "${PATH-}" ':' | xargs -0 -- readlink -z --canonicalize-missing -- )
+    fi
+
+    for path in ${new_list[@]+"${new_list[@]}"}; do
+        [ -n "${old_dict[$path]+x}" ] && continue
+        old_dict[$path]=1
+        old_list+=("$path")
     done
 
-    str_join ':' ${old_paths_list[@]+"${old_paths_list[@]}"}
+    str_join ':' ${old_list[@]+"${old_list[@]}"}
 )
 
 add_path() {
diff --git a/%HOME%/.bash_utils/text.sh b/%HOME%/.bash_utils/text.sh
index 2228a8b..242837f 100644
--- a/%HOME%/.bash_utils/text.sh
+++ b/%HOME%/.bash_utils/text.sh
@@ -5,18 +5,18 @@
 # For details, see https://github.com/egor-tensin/cygwin-home.
 # Distributed under the MIT License.
 
-alias dos2eol='sed --binary --in-place '"'"'s/\(\r\?\)$//'"'"
-alias eol2dos='sed --binary --in-place '"'"'s/\r\?$/\r/'"'"
+alias dos2eol='sed --binary --in-place -- '"'"'s/\(\r\?\)$//'"'"
+alias eol2dos='sed --binary --in-place -- '"'"'s/\r\?$/\r/'"'"
 
-alias trim='sed --binary --in-place '"'"'s/[[:blank:]]*\(\r\?\)$/\1/'"'"
+alias trim='sed --binary --in-place -- '"'"'s/[[:blank:]]*\(\r\?\)$/\1/'"'"
 
-alias trimeol='sed --binary --in-place -e :a -e '"'"'/^\n*$/{$d;N;ba}'"'"
-alias trimdoseol='sed --binary --in-place -e :a -e '"'"'/^\(\r\n\)*\r$/{$d;N;ba}'"'"
+alias trimeol='sed --binary --in-place -e :a -e '"'"'/^\n*$/{$d;N;ba}'"'"' --'
+alias trimdoseol='sed --binary --in-place -e :a -e '"'"'/^\(\r\n\)*\r$/{$d;N;ba}'"'"' --'
 
-alias eol='sed --binary --in-place '"'"'$a\'"'"
-alias doseol='sed --binary --in-place '"'"'$s/\r\?$/\r/;a\'"'"
+alias eol='sed --binary --in-place -- '"'"'$a\'"'"
+alias doseol='sed --binary --in-place -- '"'"'$s/\r\?$/\r/;a\'"'"
 
-alias trimbom='sed --binary --in-place '"'"'1 s/^\xef\xbb\xbf//'"'"
+alias trimbom='sed --binary --in-place -- '"'"'1 s/^\xef\xbb\xbf//'"'"
 
 lint() {
     trim "$@" && trimeol "$@" && eol "$@"
@@ -39,7 +39,7 @@ replace_word() (
     local new="$1"
     shift
 
-    sed --binary --in-place "s/\\b$old\\b/$new/g" "$@"
+    sed --binary --in-place -- "s/\\b$old\\b/$new/g" "$@"
 )
 
 str_tolower() (
@@ -70,7 +70,7 @@ str_contains() (
 
     local str="$1"
     local sub
-    sub="$( printf '%q' "$2" )"
+    sub="$( printf -- '%q' "$2" )"
 
     test "$str" != "${str#*$sub}"
 )
@@ -85,7 +85,7 @@ str_starts_with() (
 
      local str="$1"
      local sub
-     sub="$( printf '%q' "$2" )"
+     sub="$( printf -- '%q' "$2" )"
 
      test "$str" != "${str#$sub}"
 )
@@ -93,34 +93,29 @@ str_starts_with() (
 str_split() (
     set -o errexit -o nounset -o pipefail
 
-    local zero=
+    local fmt='%s\n'
     local -a args
 
     while [ "$#" -ne 0 ]; do
-        case "$1" in
-            -0|-z)
-                zero=1
-                shift
-                ;;
-
+        local key="$1"
+        shift
+        case "$key" in
             -h|--help)
-                echo "usage: ${FUNCNAME[0]} [-z|-0] [-h|--help] [--] STR DELIM"
+                echo "usage: ${FUNCNAME[0]} [-h|--help] [-z|-0] [--] STR DELIM"
                 return 0
                 ;;
-
+            -0|-z)
+                fmt='%s\0'
+                ;;
             --)
-                shift
                 break
                 ;;
-
             -*)
-                echo "${FUNCNAME[0]}: unrecognized parameter: $1" >&2
+                echo "${FUNCNAME[0]}: unrecognized parameter: $key" >&2
                 return 1
                 ;;
-
             *)
-                args+=("$1")
-                shift
+                args+=("$key")
                 ;;
         esac
     done
@@ -128,7 +123,7 @@ str_split() (
     args+=("$@")
 
     if [ "${#args[@]}" -ne 2 ]; then
-        echo "usage: ${FUNCNAME[0]} [-z|-0] [-h|--help] [--] STR DELIM"
+        echo "usage: ${FUNCNAME[0]} [-h|--help] [-z|-0] [--] STR DELIM"
         return 1
     fi
 
@@ -138,14 +133,10 @@ str_split() (
     local -a xs
     local x
 
-    IFS="$old_delim" read -ra xs <<< "$str"
+    IFS="$old_delim" read -a xs -r <<< "$str"
 
     for x in ${xs[@]+"${xs[@]}"}; do
-        if [ -z "$zero" ]; then
-            printf '%s\n' "$x"
-        else
-            printf '%s\0' "$x"
-        fi
+        printf "$fmt" "$x"
     done
 )
 
@@ -169,10 +160,10 @@ str_join() (
         *)
             local s="$1"
             shift
-            printf '%s' "$s"
+            printf -- '%s' "$s"
 
             for s; do
-                printf '%s%s' "$delim" "$s"
+                printf -- '%s%s' "$delim" "$s"
             done
             ;;
     esac
-- 
cgit v1.2.3