Index: trunk/Ohana/src/opihi/cmd.data/queuesubstr.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/queuesubstr.c	(revision 17575)
+++ trunk/Ohana/src/opihi/cmd.data/queuesubstr.c	(revision 17575)
@@ -0,0 +1,42 @@
+# include "data.h"
+
+int queuesubstr (int argc, char **argv) {
+  
+  int i;
+  char *p, *q;
+  char *match, *replace;
+  Queue *queue;
+
+  if (argc != 4) {
+    gprint (GP_ERR, "USAGE: queueprint (queue) (match) (replace)\n");
+    return (FALSE);
+  }
+
+  match = argv[2];
+  replace = argv[3];
+
+  assert (match);
+  assert (replace);
+
+  queue = FindQueue (argv[1]);
+  if (queue == NULL) {
+    gprint (GP_ERR, "ERROR: queue %s not found\n", argv[1]);
+    return (FALSE);
+  }
+
+  for (i = 0; i < queue[0].Nlines; i++) {
+
+    p = queue[0].lines[i];
+    if (p == NULL) continue;
+    
+    while (strstr (p, match) != NULL) {
+      q = strsubs (p, match, replace);
+      free (p);
+      p = q;
+    }
+    queue[0].lines[i] = p;
+  }
+
+  return (TRUE);
+}
+
Index: trunk/ippScripts/scripts/ipp_cleanup.pl
===================================================================
--- trunk/ippScripts/scripts/ipp_cleanup.pl	(revision 17575)
+++ trunk/ippScripts/scripts/ipp_cleanup.pl	(revision 17575)
@@ -0,0 +1,92 @@
+#!/usr/bin/env perl
+
+# this script is used to cleanup the files from the different ipp
+# stages.  It can be called with one of two cleanup modes: clean and
+# purge.  the former removes temporary data files, leaving behind
+# enough information for the results to be rebuilt.  The latter
+# removes all but basic logging data.
+
+use warnings;
+use strict;
+
+use IPC::Cmd 0.36 qw( can_run run );
+use File::Spec;
+use PS::IPP::Config;
+use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
+use Pod::Usage qw( pod2usage );
+
+my $ipprc = PS::IPP::Config->new(); # this is used for PATH, NEB filename conversions
+
+# Parse the command-line arguments
+my ($camera, $outroot, $dbname, $mode, $no_op, $help);
+GetOptions('camera|i=s'     => \$camera,    # user-supplied camera name
+	   'outroot|o=s'    => \$outroot,   # basename for files
+	   'dbname|d=s'     => \$dbname,    # Database name
+	   'mode|m=s'       => \$mode,      # cleanup mode (clean / purge)
+	   'no-op'          => \$no_op,     # pretend but don't actually inject
+	   'help'           => \$help       # give help listing
+	   ) or pod2usage( 2 );
+
+pod2usage( -msg => "remove temporary / all data files for an IPP analysis stage", 
+	   -exitval => 2) if 
+    defined $help;
+
+pod2usage( -msg => "Usage: $0 --camera (name) --outroot (path) --stage (stage) --mode (mode) [--dbname dbname] [--no-op] [--help]", 
+	   -exitval => 2 ) if 
+    scalar @ARGV == 0;
+
+pod2usage( -msg => "Required options:--camera (name) --outroot (path) --stage (stage) --mode (mode)",
+	   -exitval => 3) unless 
+    defined $camera and
+    defined $outroot and
+    defined $stage and
+    defined $mode;
+
+# $mode must be one of "clean" or "purge"
+unless (($mode eq "clean") || ($mode eq "purge")) {
+    die "invalid cleanup mode $mode\n";    
+}
+
+$ipprc->define_camera($camera);
+
+my $found = 0;
+my @files = ();
+
+# XXX : should ipp_cleanup.pl determine the class ID values, or should it require them as input?
+
+if ($stage eq "chip") {
+    # delete the temporary image datafiles
+    addFilename (\@files, "PPIMAGE.OUTPUT", $outroot, $class_id);
+    addFilename (\@files, "PPIMAGE.OUTPUT.MASK", $outroot, $class_id);
+    addFilename (\@files, "PPIMAGE.OUTPUT.WEIGHT", $outroot, $class_id);
+    addFilename (\@files, "PPIMAGE.CHIP", $outroot, $class_id);
+    addFilename (\@files, "PPIMAGE.CHIP.MASK", $outroot, $class_id);
+    addFilename (\@files, "PPIMAGE.CHIP.WEIGHT", $outroot, $class_id);
+    if ($mode eq "purge") {
+	# additional files to remove for 'purge' mode
+	addFilename (\@files, "PPIMAGE.OUTPUT.FPA1", $outroot, $class_id);
+	addFilename (\@files, "PPIMAGE.OUTPUT.FPA2", $outroot, $class_id);
+	addFilename (\@files, "PPIMAGE.BIN1", $outroot, $class_id);
+	addFilename (\@files, "PPIMAGE.BIN2", $outroot, $class_id);
+	addFilename (\@files, "PPIMAGE.JPEG1", $outroot, $class_id);
+	addFilename (\@files, "PPIMAGE.JPEG", $outroot, $class_id);
+	addFilename (\@files, "PPIMAGE.STATS", $outroot, $class_id);
+    }
+}
+
+exit 0;
+
+sub addFilename 
+{
+    my $files    = shift; # reference to a list of files to unlink
+    my $filerule = shift; # filerule to add
+    my $outroot  = shift; # base filename
+    my $class_id = shift; # class_id, if needed
+
+    my $file = $ipprc->filename($filerule, $outroot, $class_id);
+
+    push @$files, $file;
+    return 1;
+}
+
+__END__
Index: trunk/ippTasks/simtest.pro
===================================================================
--- trunk/ippTasks/simtest.pro	(revision 17575)
+++ trunk/ippTasks/simtest.pro	(revision 17575)
@@ -0,0 +1,38 @@
+## simtest.pro : automatic full-suite simulated IPP test : -*- sh -*-
+
+macro simtest
+  if ($0 != 4)
+    echo "USAGE: simtest (dbname) (hostname) (init)"
+    echo " if (init) == 1, recreate and inject the images"
+    break
+  end
+
+  $dbname = $1
+  $hostname = $2
+ 
+  if ($3 == 1)
+    # XXX this will fail and exit the script if the db does not exist or is old...
+    exec pxadmin -delete -dbname $dbname
+
+    # XXX this gives warnings if the db exists...
+    exec pxadmin -create -dbname $dbname
+
+    # the labels "wait" and "proc" are special names used in automate.pro
+    exec ppSimSequence basic.simtest.config basic.simtest.mkimages basic.simtest.inject -path raw -workdir work -dbname $dbname -label wait
+    exec source basic.simtest.mkimages
+    exec source basic.simtest.inject
+  end
+
+  module pantasks.pro
+  module automate.pro
+
+  module.tasks
+
+  controller host add $hostname
+  add.database $dbname
+
+  load.automate simtest.auto $dbname
+  run
+end
+
+# XXX add a test function to pxadmin to check for db existence
