# Setup functions and settings used in subdirectories.
#
# Their setup.sh script sources this file.
# Copyright (C) 2009-2013 Simon Ruderich
#
# This program 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 .
# csh gives the error "Unknown colorls variable `su'." when used with newer
# options supported by Zsh or GNU ls.
unset LS_COLORS
# Check if the given program is installed. `type` is portable, `which` is not.
installed() {
type "$1" >/dev/null 2>&1
}
# 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 ...
#
# Run with all arguments (including the last file) and write the result
# to the temporary file .tmp and then renamed that file to . This
# can't be done in-place (e.g. cmd 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 ...
#
# sed -i is not compatible due to different implementations. See cmd_i.
sed_i() {
cmd_i sed "$@"
}
grep_i() {
cmd_i grep "$@"
}
# Usage: perl_line_filter ...
#
# 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 () { $cmd; print; }" "$@"
}
# Usage: simple_cpp .. -- ...
#
# Replaces each FIRST (on word boundaries) with 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" -- "$@"
}
# Print the current OS. The following OS are supported at the moment:
#
# - Debian (debian)
# - Gentoo (gentoo)
# - Mac OS X (darwin)
# - Solaris/OpenSolaris (sun)
# - FreeBSD (freebsd)
#
# If an unsupported OS is used an error is printed.
os() {
if test -f /etc/debian_version; then
echo debian
elif test -f /etc/gentoo-release; then
echo gentoo
elif test x`uname` = xDarwin; then
echo darwin
elif test x`uname` = xSunOS; then
echo sun
elif test x`uname` = xFreeBSD; then
echo freebsd
else
echo unsupported OS! >&2
return 1
fi
}
# Creates a symbolic link for file $1 in dirname of $2 with name of basename
# $2.
#
# `./link.sh example ~/.examplerc` creates a symbolic link to example
# (wherever it is located) in ~/ named .examplerc.
link() {
local pwd base source target >/dev/null 2>&1 || true
# Get all necessary paths.
pwd=`pwd`
base=`printf '%s' "$2" | sed "s|\~|$HOME|"` # expand ~, some sh don't do it
base=`dirname "$base"`
source=`printf '%s' "$pwd/$1" | sed "s|$base/||"`
target=`basename "$2"`
# Go to the directory where the link is going to be created.
cd "$base"
# Abort if the target file exists and is no symbolic link. Prevents
# overwriting real files.
if ( test -f "$target" && test ! -h "$target" ) || \
( test -s "$target" && test ! -h "$target" ); then
printf "link(): target '%s' exists already and is no symbolic link!" \
"$target" >&2
exit 1
fi
# Make sure the source exists (is file, directory or link).
if test ! -f "$source" && test ! -d "$source" && test ! -h "$source"; then
printf "link(): source '%s' doesn't exist!" "$source" >&2
exit 1
fi
# Create the new symbolic link; remove the old one if necessary.
printf "link(): linking '%s' to '%s'\n" "$source" "$target"
rm -f "$target"
ln -s "$source" "$target"
# Go back to the directory where we were before.
cd "$pwd"
}
# Generate a file from a source file using a given command. A warning not to
# edit it is automatically added to the created file.
#
# Usage: generated()
#
# If an empty extension is provided, the file is modified in-place (through a
# temporary file).
generate() {
local file >/dev/null 2>&1 || true
local file_tmp >/dev/null 2>&1 || true
local extension >/dev/null 2>&1 || true
# Get command and target file.
file="$1"
extension="$2"
shift
shift
if test -z "$extension"; then
file_tmp="$file.tmp"
else
# We only need this message if we generate a new file.
printf "%s: generating from '%s' (%s)\n" \
"$file" "$file$extension" "$1"
echo '###################################' >"$file"
echo '# WARNING! DO NOT EDIT THIS FILE! #' >>"$file"
echo '###################################' >>"$file"
echo >>"$file"
printf "# It was generated from '%s' on %s.\n" \
"$file$extension" "`date`" >>"$file"
echo >>"$file"
file_tmp="$file"
fi
# Generate $file from $file$extension using the given command.
"$@" <"$file$extension" >>"$file_tmp"
if test -z "$extension"; then
mv "$file_tmp" "$file"
fi
}