Index: trunk/ippTools/src/dettool.c
===================================================================
--- trunk/ippTools/src/dettool.c	(revision 11047)
+++ trunk/ippTools/src/dettool.c	(revision 11088)
@@ -167,4 +167,5 @@
         " WHERE"
         "    detInputExp.exp_tag IS NULL"
+        "    AND rawExp.obstype != 'object'"
     );
 
@@ -188,5 +189,4 @@
     }
     if (!psArrayLength(output)) {
-        // XXX check psError here
         psError(PS_ERR_UNKNOWN, false, "no pending rawExp rows found");
         psFree(output);
@@ -1717,4 +1717,11 @@
     }
 
+    // default values
+    psS8 code = psMetadataLookupS8(&status, config->args, "-code");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");
+        return false;
+    }
+
     psArray *rawImfiles = rawImfileSelectRowObjects(config->dbh, where, 0);
     psFree(where);
@@ -1723,4 +1730,5 @@
         return false;
     }
+
 
     // create a new detProcessedImfile object
@@ -1735,5 +1743,6 @@
         bg_mean_stdev,
         b1_uri,
-        b2_uri
+        b2_uri,
+        code
     );
     psFree(rawImfiles);
@@ -1950,4 +1959,11 @@
     }
 
+    // default values
+    psS8 code = psMetadataLookupS8(&status, config->args, "-code");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");
+        return false;
+    }
+
     psString query = psStringCopy(
         " SELECT DISTINCT"
@@ -2015,5 +2031,6 @@
         bg_mean_stdev,
         b1_uri,
-        b2_uri
+        b2_uri,
+        code
     );
 
@@ -2033,4 +2050,17 @@
 {
     PS_ASSERT_PTR_NON_NULL(config, false);
+
+    bool status = false;
+    psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");
+        return false;
+    }
+
+    bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted");
+        return false;
+    }
 
     psString query = psStringCopy("SELECT * FROM detProcessedExp");
@@ -2040,4 +2070,19 @@
         psStringAppend(&query, " %s", whereClause);
         psFree(whereClause);
+    }
+
+    if (faulted) {
+        // list only faulted rows
+        psStringAppend(&query, " %s", "AND detProcessedExp.fault != 0");
+    } else {
+        // don't list faulted rows
+        psStringAppend(&query, " %s", "AND detProcessedExp.fault = 0");
+    }
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
     }
 
@@ -2206,4 +2251,17 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
 
+    bool status = false;
+    psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");
+        return false;
+    }
+
+    bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted");
+        return false;
+    }
+
     psString query = psStringCopy(
         " SELECT DISTINCT"
@@ -2248,4 +2306,19 @@
     psFree(query);
 
+    if (faulted) {
+        // list only faulted rows
+        psStringAppend(&query, " %s", "AND detProcessedImfile.fault != 0");
+    } else {
+        // don't list faulted rows
+        psStringAppend(&query, " %s", "AND detProcessedImfile.fault = 0");
+    }
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
     psArray *output = p_psDBFetchResult(config->dbh);
     if (!output) {
@@ -2352,8 +2425,14 @@
     }
 
-    // iteration has a default value
+    // default values
     psS32 iteration = psMetadataLookupS32(&status, config->args, "-iteration");
     if (!status) {
         psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -iteration");
+        return false;
+    }
+
+    psS8 code = psMetadataLookupS8(&status, config->args, "-code");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");
         return false;
     }
@@ -2400,5 +2479,6 @@
             bg,
             bg_stdev,
-            bg_mean_stdev
+            bg_mean_stdev,
+            code
         );
 
@@ -2418,4 +2498,17 @@
 {
     PS_ASSERT_PTR_NON_NULL(config, false);
+
+    bool status = false;
+    psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");
+        return false;
+    }
+
+    bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted");
+        return false;
+    }
 
     // select detStackedImfile.*
@@ -2438,4 +2531,19 @@
         psStringAppend(&query, " AND %s", whereClause);
         psFree(whereClause);
+    }
+
+    if (faulted) {
+        // list only faulted rows
+        psStringAppend(&query, " %s", "AND detStackedImfile.fault != 0");
+    } else {
+        // don't list faulted rows
+        psStringAppend(&query, " %s", "AND detStackedImfile.fault = 0");
+    }
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
     }
 
@@ -2708,9 +2816,17 @@
     }
 
+    // default values
+    psS8 code = psMetadataLookupS8(&status, config->args, "-code");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");
+        return false;
+    }
+
     return detNormalizedStatImfileRowAlloc(
         stackedImfile->det_id,
         stackedImfile->iteration,
         stackedImfile->class_id,
-        norm
+        norm,
+        code
     );
 }
@@ -3104,5 +3220,5 @@
     }
 #endif
-
+    
     // treat limit == 0 as "no limit"
     if (limit) {
@@ -3210,4 +3326,11 @@
         psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -iteration");        return false;
     }
+
+    psS8 code = psMetadataLookupS8(&status, config->args, "-code");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");
+        return false;
+    }
+
     // optional
     psString b1_uri = psMetadataLookupStr(&status, config->args, "-b1_uri");
@@ -3290,5 +3413,6 @@
         bg_mean_stdev,
         b1_uri,
-        b2_uri
+        b2_uri,
+        code
     );
 
@@ -3308,4 +3432,17 @@
 {
     PS_ASSERT_PTR_NON_NULL(config, false);
+
+    bool status = false;
+    psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");
+        return false;
+    }
+
+    bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted");
+        return false;
+    }
 
     psString query = psStringCopy(
@@ -3326,4 +3463,19 @@
     }
 
+    if (faulted) {
+        // list only faulted rows
+        psStringAppend(&query, " %s", "AND detNormalizedExp.fault != 0");
+    } else {
+        // don't list faulted rows
+        psStringAppend(&query, " %s", "AND detNormalizedExp.fault = 0");
+    }
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
     if (!p_psDBRunQuery(config->dbh, query)) {
         psError(PS_ERR_UNKNOWN, false, "database error");
@@ -3418,4 +3570,11 @@
     if (!status) {
         psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -b2_uri");
+        return false;
+    }
+
+    // default values
+    psS8 code = psMetadataLookupS8(&status, config->args, "-code");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");
         return false;
     }
@@ -3430,5 +3589,6 @@
         bg_mean_stdev,
         b1_uri,
-        b2_uri
+        b2_uri,
+        code
     );
 }
@@ -3581,4 +3741,17 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
 
+    bool status = false;
+    psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");
+        return false;
+    }
+
+    bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted");
+        return false;
+    }
+
     psString query = psStringCopy(
         "SELECT"
@@ -3602,4 +3775,19 @@
         psStringAppend(&query, " AND %s", whereClause);
         psFree(whereClause);
+    }
+
+    if (faulted) {
+        // list only faulted rows
+        psStringAppend(&query, " %s", "AND detNormalizedImfile.fault != 0");
+    } else {
+        // don't list faulted rows
+        psStringAppend(&query, " %s", "AND detNormalizedImfile.fault = 0");
+    }
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
     }
 
@@ -3685,5 +3873,6 @@
         "   0.0 as bg_mean_stdev,\n"
         "   'NULL' as b1_uri,\n"
-        "   'NULL' as b2_uri\n"
+        "   'NULL' as b2_uri,\n"
+        "    0 as fault\n"
         " FROM detRun\n"
         " JOIN detInputExp\n"
@@ -3915,4 +4104,11 @@
     }
 
+    // default values
+    psS8 code = psMetadataLookupS8(&status, config->args, "-code");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");
+        return false;
+    }
+
     // create a new detResidImfileRow and insert it
     return detResidImfileRowAlloc(
@@ -3927,5 +4123,6 @@
             bg_mean_stdev,
             b1_uri,
-            b2_uri
+            b2_uri,
+            code
         );
 }
@@ -3934,4 +4131,17 @@
 {
     PS_ASSERT_PTR_NON_NULL(config, false);
+
+    bool status = false;
+    psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");
+        return false;
+    }
+
+    bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted");
+        return false;
+    }
 
     // select detResidImfile.*
@@ -3955,4 +4165,19 @@
         psStringAppend(&query, " AND %s", whereClause);
         psFree(whereClause);
+    }
+
+    if (faulted) {
+        // list only faulted rows
+        psStringAppend(&query, " %s", "AND p2ProcessedImfile.fault != 0");
+    } else {
+        // don't list faulted rows
+        psStringAppend(&query, " %s", "AND p2ProcessedImfile.fault = 0");
+    }
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
     }
 
@@ -4409,4 +4634,10 @@
         return false;
     }
+    // default values
+    psS8 code = psMetadataLookupS8(&status, config->args, "-code");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");
+        return false;
+    }
 
     // create a new detResidImfileRow and insert it
@@ -4421,5 +4652,6 @@
             b1_uri,
             b2_uri,
-            !reject
+            !reject,
+            code
         );
 }
@@ -4428,4 +4660,17 @@
 {
     PS_ASSERT_PTR_NON_NULL(config, false);
+
+    bool status = false;
+    psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");
+        return false;
+    }
+
+    bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted");
+        return false;
+    }
 
     psString query = psStringCopy(
@@ -4447,4 +4692,19 @@
         psStringAppend(&query, " AND %s", whereClause);
         psFree(whereClause);
+    }
+
+    if (faulted) {
+        // list only faulted rows
+        psStringAppend(&query, " %s", "AND detResidExp.fault != 0");
+    } else {
+        // don't list faulted rows
+        psStringAppend(&query, " %s", "AND detResidExp.fault = 0");
+    }
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
     }
 
@@ -4972,4 +5232,10 @@
         return NULL;
     }
+    // default values
+    psS8 code = psMetadataLookupS8(&status, config->args, "-code");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");
+        return false;
+    }
 
     return detRunSummaryRowAlloc(
@@ -4979,5 +5245,6 @@
             bg_stdev,
             bg_mean_stdev,
-            accept
+            accept,
+            code
         );
 }
@@ -4986,4 +5253,17 @@
 {
     PS_ASSERT_PTR_NON_NULL(config, false);
+
+    bool status = false;
+    psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");
+        return false;
+    }
+
+    bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted");
+        return false;
+    }
 
     psString query = psStringCopy(
@@ -5003,4 +5283,19 @@
         psStringAppend(&query, " AND %s", whereClause);
         psFree(whereClause);
+    }
+
+    if (faulted) {
+        // list only faulted rows
+        psStringAppend(&query, " %s", "AND p2ProcessedImfile.fault != 0");
+    } else {
+        // don't list faulted rows
+        psStringAppend(&query, " %s", "AND p2ProcessedImfile.fault = 0");
+    }
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
     }
 
@@ -5564,5 +5859,6 @@
             bg_stdev,
             bg_mean_stdev,
-            true // accept
+            true,   // accept
+            0       // fault code
     )) {
         psError(PS_ERR_UNKNOWN, false, "database error");
@@ -5662,5 +5958,6 @@
             bg_mean_stdev,
             b1_uri,
-            b2_uri
+            b2_uri,
+            0       // fault code
     )) {
         psError(PS_ERR_UNKNOWN, false, "database error");
