]> ruderich.org/simon Gitweb - config/dotfiles.git/blobdiff - lib.sh
lib.sh: Add grep_i().
[config/dotfiles.git] / lib.sh
diff --git a/lib.sh b/lib.sh
index 204a8e9f95a2e695c4822682f85de7bf6cb1727c..474f638c42c8fc858418656ca59ad73e9adab8da 100644 (file)
--- a/lib.sh
+++ b/lib.sh
@@ -50,12 +50,71 @@ installed_path() {
     )
 }
 
+# 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 renamed 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 compatible 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" -- "$@"
+}
+
 # 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
@@ -115,67 +174,45 @@ link() {
     cd "$pwd"
 }
 
-# Write a warning to $1 to make clear it should not be modified. $2 is the
-# source for the generated file. Also print a message to stdout that the file
-# $1 was generated from $2 using the command $3 with options $4.
-warning() {
-    echo "###################################" > $1
-    echo "# WARNING! DO NOT EDIT THIS FILE! #" >> $1
-    echo "###################################" >> $1
-    echo >> $1
-    echo "# It was generated from $2 on `date`." >> $1
-    echo >> $1
-
-    # Display given options if there were any (Zsh has a problem with $options
-    # as variable name).
-    option=
-    if test -n "$4"; then
-        option=" with options '$4'"
-    fi
-    # Write message to stdout.
-    echo "$3: generating '$1' from '$2'$option"
-
-    unset option
-}
-
-# Generate a file using several methods. A warning not to edit it is
-# automatically added to the created file and a message printed to stdout
-# through warning().
+# Generate a file from a source file using a given command. A warning not to
+# edit it is automatically added to the created file.
 #
-# The following commands are possible; the file extension for the source file
-# in brackets.
+# Usage: generated() <file> <extension> <cmd..>
 #
-# - m4   (.m4): pipe $2.m4 through m4 then write it to $2
-# - awk  (.in): pipe $2.in through awk then write it to $2
-# - perl (.in): pipe $2.in through perl then write it to $2
-# - cat  ($3):  copy $2$3 to $2
+# 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.
-    command="$1"
-    file="$2"
-    # Remove arguments from list.
+    file="$1"
+    extension="$2"
     shift
     shift
 
-    # Set extension for the used commands. When cat is used $3 is used as
-    # extension.
-    if test x"$command" = xm4; then
-        extension=.m4
-    elif test x"$command" = xawk -o x"$command" = xperl; then
-        extension=.in
-    elif test x"$command" = xcat; then
-        extension="$1" # is $3 in reality, $1 because of shifting
-        shift
-    # Print a warning and exit if an unsupported command is used.
+    if test -z "$extension"; then
+        file_tmp="$file.tmp"
     else
-        echo "generate(): command '$command' not supported!" >&2
-        exit 1
+        # 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"
+        echo "# It was generated from $file$extension on `date`." >>"$file"
+        echo >>"$file"
+
+        file_tmp="$file"
     fi
 
-    # Add warning to file and write a message to stdout.
-    warning "$file" "$file$extension" $command "$*"
     # Generate $file from $file$extension using the given command.
-    cat "$file$extension" | $command "$@" >> "$file"
+    "$@" <"$file$extension" >>"$file_tmp"
 
-    unset command file
+    if test -z "$extension"; then
+        mv "$file_tmp" "$file"
+    fi
 }