Index: /branches/end_stage/ippTools/src/pxtools.h
===================================================================
--- /branches/end_stage/ippTools/src/pxtools.h	(revision 16124)
+++ /branches/end_stage/ippTools/src/pxtools.h	(revision 16125)
@@ -80,71 +80,61 @@
 }
 
+#define PXOPT_LOOKUP_F(var, md, key, type, required, ret) \
+ps##type var; \
+{ \
+    bool status; \
+ \
+    var = psMetadataLookup##type(&status, md, key); \
+    if (!status) { \
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for %s", key); \
+        return ret; \
+    } \
+ \
+    if (required && isnan(var)) { \
+        psError(PS_ERR_UNKNOWN, true, "%s is required", key); \
+        return ret; \
+    } \
+}
+
 #define PXOPT_LOOKUP_F32(var, md, key, required, ret) \
-psF32 var; \
-{ \
-    bool status; \
- \
-    var = psMetadataLookupF32(&status, md, key); \
-    if (!status) { \
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for %s", key); \
-        return ret; \
-    } \
- \
-    if (required && isnan(var)) { \
-        psError(PS_ERR_UNKNOWN, true, "%s is required", key); \
-        return ret; \
-    } \
-}
+    PXOPT_LOOKUP_F(var, md, key, F64, required, ret)
 
 #define PXOPT_LOOKUP_F64(var, md, key, required, ret) \
-psF64 var; \
-{ \
-    bool status; \
- \
-    var = psMetadataLookupF64(&status, md, key); \
-    if (!status) { \
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for %s", key); \
-        return ret; \
-    } \
- \
-    if (required && isnan(var)) { \
-        psError(PS_ERR_UNKNOWN, true, "%s is required", key); \
-        return ret; \
-    } \
-}
+    PXOPT_LOOKUP_F(var, md, key, F64, required, ret)
+
+#define PXOPT_LOOKUP_PRIMITIVE(var, md, key, type, suffix, max, required, ret) \
+type var; \
+{ \
+    bool status; \
+ \
+    var = psMetadataLookup##suffix(&status, md, key); \
+    if (!status) { \
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for %s", key); \
+        return ret; \
+    } \
+ \
+    if (required && (var != max)) { \
+        psError(PS_ERR_UNKNOWN, true, "%s is required", key); \
+        return ret; \
+    } \
+}
+
+#define PXOPT_LOOKUP_S16(var, md, key, required, ret) \
+    PXOPT_LOOKUP_PRIMITIVE(var, md, key, psS16, S16, INT16_MAX, required, ret)
+
+#define PXOPT_LOOKUP_S32(var, md, key, required, ret) \
+    PXOPT_LOOKUP_PRIMITIVE(var, md, key, psS32, S32, INT32_MAX, required, ret)
+
+#define PXOPT_LOOKUP_S64(var, md, key, required, ret) \
+    PXOPT_LOOKUP_PRIMITIVE(var, md, key, psS64, S64, INT64_MAX, required, ret)
+
+#define PXOPT_LOOKUP_U16(var, md, key, required, ret) \
+    PXOPT_LOOKUP_PRIMITIVE(var, md, key, psU16, U16, UINT16_MAX, required, ret)
+
+#define PXOPT_LOOKUP_U32(var, md, key, required, ret) \
+    PXOPT_LOOKUP_PRIMITIVE(var, md, key, psU32, U32, UINT32_MAX, required, ret)
 
 #define PXOPT_LOOKUP_U64(var, md, key, required, ret) \
-psU64 var; \
-{ \
-    bool status; \
- \
-    var = psMetadataLookupU64(&status, md, key); \
-    if (!status) { \
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for %s", key); \
-        return ret; \
-    } \
- \
-    if (required && (var != UINT64_MAX)) { \
-        psError(PS_ERR_UNKNOWN, true, "%s is required", key); \
-        return ret; \
-    } \
-}
-
-#define PXOPT_LOOKUP_S16(var, md, key, required, ret) \
-psS16 var; \
-{ \
-    bool status; \
- \
-    var = psMetadataLookupS16(&status, md, key); \
-    if (!status) { \
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for %s", key); \
-        return ret; \
-    } \
- \
-    if (required && (var != INT16_MAX)) { \
-        psError(PS_ERR_UNKNOWN, true, "%s is required", key); \
-        return ret; \
-    } \
-}
+    PXOPT_LOOKUP_PRIMITIVE(var, md, key, psU64, U64, UINT64_MAX, required, ret)
 
 #define PXOPT_LOOKUP_TIME(var, md, key, required, ret) \
@@ -177,3 +167,54 @@
 }
 
+// XXX the PXOPT_COPY_* macros free 'to' on error
+
+#define PXOPT_COPY_PRIMITIVE(from, to, type, suffix, oldname, newname, comment) \
+{ \
+    bool status = false; \
+    type var = psMetadataLookup##suffix(&status, from, oldname); \
+    if (!status) { \
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for " oldname); \
+        return false; \
+    } \
+    if (var) { \
+        if (!psMetadataAdd##suffix(to, PS_LIST_TAIL, newname, PS_META_DUPLICATE_OK, comment, var)) { \
+            psError(PS_ERR_UNKNOWN, false, "failed to add item " newname); \
+            psFree(to); \
+            return false; \
+        } \
+    } \
+}
+
+#define PXOPT_COPY_V(from, to, type, suffix, oldname, newname, comment) \
+    PXOPT_COPY_PRIMITIVE(from, to, type*, suffix, oldname, newname, comment) \
+
+#define PXOPT_COPY_F(from, to, type, oldname, newname, comment) \
+{ \
+    bool status = false; \
+    ps##type var = psMetadataLookup##type(&status, from, oldname); \
+    if (!status) { \
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for " oldname); \
+        return false; \
+    } \
+    if (!isnan(var)) { \
+        if (!psMetadataAdd##type(to, PS_LIST_TAIL, newname, PS_META_DUPLICATE_OK, comment, var)) { \
+            psError(PS_ERR_UNKNOWN, false, "failed to add item " newname); \
+            psFree(to); \
+            return false; \
+        } \
+    } \
+}
+
+#define PXOPT_COPY_F32(from, to, oldname, newname, comment) \
+  PXOPT_COPY_F(from, to, F32, oldname, newname, comment)
+
+#define PXOPT_COPY_F64(from, to, oldname, newname, comment) \
+  PXOPT_COPY_F(from, to, F64, oldname, newname, comment)
+
+#define PXOPT_COPY_TIME(from, to, oldname, newname, comment) \
+  PXOPT_COPY_V(from, to, psTime, Time, oldname, newname, comment)
+
+#define PXOPT_COPY_STR(from, to, oldname, newname, comment) \
+  PXOPT_COPY_PRIMITIVE(from, to, psString, Str, oldname, newname, comment)
+
 #endif // PXTOOLS_H
