diff options
-rw-r--r-- | functions.sh | 36 | ||||
-rwxr-xr-x | test-functions | 126 |
2 files changed, 122 insertions, 40 deletions
diff --git a/functions.sh b/functions.sh index cfaddc3..ccd0d1d 100644 --- a/functions.sh +++ b/functions.sh @@ -61,21 +61,41 @@ chdir() # contains_all() { - [ "$#" -ge 2 ] && IFS=${IFS} awk -f - -- "$@" <<-'EOF' + # shellcheck disable=2097,2098 + [ "$#" -ge 2 ] && + IFS=${IFS} awk -v ifs_set=${IFS+1} -f - -- "$@" <<-'EOF' BEGIN { - ifs = ENVIRON["IFS"] haystack = ARGV[1] argc = ARGC ARGC = 1 + if (ifs_set) { + ifs = ENVIRON["IFS"] + } else { + ifs = " \t\n" + } + # Translate IFS to FS, in accordance with section 2.6.5. if (length(ifs) == 0) { FS = "^" - } else if (length(ifs) != 3 || ifs ~ /[^ \t\n]/) { - # Split by the first character of IFS. - FS = "[" substr(ifs, 1, 1) "]" } else { - # Mimic default field splitting behaviour, per section 2.6.5. - FS = "[ \t\n]+" - sub("^" FS, "", haystack) + whitespace = "" + FS = "(" + for (i = 1; i <= length(ifs); i++) { + char = substr(ifs, i, 1) + if (seen[char]++) { + continue + } else if (char ~ /[ \t\n]/) { + whitespace = whitespace char + FS = FS "[" char "]+|" + } else { + FS = FS "[" char "]|" + } + } + sub(/\|$/, "", FS) + FS = FS ")" + } + # Leading whitespace characters must be removed. + if (length(whitespace) > 0) { + sub("^[" whitespace "]+", "", haystack) } # In sh, fields are terminated, not separated. sub(FS "$", "", haystack) diff --git a/test-functions b/test-functions index 59c0b29..dab0aea 100755 --- a/test-functions +++ b/test-functions @@ -721,43 +721,105 @@ test_substr() { test_contains_all() { set -- \ - ge 1 N/A N/A N/A N/A \ - ge 1 'foo bar' '' N/A N/A \ - ge 1 'foo bar' '' ' ' N/A \ - ge 1 'foo bar' '' ' bar' N/A \ - ge 1 'foo bar' '' ' bar' N/A \ - ge 1 'foo bar' '' 'foo ' N/A \ - ge 1 'foo bar' '' 'foo bar' N/A \ - ge 1 'foo bar' ' ' '' N/A \ - ge 1 'foo bar' ' ' ' ' N/A \ - ge 1 'foo bar' ' ' N/A N/A \ - ge 1 'foo bar' ' bar' '' N/A \ - ge 1 'foo bar' ' bar' N/A N/A \ - ge 1 'foo bar' 'foo ' '' N/A \ - ge 1 'foo bar' 'foo ' ' bar' N/A \ - ge 1 'foo bar' 'foo ' N/A N/A \ - ge 1 'foo bar' 'foo bar' '' N/A \ - ge 1 'foo bar' 'foo bar' N/A N/A \ - ge 1 'foo bar' N/A N/A N/A \ - ge 1 'foo bar' bar foo '' \ - ge 1 'foo bar' bar foo ' ' \ - ge 1 'foo bar' baz bar foo \ - ge 1 'foo bar' fo ba N/A \ - ge 1 'foo bar' foo bar '' \ - ge 1 'foo bar' foo bar ' ' \ - ge 1 'foo bar' foo bar baz \ - ge 1 'foo bar' o a N/A \ - ge 1 'foo bar' oo ar N/A \ - eq 0 'foo bar' foo bar N/A \ - eq 0 'foo bar' bar foo N/A + ge 1 default N/A N/A N/A N/A \ + ge 1 default ' foo bar ' '' N/A N/A \ + ge 1 default ' foo bar ' '' ' ' N/A \ + ge 1 default ' foo bar ' '' ' bar' N/A \ + ge 1 default ' foo bar ' '' 'foo ' N/A \ + ge 1 default ' foo bar ' '' 'foo bar' N/A \ + ge 1 default ' foo bar ' ' ' '' N/A \ + ge 1 default ' foo bar ' ' ' ' ' N/A \ + ge 1 default ' foo bar ' ' ' N/A N/A \ + ge 1 default ' foo bar ' ' bar' '' N/A \ + ge 1 default ' foo bar ' ' bar' N/A N/A \ + ge 1 default ' foo bar ' 'foo ' '' N/A \ + ge 1 default ' foo bar ' 'foo ' ' bar' N/A \ + ge 1 default ' foo bar ' 'foo ' N/A N/A \ + ge 1 default ' foo bar ' 'foo bar' '' N/A \ + ge 1 default ' foo bar ' 'foo bar' N/A N/A \ + ge 1 default ' foo bar ' N/A N/A N/A \ + ge 1 default ' foo bar ' bar foo '' \ + ge 1 default ' foo bar ' bar foo ' ' \ + ge 1 default ' foo bar ' baz bar foo \ + ge 1 default ' foo bar ' fo ba N/A \ + ge 1 default ' foo bar ' foo bar '' \ + ge 1 default ' foo bar ' foo bar ' ' \ + ge 1 default ' foo bar ' foo bar baz \ + ge 1 default ' foo bar ' o a N/A \ + ge 1 default ' foo bar ' oo ar N/A \ + eq 0 default ' foo bar ' foo bar N/A \ + eq 0 default ' foo bar ' bar foo N/A \ + ge 1 ', ' N/A N/A N/A N/A \ + ge 1 ', ' ' foo bar ' '' N/A N/A \ + ge 1 ', ' ' foo bar ' '' ' ' N/A \ + ge 1 ', ' ' foo ,bar, ' '' ',' N/A \ + ge 1 ', ' ' foo bar ' '' ' bar' N/A \ + ge 1 ', ' ' foo ,bar ' '' ',bar' N/A \ + ge 1 ', ' ' foo bar ' '' 'foo ' N/A \ + ge 1 ', ' ' foo, bar ' '' 'foo,' N/A \ + ge 1 ', ' ' foo bar ' '' 'foo bar' N/A \ + ge 1 ', ' ' foo bar ' ' ' '' N/A \ + ge 1 ', ' ' foo,bar, ' ',' '' N/A \ + ge 1 ', ' ' foo bar ' ' ' ' ' N/A \ + ge 1 ', ' ',foo,,bar,' ',' ',' N/A \ + ge 1 ', ' ' foo bar ' ' ' N/A N/A \ + ge 1 ', ' ',foo,,bar,' ',' N/A N/A \ + ge 1 ', ' ' foo bar ' ' bar' '' N/A \ + ge 1 ', ' 'foo,bar,' ',bar' '' N/A \ + ge 1 ', ' ' foo bar ' ' bar' N/A N/A \ + ge 1 ', ' ',foo,,bar,' ',bar' N/A N/A \ + ge 1 ', ' ' foo bar ' 'foo ' '' N/A \ + ge 1 ', ' 'foo,bar,' 'foo,' '' N/A \ + ge 1 ', ' ' foo bar ' 'foo ' ' bar' N/A \ + ge 1 ', ' ',foo,,bar,' 'foo,' ',bar' N/A \ + ge 1 ', ' ' foo bar ' 'foo ' N/A N/A \ + ge 1 ', ' ',foo,,bar,' 'foo,' N/A N/A \ + ge 1 ', ' ' foo bar ' 'foo bar' '' N/A \ + ge 1 ', ' 'foo,bar,' 'foo,bar' '' N/A \ + ge 1 ', ' ' foo bar ' 'foo bar' N/A N/A \ + ge 1 ', ' ',foo,,bar,' 'foo,,bar' N/A N/A \ + ge 1 ', ' ' foo bar ' N/A N/A N/A \ + ge 1 ', ' ' foo bar ' bar foo '' \ + ge 1 ', ' ' foo,bar ' bar foo '' \ + ge 1 ', ' ' foo bar ' bar foo ' ' \ + ge 1 ', ' ' foo,,bar ' bar foo ',' \ + ge 1 ', ' ' foo bar ' baz bar foo \ + ge 1 ', ' ',foo,,bar,' baz bar foo \ + ge 1 ', ' ' foo bar ' fo ba N/A \ + ge 1 ', ' ',foo,,bar,' fo ba N/A \ + ge 1 ', ' ' foo bar ' foo bar '' \ + ge 1 ', ' ' foo,bar ' foo bar '' \ + ge 1 ', ' ' foo bar ' foo bar ' ' \ + ge 1 ', ' ' foo,,bar ' foo bar ',' \ + ge 1 ', ' ' foo bar ' foo bar baz \ + ge 1 ', ' ',foo,,bar,' foo bar baz \ + ge 1 ', ' ' foo bar ' o a N/A \ + ge 1 ', ' ',foo,,bar,' o a N/A \ + ge 1 ', ' ' foo bar ' oo ar N/A \ + ge 1 ', ' ',foo,,bar,' oo ar N/A \ + eq 0 ', ' ' foo bar ' foo bar N/A \ + eq 0 ', ' ',foo bar,' foo bar N/A \ + eq 0 ', ' ' foo,,bar ' foo bar N/A \ + eq 0 ', ' ',foo,,bar,' foo bar N/A \ + eq 0 ', ' ' foo bar ' bar foo N/A \ + eq 0 ', ' ',foo bar,' bar foo N/A \ + eq 0 ', ' ' foo,,bar ' bar foo N/A \ + eq 0 ', ' ',foo,,bar,' bar foo N/A callback() { shift - test_description="contains_all $(quote_args "$@")" - contains_all "$@" + ifs=$1 + shift + if [ "${ifs}" = "default" ]; then + test_description="contains_all $(quote_args "$@")" + contains_all "$@" + else + test_description="IFS='${ifs}' contains_all $(quote_args "$@")" + IFS=${ifs} contains_all "$@" + fi } - iterate_tests 6 "$@" + iterate_tests 7 "$@" } test_contains_any() { |