#!/bin/bash
function COPYRIGHT () { cat <<'---'
This is the `eev-rctool' file of GNU eev.
Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.

This file is part of GNU eev.

GNU eev 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 2, or (at your option) any
later version.

GNU eev 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 GNU eev; see the file COPYING. If not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.

Author:     Eduardo Ochs <eduardoochs@gmail.com>
Maintainer: Eduardo Ochs <eduardoochs@gmail.com>
Version:    2008jan10
---
}
### Commentary:

# This is the new (mar2005) installer script for eev. Strangely, its
# main function is to modify rcfiles... Let me explain:
#
# Eev is able to send blocks of commands to many external interactive
# programs, but it usually only does half of the job: it saves the
# block of commands into a temporary file and only that, and then the
# user needs to tell the external program something like "now read the
# temporary file and execute its contents as commands".
#
# The trick is that we can abbreviate "now read the temporary file and
# execute its contents as commands" to just "ee" if we define "ee" in
# the right way for each one of these external programs; for example,
# for Bash one possible definition for "ee" would be:
#
#   function ee () { . ~/.eev/ee.sh; }
#
# and for GDB it could be:
#
#   define ee
#     source ~/.eev/ee.gdb
#   end
#
# The best way(*) to make Bash and GDB recognize these "ee" commands
# is to put these definitions in their initialition files, a.k.a.
# "rcfiles": ~/.bashrc for Bash, ~/.gdbinit for GDB, ~/.emacs for
# Emacs, etc.
#
# Changing rcfiles by hand is boring and error-prone; changing rcfiles
# automatically is extremely rude; and some people would go to great
# lengths to avoid actually changing their rcfiles. So this script has
# to try to be everything for everybody: it allows automatic patching
# of all or some rcfiles, it allows comparing the would-be-rcfiles
# with the current ones, it keeps backups to allow unpatching, and it
# permits executing the things that it does step-by-step.
#
# (*): "best" because it is technically simpler, easier to understand,
# less likely to break and the idea is easier to adapt to other
# programs; it's not "best" in the sense of "works transparently,
# invisibly and miraculously and requires no extra keystrokes".

function help_text () {
  echo 'Usage:

  Invocation                   Action
  ==========                   ======
  eev-rctool prepare_rc DIR    same as the next one but using EEVDIR:=DIR
  eev-rctool prepare_rc        create the modified and backup rcfiles and
                               the do_install.sh and do_uninstall.sh scripts
                               inside BACKUPDIR, using EEVDIR:=THISDIR
  eev-rctool diff_rc           show the differences between the modified
                               and the backup rcfiles
  eev-rctool install_rc        copy the modified rcfiles from BACKUPDIR to
                               HOME (actually runs BACKUPDIR/do_install.sh)
  eev-rctool uninstall_rc      copy the backup rcfiles from BACKUPDIR to
                               HOME (actually runs BACKUPDIR/do_uninstall.sh)

  eev-rctool prepare_tmpdir    create EEVTMPDIR and a few files in it
  eev-rctool prepare           run both prepare_tmpdir and prepare_rc

  eev-rctool help                    show instructions
  eev-rctool new_block_emacs         show the new eev block for .emacs
  eev-rctool current_block_emacs     show the current eev block for .emacs
  DIFF="tkdiff" eev-rctool diff_rc   like eev-rctool diff_rc, but using tkdiff

  Variable    Default value    Meaning
  ========    =============    =======
  THISDIR     ~/eev-current    (the dir where this script is)
  EEVDIR      ~/eev-current    (the dir where the elisp files are)
  EEVTMPDIR   ~/.eev           (where the temporary scripts are stored)
  BACKUPDIR   ~/.eev/backup    (where the modified and backup rcfiles
                                and the do_install.sh and do_uninstall.sh
                                scripts are kept)
  DIFF        "diff -N -c"     (what to run for diff_rc)
  RCFILES     ".emacs .bashrc .zshrc .gdbinit .tclshrc"
                               (which rcfiles to modify or inspect)'
}
function show_vars () {
  echo "Variable          Current value"
  echo "========          ============="
  echo "HOME            = $HOME"
  echo "THISDIR         = $THISDIR"
  echo "EEVDIR          = $EEVDIR"
  echo "EEVTMPDIR       = $EEVTMPDIR"
  echo "BACKUPDIR       = $BACKUPDIR"
  echo "INSTALLSCRIPT   = $INSTALLSCRIPT"
  echo "UNINSTALLSCRIPT = $UNINSTALLSCRIPT"
  echo "DIFF            = \"$DIFF\""
  echo "RCFILES         = \"$RCFILES\""
}
function help () { help_text; echo; show_vars; }



function notes () {
  cat <<'%%%'
Notes (technical & messy):

I need to reimplement parts of the functionality of eev-rctool in
elisp... the commands "install_rc" and "uninstall_rc" to eev-rctool
don't deal well with symlinks... also, in BSDs the "cp" command
doesn't have the option "-a", that in GNU cp means to try to preserve
as most the possible the attributes of the original file; I replaced
the "-a" by "-p", but I'm not sure if this is adequate. Suggestions?

  (find-node "(coreutils)cp invocation" "\n`-a'\n")

  (find-eev     "eev-rctool")
  (find-eevsh "./eev-rctool")
  (find-eevsh "./eev-rctool help")
  (find-eevsh "./eev-rctool show_vars")
  (find-eevsh "./eev-rctool     new_block_emacs")
  (find-eevsh "./eev-rctool current_block_emacs")
  (find-eevsh "./eev-rctool     new_block_bashrc")
  (find-eevsh "./eev-rctool current_block_bashrc")
  (find-eevsh "./eev-rctool     new_block_zshrc")
  (find-eevsh "./eev-rctool current_block_zshrc")
  (find-eevsh "./eev-rctool     new_block_gdbinit")
  (find-eevsh "./eev-rctool current_block_gdbinit")
  (find-eevsh "./eev-rctool     new_block_tclshrc")
  (find-eevsh "./eev-rctool current_block_tclshrc")

  (find-eevsh "./eev-rctool notes")
  (find-eev     "eev-rctool" "notes")
  (find-eev     "eev-rctool"     "new_block_emacs")
  (find-eev     "eev-rctool"     "new_block_emacs")
  (find-eev     "eev-rctool" "current_block_gdbinit")
%%%
}



