Index: trunk/Ohana/src/opihi/dvo/mextract.c
===================================================================
--- trunk/Ohana/src/opihi/dvo/mextract.c	(revision 12332)
+++ trunk/Ohana/src/opihi/dvo/mextract.c	(revision 13479)
@@ -3,13 +3,18 @@
 int mextract (int argc, char **argv) {
   
-  int i, j, k, m, N, N1, NPTS;
+  int i, j, k, m, n, N, N1, Npts, NPTS, last, Nfields, Nreturn, Ncstack, Nstack;
   int param, mode, Nsecfilt;
   char *RegionName, *RegionList, *p;
   double *M1;
+  char **cstack;
+  float *values;
 
-  PhotCode *code;
   Catalog catalog;
   SkyList *skylist;
-  Vector *vec;
+  PhotCode *code;
+  Vector **vec;
+
+  dbField *fields;
+  dbStack *stack;
 
   /* defaults */
@@ -24,35 +29,47 @@
   if (!InitPhotcodes ()) goto escape;
   Nsecfilt = GetPhotcodeNsecfilt ();
+  
+  // init locally static variables (time refs)
+  dbExtractMeasuresInit();
 
-  /* interpret command-line options */
-  SetSelectionParam (0);
+  // remove skyregion options
+  // XXX this needs to explicitly handle -qregion and -skyregion
   if (!SetRegionSelection (&argc, argv, &RegionName, &RegionList)) goto escape;
-  if (!SetPhotSelections (&argc, argv, 1)) goto usage;
 
-  /* interpret required command-line arguments: mextract (value) */
-  if (argc != 2) goto usage;
-  param = GetMeasureParam (argv[1]);
-  if (param == MEAS_ZERO) {
-    if (!GetPhotcodeInfo (argv[1], &code, &mode)) {
-      GetMeasureParam ("help");
-      goto escape;
-    }
-    param = MEAS_MAG;
-    for (p = argv[1]; *p != 0; p++) { 
-      if (*p == '.') *p = ':';
-    }
-  }
-  if (!TestPhotSelections (&code, &mode, MEAS_ZERO)) goto escape;
+  // command-line is of the form: avextract field,field, field [where (field op value)...]
+
+  // parse the fields to be extracted and returned
+  fields = dbCmdlineFields (argc, argv, DVO_TABLE_MEASURE, &last, &Nfields);
+  if (fields == NULL) return (FALSE);
+
+  // parse the remainder of the line as a boolean math expression
+  cstack = isolate_elements (argc-last, &argv[last], &Ncstack);
+  
+  // construct the db Boolean math stack (frees cstack)
+  stack = dbRPN (Ncstack, cstack, &Nstack);
+
+  Nreturn = Nfields; 
+  dbCheckStack (stack, Nstack, DVO_TABLE_MEASURE, &fields, &Nfields);
+  // XXX handle errors
 
   /* load region corresponding to selection above */
   if ((skylist = SelectRegions (RegionName, RegionList)) == NULL) goto escape;
-  if (!SetImageSelection (param, ((RegionName == NULL) && (RegionList == NULL)))) goto escape;
+
+  // XXX is this still needed?
+  // if (!SetImageSelection (param, ((RegionName == NULL) && (RegionList == NULL)))) goto escape;
 
   /* create storage vector */
-  N = 0;
+  ALLOCATE (values, float, Nfields);
+  ALLOCATE (vec, Vector *, Nreturn);
+  for (i = 0; i < Nreturn; i++) {
+    if ((vec[i] = SelectVector (fields[i].name, ANYVECTOR, TRUE)) == NULL) goto escape;
+  }
+
+  Npts = 0;
   NPTS = 1;
-  if ((vec = SelectVector (argv[1], ANYVECTOR, TRUE)) == NULL) goto escape;
 
+  // XXX need to add interrupt test to this loop
   for (i = 0; i < skylist[0].Nregions; i++) {
+    /* lock, load, unlock catalog */
     catalog.filename = skylist[0].filename[i];
     catalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_SECF;
@@ -69,18 +86,34 @@
 
     for (j = 0; j < catalog.Naverage; j++) {
-      M1 = NULL;
       m = catalog.average[j].offset;
-      M1 = ExtractMeasures (code, mode, &catalog.average[j], &catalog.secfilt[j*Nsecfilt], &catalog.measure[m], &N1, param);
-      for (k = 0; k < N1; k++) {
-	vec[0].elements[N] = M1[k];
-	N++;
-	CHECK_REALLOCATE (vec[0].elements, float, NPTS, N, 2000);
+      for (k = 0; k < catalog.average[j].Nm; k++, m++) {
+
+	// extract the relevant values for this measurement
+	for (n = 0; n < Nfields; n++) {
+	  values[n] = dbExtractMeasures (&catalog.average[j], &catalog.secfilt[j*Nsecfilt], &catalog.measure[m], &fields[n]);
+	}
+	
+	// test the conditional statement
+	if (!dbBooleanCond (stack, Nstack, values)) continue;
+	for (n = 0; n < Nreturn; n++) {
+	  vec[n][0].elements[Npts] = values[n];
+	}
+	Npts++;
+	if (Npts >= NPTS) {
+	  NPTS += 2000;
+	  for (n = 0; n < Nreturn; n++) {
+	    REALLOCATE (vec[n][0].elements, float, NPTS);
+	  }
+	}
       }
-      if (M1 != NULL) free (M1);
     }
     dvo_catalog_free (&catalog);
   }
-  vec[0].Nelements = N;
-  REALLOCATE (vec[0].elements, float, MAX(1,N));
+  for (n = 0; n < Nreturn; n++) {
+    vec[n][0].Nelements = Npts;
+    REALLOCATE (vec[n][0].elements, float, MAX(1,Npts));
+  }
+
+  // XXX free fields and stack 
 
   FreeImageSelection ();
