+# Get the path of the given program. Thanks to Gilles on [1] (read on
+# 2013-03-10) for the PATH-walking idea. `which` is not portable and `type`
+# has no well-formed output format.
+#
+# [1]: http://unix.stackexchange.com/questions/4988/how-do-i-test-to-see-if-an-application-exists-in-path/4991
+installed_path() {
+ test -z "$1" && return 1
+
+ # Keep IFS change local.
+ (
+ IFS=:
+ # Walk PATH.
+ for directory in $PATH; do
+ if test -x "$directory/$1"; then
+ printf '%s\n' "$directory/$1"
+ return 0
+ fi
+ done
+
+ return 1
+ )
+}
+
+# Usage: cmd_i <cmd> ... <file>
+#
+# Run <cmd> with all arguments (including the last file) and write the result
+# to the temporary file <file>.tmp and then rename that file to <file>. This
+# can't be done in-place (e.g. cmd <file >file) because it truncates the file.
+cmd_i() {
+ # Get last argument.
+ last=
+ for x; do
+ last="$x"
+ done
+
+ "$@" >"$last".tmp
+ mv "$last".tmp "$last"
+}
+
+# Usage: sed_i ... <file>
+#
+# sed -i is not portable due to different implementations. See cmd_i.
+sed_i() {
+ cmd_i sed "$@"
+}
+grep_i() {
+ cmd_i grep "$@"
+}
+
+# Usage: perl_line_filter <cmd> ...
+#
+# Run the perl command cmd on each line before printing it.
+perl_line_filter() {
+ cmd="$1"
+ shift
+
+ # Can't use -pe because it uses <> which treats the arguments as files.
+ perl -e "use strict; use warnings; while (<STDIN>) { $cmd; print; }" "$@"
+}
+
+# Usage: simple_cpp <FIRST> <SECOND> .. -- <replacement-for-first> ...
+#
+# Replaces each FIRST (on word boundaries) with <replacement-for-first> like a
+# simple cpp replacement.
+simple_cpp() {
+ cmd='my $i = 0;'
+
+ for x; do
+ shift
+
+ if test x"$x" = x--; then
+ break
+ fi
+
+ cmd="$cmd s/\\b$x\\b/\$ARGV[\$i]/g; \$i++;"
+ done
+
+ perl_line_filter "$cmd" -- "$@"
+}