# (find-eev "Makefile")
# (find-eevrc "change")
# (find-eevrc "change.awk")

# (find-bashnode "The Set Builtin" "`-e'")
# (find-bashnode "Shell Parameter Expansion" "`${PARAMETER:=WORD}'")
# (find-bashnode "Conditional Constructs" "`case'")

# (find-efunction 'sh-maybe-here-document)
# (remove-from-keymap sh-mode-map ?<)

set -e

function absolute () { case $1 in  /*) echo $1;;  *) echo $PWD/$1;;  esac; }
function semiabsolute () { absolute $1 | sed "s,^$HOME,~,"; }
function noslash () { sed 's_\(.\)/$_\1_'; }      # remove a trailing "/"
function stem () { echo $1 | sed 's/\.//'; }      # remove "."s
function v () { echo $*; $*; }
function vecho () { echo '#' $*; }

### Do I need noslash? or sed 's_//_/_g' ?
### h2so4 reported a bug involving a final slash in a Conectiva box
# export HOME=$(echo $HOME | no_final_slash)

THISSCRIPT=$(absolute $0)
THISDIR=$(cd $(dirname $THISSCRIPT); echo $PWD)
EEVDIR=$THISDIR

: ${DIFF:="diff -N -c"}

: ${RCFILES:=".emacs .bashrc .zshrc .gdbinit .tclshrc"}

: ${EEVTMPDIR:=$HOME/.eev}
: ${BACKUPDIR:=$EEVTMPDIR/backup}
: ${EEVRCDIR:=$EEVDIR/rcfiles}

INSTALLSCRIPT=$BACKUPDIR/do_install.sh
UNINSTALLSCRIPT=$BACKUPDIR/do_uninstall.sh

_EEVRCDIR=$(semiabsolute $EEVRCDIR)
_EEVDIR=$(semiabsolute $EEVDIR)
_EEVTMPDIR=$(semiabsolute $EEVTMPDIR)

function substitute_paths () {
  # this sed used to be just a simple cat (back when I didn't have the
  # "@...@"s in the eev chunks)
  sed -e "s,@EEVRCDIR@,$EEVRCDIR,g"   -e "s,@_EEVRCDIR@,$_EEVRCDIR,g"   \
      -e "s,@EEVDIR@,$EEVDIR,g"       -e "s,@_EEVDIR@,$_EEVDIR,g"       \
      -e "s,@EEVTMPDIR@,$EEVTMPDIR,g" -e "s,@_EEVTMPDIR@,$_EEVTMPDIR,g"
}

function wrap_block () {
  echo "$1 Beginning of the eev block:"
  echo "$1 See: (find-eev \"eev-rctool\" \"new_block_$2\")"
  echo "$1      (find-eev-update-links)"
  echo "$1"
  new_block_no_wrappers_$2 | substitute_paths
  echo "$1"
  echo "$1 End of the eev block."
}



#####
#
# generating the "eev blocks" that will be put in rcfiles
#
#####

function new_block_bashrc () { wrap_block '#' bashrc; }
function new_block_no_wrappers_bashrc () {
  new_block_no_wrappers_zshrc; # same as the eev block for .zshrc, below
}

function new_block_zshrc () { wrap_block '#' zshrc; }
function new_block_no_wrappers_zshrc () {
  cat <<'%%%'
export EEVTMPDIR ;: ${EEVTMPDIR:=@_EEVTMPDIR@}
export EE        ;: ${EE:=$EEVTMPDIR/ee.sh}
function ee () { set -v; . $EE$*; set +v; }
#
export EEVDIR    ;: ${EEVDIR:=@_EEVDIR@}
export EEVRCDIR  ;: ${EEVRCDIR:=$EEVDIR/rcfiles}
export EEG       ;: ${EEG:=$EEVTMPDIR/ee.eeg}
export EEGDB     ;: ${EEGDB:=$EEVTMPDIR/ee.gdb}
export EETEX     ;: ${EETEX:=$EEVTMPDIR/ee.tex}
#
export EEC       ;: ${EEC:=$EEVTMPDIR/ee.c}
export EETMPC    ;: ${EETMPC:=$EEVTMPDIR/tmp.c}
export EEAOUT    ;: ${EEAOUT:=$EEVTMPDIR/ee.aout}
function eegcc () {
  cat $EETMPC - > $EEC
  gcc $* -o $EEAOUT $EEC
}
alias eec=$EEAOUT
#
# To define $S and psne uncomment the line below (or copy it,
# uncommented, to outside of the eev block):
#   if [ -e $EEVTMPDIR/psne.sh ]; then . $EEVTMPDIR/psne.sh; fi
# (find-eevtmpfile "psne.sh")
%%%
}

function new_block_tclshrc () { wrap_block '#' tclshrc; }
function new_block_no_wrappers_tclshrc () {
  cat <<'%%%'
proc ee {} { global env; uplevel #0 source $env(EEVTMPDIR)/ee.tcl }
%%%
}

function new_block_gdbinit () { wrap_block '#' gdbinit; }
function new_block_no_wrappers_gdbinit () {
  cat <<'%%%'
define ee
  source @_EEVTMPDIR@/ee.gdb
end
%%%
}

function new_block_emacs () { wrap_block ';;' emacs; }
function new_block_no_wrappers_emacs () {
  cat <<'%%%'
(add-to-list 'load-path "@_EEVDIR@")
(require 'eev-all)      ; (find-eev "eev-all.el")
(eev-mode 1)
%%%
}

# 2007dec21: I changed the function above to make it use "eev-all.el".
# It used to do all this...
#
# function new_block_no_wrappers_emacs () {
#   cat <<'%%%'
# (add-to-list 'load-path "@_EEVDIR@")
# (load-library "eev.el")         ; (find-eev "eev.el")
# (eev-mode 1)                  ; (find-efunctiondescr 'eev-mode)
# (load-library "eev-bounded.el") ; (find-eev "eev-bounded.el")
# (load-library "eev-insert.el")  ; (find-eev "eev-insert.el")
# ;; (load-library "eev-steps.el")   ; (find-eev "eev-steps.el")
# (load-library "eev-mini-steps.el") ; (find-eev "eev-mini-steps.el")
# (load-library "eev-glyphs.el")  ; (find-eev "eev-glyphs.el")
# (load-library "eev-compose.el") ; (find-eev "eev-compose.el")
# (load-library "eev-langs.el")   ; (find-eev "eev-langs.el")
# (eev-set-aliases)               ; (find-eev "eev.el")
# (eev-set-default-glyphs)
# %%%
# }





#####
#
# the awk script
#
#####

# Usage:
#
#   run_awk_script PATCHFILE < OLDFILE > NEWFILE
#
# What this does: it reads PATCHFILE and OLDFILE and produces NEWFILE,
# which is OLDFILE with its "eev block" replaced by a new "eev block".
# The new "eev block" is given by PATCHFILE. If OLDFILE didn't have an
# "eev block" then we spit out a copy of OLDFILE, then a newline, then
# a copy of PATCHFILE.
#
# That was too obscure, so now let me explain that in all the details.
# PATCHFILE is typically like this (see `wrap_block', above):
#
#   ;; Beginning of the eev block:
#   (stuff)
#   ;; End of the eev block.
#
# or:
#
#   # Beginning of the eev block:
#   (stuff)
#   # End of the eev block.
#
# we read PATCHFILE and store its first line and its last line into
# the variables `firstline' and `lastline'. The "eev block" of OLDFILE
# is the part of OLDFILE that is between the first occurrence of
# `firstline' in it and the first ocurrence of `lastline' after that;
# what the awk script does is to replace that "eev block" by a new one
# (or to just append the new block at the end).
#
# Now some technical explanations about the code below: after reading
# PATCHFILE we set ARGV[1] to "-" so that awk will try to read from
# stdin afterwards; when we are reading from stdin (i.e., from
# OLDFILE) then state==0 means that we're before the first occurrence
# of "firstline", state==1 means that we're inside its "eev block",
# and state==2 means that we are past the "lastline". When state==0 or
# state==2 we echo the input lines to NEWFILE, when state==1 we skip
# lines, when we transition from state==1 to state==2 we print
# PATCHFILE. Finishing reading stdin in state==0 means that we still
# have to output a copy of PATCHFILE (preceded by a newline),
# finishing in state==1 is an error, and finishing with state==2 is
# ok.

function run_awk_script () {
  awk '
BEGIN {
  patchfile = ARGV[1]; n = 0;
  while ((getline line < patchfile) > 0) patchlines[++n] = line;
  firstline = patchlines[1]; lastline = patchlines[n];
  ARGV[1] = "-";
}
function printpatchfile (i) { for (i=1; i<=n; ++i) print patchlines[i]; }
function myerror (str) { print str > "/dev/stderr"; exit 1; }
#
state == 0 { if ($0 == firstline) state = 1; else print; }
state == 1 { if ($0 == lastline) { printpatchfile(); state = 2; next; } }
state == 2 { print }
END {
  if (state == 0) { print ""; printpatchfile(); }
  if (state == 1) myerror("Input file ends in the middle of the patch block");
  if (state == 2) { }
}' $1
}



# A quick hack: run_awk_script_2 is only used by the
# `current_block_xxxrc' functions below.
#
function run_awk_script_2 () {
  awk '
BEGIN {
  patchfile = ARGV[1]; n = 0;
  while ((getline line < patchfile) > 0) patchlines[++n] = line;
  firstline = patchlines[1]; lastline = patchlines[n];
  ARGV[1] = "-";
}
state == 0 { if ($0 == firstline) state = 1 }
state == 1 { print; if ($0 == lastline) state = 2 }
state == 2 { }
' $1
}

function current_block         () { run_awk_script_2 <(new_block_$1) < $2; }
function current_block_bashrc  () { current_block bashrc  ~/.bashrc;  }
function current_block_zshrc   () { current_block zshrc   ~/.zshrc;   }
function current_block_tclshrc () { current_block tclshrc ~/.tclshrc; }
function current_block_gdbinit () { current_block gdbinit ~/.gdbinit; }
function current_block_emacs   () { current_block emacs   ~/.emacs;   }







#####
#
# more auxiliary words
#
#####

# (eev "eev-rctool for_rcfile .emacs prepare_backup")

function for_rcfile () { set_vars_for_file $1; shift; $*; }    # for tests

function set_vars_for_file () {
  ORIGFILE=$HOME/$1
  BACKUPFILE=$BACKUPDIR/$1.backup
  NEWFILE=$BACKUPDIR/$1.new
  STEM=$(stem $1)
}

# 2008jan10: I replaced "cp -a" by "cp -p" here (experimentally)...
CP="cp -p"

function prepare_backup () {
  if [ -e $ORIGFILE ]; then
    echo      "  Backup:  $ORIGFILE  ->  $BACKUPFILE"
    $CP                   $ORIGFILE      $BACKUPFILE
    echo "echo '  Restore: $ORIGFILE  <-  $BACKUPFILE'" >> $UNINSTALLSCRIPT
    echo  "$CP $BACKUPFILE $ORIGFILE"                  >> $UNINSTALLSCRIPT
  else
    echo "echo '  Remove:  $ORIGFILE'"                  >> $UNINSTALLSCRIPT
    echo "rm               $ORIGFILE"                   >> $UNINSTALLSCRIPT
  fi
}

function transform () {
  if [ -e $ORIGFILE ]; then
    run_awk_script <(new_block_$STEM) < $BACKUPFILE > $NEWFILE
  else
    new_block_$STEM
  fi
}

function prepare_new () {
  transform $ORIGFILE > $NEWFILE
  echo "echo '  Install: $ORIGFILE  <-  $NEWFILE'" >> $INSTALLSCRIPT
  echo "cp $NEWFILE $ORIGFILE"     >> $INSTALLSCRIPT
}
 


#####
#
# creating the eev temp dir (usually ~/.eev) and some files in it
#
#####

function create_tmpdir_file_maybe () {
  if [ -e $EEVTMPDIR/$1 ]; then
    echo "  Not changing: $EEVTMPDIR/$1"
  else
    echo "  Creating:     $EEVTMPDIR/$1"
    cat > $EEVTMPDIR/$1
  fi
}

function create_help () {
  create_tmpdir_file_maybe HELP <<'---'
  M-?    eev-help-page (*)         Evaluation:
  C-_    undo                        C-x C-e   eval-last-sexp
  C-g    keyboard-quit               M-e       eek-eval-sexp-eol (*)
  M-x    execute-extended-command    M-E       eek-eval-last-sexp (*)
  TAB    indent/complete             M-0 M-e, M-0 M-E  just highlight (*)
                                        (* (+ 1 2) (+ 3 4))
  C-w    kill-region (cut)
  M-w    kill-ring-save (copy)     "Return from hyperlinks":
  C-y    yank (paste)                M-k      kill-this-buffer (*)
                                     M-K      bury-buffer (*)
  C-x C-s  save-buffer               C-x C-b  buffer-menu
  C-x C-c  save-buffers-kill-emacs 
  C-x C-f  find-file               Main docs:                          
                                     (find-efunctiondescr 'eev-mode)   
  C-x 0   delete-window              (find-eevfile "article/eev.txt")  
  C-x 1   delete-other-windows       (find-eevfile "doc/keys.e")       
  C-x 2   split-window-vertically                                      
  C-x o   other-window               (find-node "(emacs)Top")          
  C-x b   switch-to-buffer           (find-node "(emacs)Concept Index")
  C-x k   kill-buffer                (find-node "(emacs)Command Index")
                                     (find-node "(emacs)Key Index")    
                                     (find-node "(elisp)Top")          
                                     (find-node "(elisp)Index")        
                                     (find-elinode "Index")            

  [Used in a workshop about Emacs and eev:]
  (tool-bar-mode)
  (menu-bar-mode nil)
  http://www.paulgraham.com/lib/paulgraham/jmc.ps
  (code-ps "pgroots" "$S/http/www.paulgraham.com/lib/paulgraham/jmc.ps")
  (find-pgrootspage 8)
  (find-eev "eev-rctool" "create_help")
---
}

function create_psnesh () {
  create_tmpdir_file_maybe psne.sh <<'---'
# -*- mode: sh -*-
# This is the `rcfiles/psne.sh' file of GNU eev.
# It was created by: (find-eev "eev-rctool" "create_psnesh")
# Author and version: Eduardo Ochs, 2005jun12. Public Domain.

# To activate the `psne' command (and to define the S variable if it
# is not already defined), source this file; it works on zsh, and it
# should also work on bash and on most sh-derivatives -- but note: I
# don't use non-zsh shell very often, I might have skipped some bugs.

# The installation scripts of eev add a few lines to your .bashrc and
# .zshrc to make bash and zsh read this file on startup.
# (find-eev "eev-rctool" "new_block_bashrc")
# (find-eev "eev-rctool" "new_block_zshrc")
#
# This is a simple implementation of `psne' for bash and zsh.
# Example: "psne http://www.foo.bar/mm" will run this:
#
#   mkdir -p $S/http/www.foo.bar/ && \
#   cd       $S/http/www.foo.bar/ && \
#   wget http://www.foo.bar/mm
#
# Note that after running that "psne" we are left at the directory
# "~/snarf/http/www.foo.bar/".

export S;: ${S:=~/snarf}

function psne-sh-sed-snarfize () { sed 's,^\([a-z]*\)://,$S/\1/,'; }
function psne-sh-urlp () { echo $1 | egrep -q '^(http|ftp)://'; }
function psne-sh-meta () {(
  URL=$1
  SURL=$(echo $1 | psne-sh-sed-snarfize)
  DIR=$(dirname $SURL)
  echo "mkdir -p $DIR/ && \\"
  echo "cd       $DIR/ && \\"
  echo "wget $URL"
);}
function psne-sh () {
  if psne-sh-urlp $1; then
    eval "$(psne-sh-meta $1)"
    echo $1 >> ~/.psne.log
  else
    echo "Not an url: $1"
  fi
}
alias psne=psne-sh

# (find-sh ". $EEVTMPDIR/psne.sh; psne-sh-meta http://www.foo.bar/mm")
# (find-node "(bashref)The Set Builtin" "`e'")
---
}

function create_tmptex () {
  create_tmpdir_file_maybe tmp.tex <<'---'
% This is the `$EEVTMPDIR/tmp.tex' file of GNU eev.
% It was created by: (find-eev "eev-rctool" "prepare_tmpdir")
% Author and version: Eduardo Ochs, 2005mar31. Public domain.
% If you run `eelatex' in a block in Emacs and then go to a shell and
% type `ee' you'll notice that this is the file that will be LaTeX'ed
% (unless you've changed the defaults). This is a wrapper around
% ee.tex.

\documentclass{book}
\usepackage[latin1]{inputenc}
\usepackage{amsmath}
\usepackage{graphicx}
\begin{document}

\input ee.tex

\end{document}
---
}

function prepare_tmpdir () {
  echo "  Creating dir: $EEVTMPDIR/"
  mkdir -p $EEVTMPDIR
  echo "  Creating:     $EEVTMPDIR/README"
  cat > $EEVTMPDIR/README <<'---'
This is the `$EEVTMPDIR/README' file of GNU eev.
It was created by: (find-eev "eev-rctool" "prepare_tmpdir")
This directory is where eev saves most of its temporary scripts.
If other people have access to your home directory then you should
consider making this directory accessible only by you.

The files with names starting with "ee" are temporary files created by eev.
The files with names starting with "tmp" are usually wrappers. See tmp.tex.
The file psne.sh is something more complicated. Look at its comments.
The file HELP is used by `M-?'.  See: (find-efunction 'eev-help-page)

  Eduardo Ochs
  2005aug15
---
  create_help      ;# (find-eev "eev-rctool" "create_help")
  create_psnesh    ;# (find-eev "eev-rctool" "create_psnesh")
  create_tmptex    ;# (find-eev "eev-rctool" "create_tmptex")
}




#####
#
# top-level words
#
#####

function prepare_rc () {
  if [ "$1" != "" ]; then EEVDIR=$1; fi
  echo "  Creating dir: $BACKUPDIR/"
  mkdir -p $BACKUPDIR
  echo "  Creating:     $INSTALLSCRIPT"
  echo "# Automatically generated by eev-rctoll" > $INSTALLSCRIPT
  echo "# in $(date)"                           >> $INSTALLSCRIPT
  echo "  Creating:     $UNINSTALLSCRIPT"
  echo "# Automatically generated by eev-rctoll" > $UNINSTALLSCRIPT
  echo "# in $(date)"                           >> $UNINSTALLSCRIPT
  for i in $RCFILES; do 
    set_vars_for_file $i
    prepare_backup
  done
  for i in $RCFILES; do 
    set_vars_for_file $i
    echo "  Creating:     $NEWFILE"
    prepare_new
  done
}

function diff_rc () {
  for i in $RCFILES; do 
    set_vars_for_file $i
    $DIFF $BACKUPFILE $NEWFILE || true
  done
}

function install_rc () {
  echo "  Running: $INSTALLSCRIPT"
  if [ -e $INSTALLSCRIPT ]; then
    sh $INSTALLSCRIPT
  else
    echo Error: $INSTALLSCRIPT not found!
  fi
}

function uninstall_rc () {
  echo "  Running: $UNINSTALLSCRIPT"
  if [ -e $UNINSTALLSCRIPT ]; then
    sh $UNINSTALLSCRIPT
  else
    echo Error: $UNINSTALLSCRIPT not found!
  fi
}

function prepare () { prepare_tmpdir; prepare_rc $1; }




#####
#
# Process the command-line arguments
#
#####

# (find-node "(bash)Conditional Constructs" "dog | cat")
# This used to be just:
# $*

function __help () { help $*; }
function _h ()     { help $*; }

COMMAND=$(echo $1 | tr \\- _)
: ${COMMAND:=help}
shift || true

$COMMAND $*








# (find-node "(gawk)ARGC and ARGV")
# (find-node "(gawk)Auto-set" "`ARGIND #'")

# Local Variables:
# ee-anchor-format: "\nfunction %s ()"
# End: