This directory contains scripts used by Ben for developing XEmacs
(and now, as of 2008, lots of other useful scripts I've written).

If you make use of the aliases and functions I've set up in .bashrc, then
you will have a powerful and easy-to-use system of building XEmacs, doing
various CVS powerful operations and diffs, doing searches over a whole
workspace, working in many workspaces at once, automating a multi-build
process (build XEmacs in many different configurations at once), easily
getting around from directory to directory using fast aliases, etc.

1. First, set up basic configuration information in ./config-inc.
   The only thing you really need to change is the location of your
   top-level src directory.  This assumes that all of your workspaces are
   direct subdirectories off of this top-level directory.  You way also
   want to set the build directory, where all the building will happen
   (this allows multiple builds to happen at once with the same source tree
   and different configuration parameters).  A good place to put the build
   directory would be on a separate disk from the source disk, or a large
   RamDISK.  Alternatively, don't change the config files but use a symlink
2. Familiarize yourself with the build options provided.  Each option has a
   name and controls some sort of parameter to  There are a
   series of configurations listed in config-inc, and for the moment,
   just use those.  Start out with `basic' and then try `1' and maybe '2'.
   At that point you can try more possibilities, such as `all', which tests
   on a lot of configurations and really stress-tests the code.  Look in
   `generate-build-values' to see what exactly the options do in terms of
   arguments to `configure'.
3. Take a look at the functions and aliases in `bash-functions'.  This is
   meant to work under either bash or zsh, and can be sourced directly into
   your .bashrc or .zshrc.  Also see `sample.bashrc', which shows a sample
   .bashrc/.zshrc that makes use of `bash-functions'.
4. To build, use `build WORKSPACE [CONFIG ...]' or the shorter alias
   `bu ...', where WORKSPACE is the name of a workspace (i.e. a direct
   subdirectory of your top-level src directory) and CONFIG is a configuration
   as specified in (2) above and in `'.
5. See also the other useful scripts and aliases.

*                      SOME USEFUL ALIASES/FUNCTIONS                     * 

See also the scripts below.  Some of the aliases are just shorter names
of the scripts, or call the scripts with convenient options.

******** Grepping ********

`rg GREP-ARGS ...'
  Recursive grep, excluding annoying files.  Remaining args are passed to
  `egrep', but should not include file names.  Greps all files recursively
  but excludes annoying files such as binary files, backups, CVS
  directories, .orig files, TAGS files, .#... files, etc.

******** Merging ********

A merge happens happens when you make a change to a file while meanwhile
someone else makes a change to the same file.  The second one who checks in
has to merge the other one's changes into his version.  When you run `cvs
update', CVS tries to automate the merge, but merge conflicts can arise,
esp. when you and the other guy are both modifying the same part of the
code.  In this case, your working version is the (broken) merged file, and
your file in its state before merging is difficult to locate.  `cthis'
tells you what changes you had made at the point you checked the file in
and begun to merge.  `cthat' similarly tells you the changes the other guy
made.  The merge is the process of combining these two.  Take a look at the
comments in `cvs-merge-diff' for full info about the merging process and
what exactly is going on.

`cthis FILE ...' or `cs FILE ...'
  After a merge on a file -- what change did I make that led to the merge?

`cthat FILE ...' or `ct FILE ...'
  After a merge on a file -- what change did the other guy make that led to
  the merge?

`cldiff [NUM] FILE ...'
  Diff most-recently checked in version and its parent or ancestor.  Do a
  diff between the most-recently checked in version of a file and its
  parent, telling you what changes were put in by the most-recently checked
  in version.  With a number, diff with the NUM'th most recent parent.

******** CVS work ********


  Replacement for `cvs' that works when modifying the tree.  May not be
  as reliable as plain `cvs' for other operations. (#### Do we still need

`cdi [--no-changelog] [--help] [--cvs-command COMMAND] [DIFF-ARG ...]
  [FILES ...]'

  Uses `cvs-diff' below.  Front end to `cvs diff', and pass through
  `more'.  Does the following in addition to a simple `cvs diff':

  -- removes ChangeLog diffs from the diff output, and (unless --no-changelog
     was specified) prepends the entries to the beginning of the diff.  This
     is useful for submitting a diff to the maintainers.
  -- removes the generated files auto-autoloads.el, custom-load.el,
     custom-defines.el, depend, and configure from the output.
  -- fixes CVS bug when specifying files to diff in multiple directories.
  -- hacks the line used by `patch' to contain the directory relative to
     the workspace root, so you can easily apply this patch to another
  -- `--cvs-command' specifies the command to use in place of just "cvs".

`cup [--help] [--cvs-command COMMAND] [CVS-UPDATE-ARGS ...]'

  Alias for `cvs-update' below.  Front end to `cvs update'.
  Does the following in addition to a simple `cvs update':
  -- if the tree was checked out R/W using `checkout -w', keep it that way.
  -- if configure or are checked out, rerun autoconf (and
  -- when updating ChangeLogs, automatically resolve conflicts.
  -- output a summary of the update results at the end.  Lists (in the
     following order, with the most important info last) the files that were
     locally modified, updated, added, deleted, merged without conflicts,
     and merged with conflicts, followed by any additional CVS warnings.
  -- `--cvs-command' specifies the command to use in place of just "cvs".

`ccom ...'

  Front end to `crw commit'.
  Works around the buggy CVS server we have that will not process top-level
  files in some circumstances.
  If no files are specified, runs the commit command twice, the second time
  forcibly picking up the top-level files omitted the first time, due to a
  nasty CVS bug.
  NOTE: There may still be problems when you explicitly specify files both on
  the top level and down below; this isn't handled right yet.

`cvs-undo-file [DIFF-ARGS ...] FILE ...'

  Undo the last change made to FILE in the repository.
  Commit the workspace to make permanent.

******** Building ********


  Basic function to build a workspace from scratch.  Run `build' script
  below with `--keep-going' and `scratch'.  See `build' below.


  Basic function to rebuild an existing workspace.  Run `build' script
  below with `--keep-going' and `rebuild'.  See `build' below.

  Same as `bu' and `rebu' but don't filter the output.

*                              	THE SCRIPTS                              * 

Normally I suggest using the aliases set up in .bashrc and described above.
However, if you want to write your own aliases, the scripts themselves are

I am gradually working on making these scripts more powerful and generally
applicable.  For the moment, the best-written and most-useful scripts are

*                   CVS Scripts                     *


  See above.

`cvs-diff [--no-changelog] [--help] [--cvs-command COMMAND] [DIFF-ARG ...]
  [FILES ...] [OPTIONS ...]'

  Implementation of `cdi' alias.  See above.

`cvs-update [--help] [--cvs-command COMMAND] [CVS-UPDATE-ARGS ...]'

  Implementation of `cup' alias.  See above.

`cvs-commit ...'

  Implementation of `ccom' alias.  See above.

`cvs-merge-diff -from SPEC -to SPEC FILE'

  This is the underlying implementation of `cthis/cs', `cthat/ct', and
  `cldiff' above.

  Do a diff between various versions of a file, no weird tag syntax necessary.
  Quite useful after an update when a manual merge is in progress.  Then
  you can easily get the diffs that you did that triggered the merge, and
  the diffs that the other guy did.
  Or, in general, do a diff between your local workspace and n commits
  back in time.
  Shows the diff between different versions of a file, after a merge.  SPEC
  is one of Z, A, B, C, or D or a number, according to the following diagram.
        NOT AFTER A MERGE:              AFTER A MERGE:
        Ancestor (2,3,...)       Common Ancestor's Parent (Z)
             |                               |
             |                               |
             |                               |
             |                               |
             |                        Common Ancestor (A)
          Parent (1)                        |   \\
             |                              |    \\
             |                              |  Ancestor (2,3,...)
             |                              |      \\
             |                              |       \\
             |                              |      Parent (1)
        Repository (C)                      |         \\
          Change                            |          \\
             |                        Pre-Merge (B)  Repository (C)
             |                        (in this ws)     Change
             |                              |         /
             |                              |        /
             |                              |       /
             |                              |      /
          Working                       Post-Merge (D)
         Version (D)                    (needs fixup)
  Note that in the after-merge case, there is no fixed ordering between the
  common ancestor (A) and any of the numbered ancestors of (C) -- (A) could
  be the same as (1), (3), (8), or any other ancestor.

*               Search/Replace Scripts              *

  Global search and replace over files specified on the command line.
  Store old files in `.backup.orig/'.

  Like `gr' but global search and replace recursively over wildcard

  Underlying implementation of global search/replace scripts; meant to
  be called from `find ... | xargs global-replace ...' or
  `find ... -print0 | xargs -0 global-replace ...'

*                   Build Scripts                   *

I've designed a comprehensive build system.  The idea is that you have
separate workspaces, and each of them can be configured and built in
various ways. (This is handled using the --srcdir option when configuring,
so that the built files go into a separate tree from the source.) You can
easily issue commands to build a specified workspace according to a
specified configuration, a list of specified configurations, or all
possible configurations.  The output that appears on the screen while
building is happening is filtered, so that only error messages, and a small
number of status messages showing the major stages, appear.  Both the
filtered and full output are available in log files.

All configuration information is specified in a single place, the file
`config-inc'.  Workspaces are assumed to be parallel subdirectories
under a single parent, and are specified using the name of the workspace
directory; that makes it easy to add and move around workspaces without
constantly having to update the config info.

If an error happens, the build can be continued from where it last left off.

Configurations are given short names (often numerical); each configuration
is a list of "features" that should or should not be present when building.
Each feature is a single word that translates to some argument or arguments
to `configure'.  For example, `cpp' means use C++ to compile.  `mule' means
compile with Mule support.  `noerror' means no error-checking code. (Each
feature comes in a positive version and a negative version; the latter
prefixes "no" onto the positive version.)

`build [--no-mule-on-win] [--keep-going] [--filtered-output-file FILE]
  [--full-output-file FILE] WORKSPACE [scratch|rebuild] [all|CONFIGURATION

  Build (from scratch) or rebuild (after error) a workspace according to
  specified configurations.

  This is the main entry point for rebuilding a workspace.

  CONFIGURATION is a number or number-like constant, see below.  If
  `scratch' is given, the workspace will be reconfigured and rebuild
  from scratch; otherwise, compilation will continue from wherever it
  was before.  The output is filtered of all "normal" messages except
  for occasional status messages (see `runcc' for how this works and
  how the change what's filtered), so that only error messages and
  other unusual output appears.  Both the full and filtered output
  are saved into files -- per-build output files that are called (by
  default) `makeout-full.txt' and `makeout-filtered.txt' in the
  top-level directory of the build tree (i.e. the parallel directory
  structure containing the build files, not the source tree), and
  combined output files called (by default) `WORKSPACE-filtered.txt'
  and `WORKSPACE-full.txt' in the parent directory of all build
  trees. (The combined and per-build files will differ when more than
  one build occurs with a single invocation of this script, e.g. when
  `all' is given as the configuration.)
  All configuration information is contained in `config-inc'.
  --no-mule-on-win indicates that in this workspace, Mule support doesn't
  work on MS Windows. (Pre 21.5.)
  --keep-going specifies the -k flag on make, so that errors do not
  stop the build. #### Need to generalize, allow for any flags to be
  passed to the make command line.
  --filtered-output-file and --full-output-file let you override the
  locations of the combined output files.

  Include file specifying all configuration information.  You need to
  generate this; check out config-inc.samp.

  Sample version of include file specifying all configuration information.

  Used by `build': Run a command that compiles XEmacs, but optionally filter
  out all "normal" output so that only the warnings and such remain.

  Converts the features into configure arguments and arguments to other

  Some older and simpler alternatives to `build' when building.  May or may
  not work perfectly currently.  Need to look into, maybe delete.