Index: /trunk/pstest/Makefile
===================================================================
--- /trunk/pstest/Makefile	(revision 5078)
+++ /trunk/pstest/Makefile	(revision 5078)
@@ -0,0 +1,65 @@
+default: pstest
+help:
+	@echo "USAGE: make pstest"
+
+CC      =       gcc
+SRC     =       src
+BIN     =       bin
+
+DESTBIN =       $(HOME)/src/bin/$(ARCH)
+
+LPSLIB  :=      $(shell pslib-config --libs)
+IPSLIB  :=      $(shell pslib-config --cflags)
+
+INCS	= 	$(IPSLIB)
+LIBS	= 	$(LPSLIB)
+CFLAGS	=	$(INCS) -std=c99 -Wall -Werror -g
+LFLAGS	=	$(LIBS) 
+
+PSTEST = \
+$(SRC)/pstest.$(ARCH).o            \
+$(SRC)/psLibUtils.$(ARCH).o        \
+$(SRC)/pstArguments.$(ARCH).o
+
+pstest: $(BIN)/pstest.$(ARCH)
+$(BIN)/pstest.$(ARCH) : $(PSTEST)
+$(PSTEST): $(SRC)/pstest.h
+
+INSTALL = pstest
+
+# dependancy rules for binary code #########################
+.PRECIOUS: %.$(ARCH).o
+.PRECIOUS: $(BIN)/%.$(ARCH)
+
+%.$(ARCH).o : %.c
+	$(CC) $(CFLAGS) -c $< -o $@
+
+$(BIN)/%.$(ARCH) : $(SRC)/%.$(ARCH).o
+	@if [ ! -d $(BIN) ]; then mkdir -p $(BIN); fi
+	$(CC) $^ -o $@ $(LFLAGS)
+	@echo "done with $@"
+
+$(DESTBIN)/%: $(BIN)/%.$(ARCH)
+	@if [ ! -d $(DESTBIN) ]; then mkdir -p $(DESTBIN); fi
+	rm -f $(DESTBIN)/$*
+	cp $(BIN)/$*.$(ARCH) $(DESTBIN)/$*
+
+$(INSTALL): % : $(BIN)/%.$(ARCH)
+
+%.clean :
+	rm -f $(BIN)/$*.$(ARCH)
+	rm -f $(SRC)/*.$(ARCH).o
+
+%.install:
+	make $(DESTBIN)/$*
+
+# utilities #################################################
+
+install:
+	for i in $(INSTALL); do make $$i.install; done
+
+clean:	
+	rm -f $(BIN)/*.$(ARCH)
+	rm -f `find . -name "*.o"`
+	rm -f `find . -name "*~"`
+	rm -f `find . -name "#*"`
Index: /trunk/pstest/src/psLibUtils.c
===================================================================
--- /trunk/pstest/src/psLibUtils.c	(revision 5078)
+++ /trunk/pstest/src/psLibUtils.c	(revision 5078)
@@ -0,0 +1,148 @@
+# include <strings.h>  // for strncasecmp
+# include <pslib.h>
+# include "psLibUtils.h"
+
+// XXX EAM : this is NOT included in the C99 headers ??
+FILE *fdopen(int fildes, const char *mode);
+
+// XXX EAM : these utility functions should be added back into PSLib
+
+static psHash *timers = NULL;
+
+bool psTimerClear (char *name) {
+
+  bool status;
+
+  if (name == NULL) return false;
+
+  status = psHashRemove (timers, name);
+  return (status);
+}
+
+void psTimerFree () {
+
+  psFree (timers);
+  p_psTimeFinalize();
+  return;
+}
+
+// start/restart a named timer
+bool psTimerStart (char *name) {
+
+    psTime *start;
+
+    if (timers == NULL) timers = psHashAlloc (16);
+
+    start = psTimeGetNow (PS_TIME_UTC);
+    psHashAdd (timers, name, start);
+    psFree (start); 
+    return (TRUE);
+}
+
+// get current elapsed time on named timer
+psF64 psTimerMark (char *name) {
+
+    psTime *start;
+    psTime *mark;
+    psF64   delta;
+
+    if (timers == NULL) return (0);
+
+    start = psHashLookup (timers, name);
+    if (start == NULL) return (0);
+
+    mark = psTimeGetNow (PS_TIME_UTC);
+    delta = psTimeDelta (mark, start);
+    psFree (mark);
+    // psFree (start); -- XXX is psHashLookup not psMemCopying?
+
+    return (delta);
+}
+
+// find the location of the specified argument
+int psArgumentGet (int argc, char **argv, char *arg) {
+
+    int i;
+
+    for (i = 0; i < argc; i++) {
+	if (!strcmp(argv[i], arg))
+	    return (i);
+    }
+  
+    return ((int)NULL);
+}
+
+// remove the specified argument (by location)
+int psArgumentRemove (int N, int *argc, char **argv) {
+
+    int i;
+
+    if ((N != (int)NULL) && (N != 0)) {
+	(*argc)--;
+	for (i = N; i < *argc; i++) {
+	    argv[i] = argv[i+1];
+	}
+    }
+
+    return (N);
+}
+
+// we have log levels 1 (Error), 2 (Warning), 3 (Info), 4 (Details), 5 (Minutiae)
+// 2 = default, -v = 3, -vv = 4, -vvv = 5 
+psS32 psLogArguments (int *argc, char **argv) {
+  
+    int N, level;
+
+    // default log level is 2
+    level = 2;
+
+    // set in order, so that -vvv overrides -vv overrides -v
+    if ((N = psArgumentGet (*argc, argv, "-v"))) {
+	psArgumentRemove (N, argc, argv);
+	level = 3;
+    }
+    if ((N = psArgumentGet (*argc, argv, "-vv"))) {
+	psArgumentRemove (N, argc, argv);
+	level = 4;
+    }
+    if ((N = psArgumentGet (*argc, argv, "-vvv"))) {
+	psArgumentRemove (N, argc, argv);
+	level = 5;
+    }
+
+    if ((N = psArgumentGet (*argc, argv, "-logfmt"))) {
+	if (*argc < N + 2) {
+	    psAbort ("psLogArguments", "USAGE: -logfmt (format)");
+	}
+	psArgumentRemove (N, argc, argv);
+	psLogSetFormat (argv[N]); // XXX EAM : this function should return an error if the log format is invalid
+	psArgumentRemove (N, argc, argv);
+    }
+
+    // set the level, return the level
+    psLogSetLevel (level);
+    return (level);
+}
+
+// set trace levels by facility
+psS32 psTraceArguments (int *argc, char **argv) {
+  
+    int N;
+
+    // argument format is: -trace (facil) (level) 
+    while ((N = psArgumentGet (*argc, argv, "-trace"))) {
+	if (*argc < N + 3) {
+	    psAbort ("psTraceArguments", "USAGE: -trace (facility) (level)");
+	}
+	psArgumentRemove (N, argc, argv);
+	psTraceSetLevel (argv[N], atoi(argv[N+1]));
+	psArgumentRemove (N, argc, argv);
+	psArgumentRemove (N, argc, argv);
+    }
+    if ((N = psArgumentGet (*argc, argv, "-trace-levels"))) {
+	psTracePrintLevels ();
+	exit (2);
+    }
+    return (TRUE);
+}
+
Index: /trunk/pstest/src/psLibUtils.h
===================================================================
--- /trunk/pstest/src/psLibUtils.h	(revision 5078)
+++ /trunk/pstest/src/psLibUtils.h	(revision 5078)
@@ -0,0 +1,16 @@
+# ifndef PS_LIB_UTILS
+# define PS_LIB_UTILS
+
+# define psMemCopy(A)(psMemIncrRefCounter((A)))
+
+// psLib extra utilities
+bool 	     psTimerStart (char *name);   // added to SDRS
+bool 	     psTimerClear (char *name);   // added to SDRS 
+psF64 	     psTimerMark (char *name);    // added to SDRS
+void 	     psTimerFree ();              // added to SDRS (as psTimerStop)
+psS32 	     psLogArguments (int *argc, char **argv);   // added to SDRS (part of psArgumentVerbosity)
+psS32 	     psTraceArguments (int *argc, char **argv); // added to SDRS (part of psArgumentVerbosity)
+int	     psArgumentGet (int argc, char **argv, char *arg); // added to SDRS
+int	     psArgumentRemove (int N, int *argc, char **argv); // added to SDRS
+
+# endif
Index: /trunk/pstest/src/pstArguments.c
===================================================================
--- /trunk/pstest/src/pstArguments.c	(revision 5078)
+++ /trunk/pstest/src/pstArguments.c	(revision 5078)
@@ -0,0 +1,75 @@
+# include "pstest.h"
+
+static void usage (void) ;
+
+psMetadata *pstArguments (int *argc, char **argv) {
+
+  int N;
+  int mode = PS_META_STR | PS_META_REPLACE;
+
+  // basic pslib options
+  fprintf (stderr, "starting... %s\n", psLibVersion());
+  psLogSetFormat ("M");
+  psLogArguments (argc, argv);
+  psTraceArguments (argc, argv);
+
+  // optional mask image - add to config
+  char *mask = NULL;
+  if ((N = psArgumentGet (*argc, argv, "-mask"))) {
+    psArgumentRemove (N, argc, argv);
+    mask = psStringCopy (argv[N]);
+    psArgumentRemove (N, argc, argv);
+  }
+
+  // optional weight image - add to config
+  char *weight = NULL;
+  if ((N = psArgumentGet (*argc, argv, "-weight"))) {
+    psArgumentRemove (N, argc, argv);
+    weight = psStringCopy (argv[N]);
+    psArgumentRemove (N, argc, argv);
+  }
+
+  // optional output residual image - add to config
+  char *resid = NULL;
+  if ((N = psArgumentGet (*argc, argv, "-resid"))) {
+    psArgumentRemove (N, argc, argv);
+    resid = psStringCopy (argv[N]);
+    psArgumentRemove (N, argc, argv);
+  }
+
+  if (*argc != 4) usage ();
+
+  // setup config information
+  psMetadata *config = psMetadataAlloc ();
+
+  // load config file 
+  // psMetadataAdd (config, PS_LIST_HEAD, "PSF_MODEL", PS_META_MULTI, "folder for psf model entries", NULL);
+  // config = psMetadataConfigParse (config, &Nfail, argv[3], FALSE);
+  // fprintf (stderr, "loaded config...\n");
+
+  // identify input image & optional weight & mask images
+  // command-line entries override config-file entries
+  psMetadataAdd (config, PS_LIST_HEAD, "IMAGE",       mode, "", argv[1]);
+  psMetadataAdd (config, PS_LIST_HEAD, "OUTPUT_FILE", mode, "", argv[2]);
+
+  if (mask != NULL) {
+    psMetadataAdd (config, PS_LIST_HEAD, "MASK_IMAGE", mode, "", mask);
+  }
+  if (weight != NULL) {
+    psMetadataAdd (config, PS_LIST_HEAD, "WEIGHT_IMAGE", mode, "", weight);
+  }
+  if (resid != NULL) {
+    psMetadataAdd (config, PS_LIST_HEAD, "RESID_IMAGE", mode, "", resid);
+  }
+  return (config);
+}
+
+static void usage (void) {
+
+    fprintf (stderr, "USAGE: pstest (image) (output) (config)\n");
+    fprintf (stderr, "options: \n");
+    fprintf (stderr, "  -mask  (filename)\n");
+    fprintf (stderr, "  -weight (filename)\n");
+    fprintf (stderr, "  -resid (filename)\n");
+    exit (2);
+}
Index: /trunk/pstest/src/pstest.c
===================================================================
--- /trunk/pstest/src/pstest.c	(revision 5078)
+++ /trunk/pstest/src/pstest.c	(revision 5078)
@@ -0,0 +1,10 @@
+# include "pstest.h"
+
+int main (int argc, char **argv) {
+
+    psMetadata *config = NULL;
+
+    config = pstArguments (&argc, argv);
+
+    exit (0);
+}
Index: /trunk/pstest/src/pstest.h
===================================================================
--- /trunk/pstest/src/pstest.h	(revision 5078)
+++ /trunk/pstest/src/pstest.h	(revision 5078)
@@ -0,0 +1,7 @@
+# include <stdio.h>
+# include <strings.h>  // for strcasecmp
+# include <unistd.h>   // for unlink
+# include <pslib.h>
+# include "psLibUtils.h"
+
+psMetadata  *pstArguments (int *argc, char **argv);
