diff options
Diffstat (limited to 'src/coreutils/cat.sh')
-rw-r--r-- | src/coreutils/cat.sh | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/coreutils/cat.sh b/src/coreutils/cat.sh new file mode 100644 index 0000000..52c3a93 --- /dev/null +++ b/src/coreutils/cat.sh @@ -0,0 +1,97 @@ +#!/bin/bash +# Bash alternative to external cat call +# +# Copyright (C) 2014 Mike Gerwitz +# +# This file is part of pkgsh. +# +# pkgsh is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# N.B. While this shell implementation may be faster for most use cases, the +# external binary will likely be much faster for large streams. +# +# This also contains some convenience functions that are not part of +# GNU coreutils. +## + +[ -z $__PKGSH_INC_COREUTILS_CAT ] || return +__PKGSH_INC_COREUTILS_CAT=1 + + +## +# Echo characters from stdin up to (but not including) the provided +# delimiter +cat-until() +{ + local -r delim="${1?Missing terminating delimiter}" + local -r file="${2:-/dev/stdin}" + + read -rd "$delim" < "$file" + local -ri result=$? + + echo -n "$REPLY" + return $result +} + + +## +# Echo characters from stdin up to and including the provided delimiter +cat-until-incl() +{ + # `cat-until` will validate + local -r delim="$1" + cat-until "$@" \ + && echo -n "$delim" +} + + +## +# Proxies to either the shell implementation of cat or the system binary, +# depending on support +cat() +{ + [[ "$1" =~ ^-[^-\ ] ]] \ + && command cat "$@" \ + || quickcat "$@" +} + + +## +# Limited implementation of `cat` for performance +# +# TODO: The proper research has not yet gone into optimizing this; this is +# just an initial implementation to get things going. I will be addressing +# this shortly. +# +# TODO: Exit status. +quickcat() +{ + local in="${1:-/dev/stdin}" + [ "$in" == - ] && in=/dev/stdin + readonly in + + while true; do + IFS= read -r || { + echo -n "$REPLY" + break + } + + echo "$REPLY" + done < "$in" + + if shift && [ $# -ne 0 ]; then + quickcat "$@" + fi +} + |