Index: /branches/eam_branches/ipp-20230313/Ohana/src/opihi/cmd.data/concat.c
===================================================================
--- /branches/eam_branches/ipp-20230313/Ohana/src/opihi/cmd.data/concat.c	(revision 42513)
+++ /branches/eam_branches/ipp-20230313/Ohana/src/opihi/cmd.data/concat.c	(revision 42514)
@@ -32,5 +32,25 @@
   if ((ivec = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);
   
-  // we have 4 cases: (ivec == flt or int) and (ovec == flt or int)
+  // if the output vector is empty, inherit the type of the input vector
+  if (!ovec->Nelements) { ResetVector (ovec, ivec->type, ovec->Nelements); }
+
+  // we have 3 input and 3 output types : INT, FLT, STR
+
+  // both are strings
+  if ((ovec[0].type == OPIHI_STR) && (ivec[0].type == OPIHI_STR)) {
+    REALLOCATE (ovec->elements.Str, char *, MAX(1, ovec->Nelements + ivec->Nelements));
+    for (j = ovec[0].Nelements, i = 0; i < ivec[0].Nelements; i++, j++) {
+      ovec[0].elements.Str[j] = strcreate(ivec[0].elements.Str[i]);
+    }
+    goto done;
+  }
+
+  // if only one is a string, raise an error
+  if ((ovec[0].type == OPIHI_STR) || (ivec[0].type == OPIHI_STR)) {
+    gprint (GP_ERR, "ERROR: cannot mix string and numerical vectors\n");
+    return FALSE;
+  }
+
+  // both vectors are floats
   if ((ovec[0].type == OPIHI_FLT) && (ivec[0].type == OPIHI_FLT)) {
     REALLOCATE (ovec[0].elements.Flt, opihi_flt, ovec[0].Nelements + ivec[0].Nelements);
@@ -38,5 +58,16 @@
       ovec[0].elements.Flt[j] = ivec[0].elements.Flt[i];
     }
+    goto done;
   }
+  // both vectors are ints
+  if ((ovec[0].type == OPIHI_INT) && (ivec[0].type == OPIHI_INT)) {
+    REALLOCATE (ovec[0].elements.Int, opihi_int, ovec[0].Nelements + ivec[0].Nelements);
+    for (j = ovec[0].Nelements, i = 0; i < ivec[0].Nelements; i++, j++) {
+      ovec[0].elements.Int[j] = ivec[0].elements.Int[i];
+    }
+    goto done;
+  }
+
+  // if output vector is a float and input is an int, cast the int values to the float
   if ((ovec[0].type == OPIHI_FLT) && (ivec[0].type == OPIHI_INT)) {
     REALLOCATE (ovec[0].elements.Flt, opihi_flt, ovec[0].Nelements + ivec[0].Nelements);
@@ -44,12 +75,8 @@
       ovec[0].elements.Flt[j] = ivec[0].elements.Int[i];
     }
-  }
-  if ((ovec[0].type == OPIHI_INT) && (ivec[0].type == OPIHI_INT)) {
-    REALLOCATE (ovec[0].elements.Int, opihi_int, ovec[0].Nelements + ivec[0].Nelements);
-    for (j = ovec[0].Nelements, i = 0; i < ivec[0].Nelements; i++, j++) {
-      ovec[0].elements.Int[j] = ivec[0].elements.Int[i];
-    }
+    goto done;
   }
 
+  // the output vector is an int and input is a float:
   // this case forces ovec to be raised to FLT
   if ((ovec[0].type == OPIHI_INT) && (ivec[0].type == OPIHI_FLT)) {
@@ -64,6 +91,8 @@
       ovec[0].elements.Flt[j] = ivec[0].elements.Flt[i];
     }
+    goto done;
   }
 
+done:
   ovec[0].Nelements += ivec[0].Nelements;
   return (TRUE);
