Index: trunk/Ohana/src/opihi/dvo/avextract.c
===================================================================
--- trunk/Ohana/src/opihi/dvo/avextract.c	(revision 12332)
+++ trunk/Ohana/src/opihi/dvo/avextract.c	(revision 13479)
@@ -3,12 +3,17 @@
 int avextract (int argc, char **argv) {
   
-  int i, j, m, N, NPTS, param;
+  int i, j, n, m, Npts, NPTS, last, Nfields, Nreturn, Ncstack, Nstack;
   int Nsecfilt, mode;
   char *RegionName, *RegionList, *p;
+  char **cstack;
+  float *values;
 
   Catalog catalog;
   SkyList *skylist;
   PhotCode *code;
-  Vector *vec;
+  Vector **vec;
+
+  dbField *fields;
+  dbStack *stack;
 
   /* defaults */
@@ -24,31 +29,36 @@
   Nsecfilt = GetPhotcodeNsecfilt ();
 
-  /* 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 = GetAverageParam (argv[1]);
-  if (param == AVE_ZERO) {
-    if (!GetPhotcodeInfo (argv[1], &code, &mode)) {
-      GetAverageParamHelp ();
-      goto escape;
-    }
-    param = AVE_MAG;
-    for (p = argv[1]; *p != 0; p++) { 
-      if (*p == '.') *p = ':';
-    }
-  } 
-  if (!TestPhotSelections (&code, &mode, param)) 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_AVERAGE, &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_AVERAGE, &fields, &Nfields);
+  // XXX handle errors
 
   /* load region corresponding to selection above */
   if ((skylist = SelectRegions (RegionName, RegionList)) == NULL) goto escape;
 
-  /* create storage vector */
-  N = 0;
+  /* create output storage vectors */
+  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
@@ -68,12 +78,30 @@
     for (j = 0; j < catalog.Naverage; j++) {
       m = catalog.average[j].offset;
-      vec[0].elements[N] = ExtractAverages (code, mode, &catalog.average[j], &catalog.secfilt[j*Nsecfilt], &catalog.measure[m], param);
-      N++;
-      CHECK_REALLOCATE (vec[0].elements, float, NPTS, N, 2000);
+      // extract the relevant values
+      // XXX for measure values, this could be optimized for one loop over measures...
+      for (n = 0; n < Nfields; n++) {
+	values[n] = dbExtractAverages (&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);
+	}
+      }
     }
     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 
 
   SkyListFree (skylist, ((RegionName != NULL) || (RegionList != NULL)));
