Index: /trunk/Ohana/src/opihi/cmd.data/read_vectors.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.data/read_vectors.c	(revision 41362)
+++ /trunk/Ohana/src/opihi/cmd.data/read_vectors.c	(revision 41363)
@@ -335,4 +335,5 @@
 		value = thisword(ptr);
 	      }
+	      if (value == NULL) {value = strcreate ("");} // we need at least an empty string not a NULL
 	      vec[i][0].elements.Str[Nelem] = value; // needs to be freed later.
 	      break;
Index: /trunk/Ohana/src/opihi/include/dvomath.h
===================================================================
--- /trunk/Ohana/src/opihi/include/dvomath.h	(revision 41362)
+++ /trunk/Ohana/src/opihi/include/dvomath.h	(revision 41363)
@@ -102,4 +102,5 @@
 void          clear_stack 	    PROTO((StackVar *stack));
 void          assign_stack 	    PROTO((StackVar *stack, char *name, StackVarType type));
+char         *clean_stack_name      PROTO((char *name));
 
 int           SSS_trinary           PROTO((StackVar *OUT, StackVar *V1, StackVar *V2, StackVar *V3, char *op));
@@ -116,4 +117,7 @@
 int           SM_binary             PROTO((StackVar *OUT, StackVar *V1, StackVar *V2, char *op));
 int           SS_binary             PROTO((StackVar *OUT, StackVar *V1, StackVar *V2, char *op));
+int           LW_binary             PROTO((StackVar *OUT, StackVar *V1, StackVar *V2, char *op));
+int           WL_binary             PROTO((StackVar *OUT, StackVar *V1, StackVar *V2, char *op));
+int           LL_binary             PROTO((StackVar *OUT, StackVar *V1, StackVar *V2, char *op));
 int           WW_binary             PROTO((StackVar *OUT, StackVar *V1, StackVar *V2, char *op));
 int           S_unary               PROTO((StackVar *OUT, StackVar *V1, char *op));
Index: /trunk/Ohana/src/opihi/lib.shell/check_stack.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/check_stack.c	(revision 41362)
+++ /trunk/Ohana/src/opihi/lib.shell/check_stack.c	(revision 41363)
@@ -84,4 +84,10 @@
       /* this is not a scalar, vector, or matrix.  must be string */
       stack[i].type  = ST_STRING;
+      
+      /* I could strip the quotes from the name here, 
+	 but this might change the behavior for string tests
+      */
+
+      // I cannot require quotes around a string here because variables are expanded upstream
     }
   }
Index: /trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c	(revision 41362)
+++ /trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c	(revision 41363)
@@ -30,4 +30,5 @@
 
 // A & B value types all have 2 possible values
+// 
 # define TWO_OP(A,B,FUNC) {						\
     if ((stack[i - 2].type == A) && (stack[i - 1].type == B)) {		\
@@ -163,20 +164,28 @@
 	}
 
+	// TWO_OP(A,B,OP) : A,B types all have a main value and a secondary value at A+1 or B+1:
+	// ST_MATRIX -> ST_MATRIX_TMP
+	// ST_VECTOR -> ST_VECTOR_TMP
+	// ST_SCALAR_INT -> ST_SCALAR_FLT 
 	status = FALSE;
 	TWO_OP (ST_MATRIX,ST_MATRIX,MM_binary);
 	TWO_OP (ST_MATRIX,ST_VECTOR,MV_binary);
-	TWO_OP (ST_MATRIX,ST_SCALAR_INT,MS_binary);
+	TWO_OP (ST_MATRIX,ST_SCALAR_INT,MS_binary); // handles ST_SCALAR_INT and ST_SCALAR_FLT 
 
 	TWO_OP (ST_VECTOR,ST_MATRIX,VM_binary);
 	TWO_OP (ST_VECTOR,ST_VECTOR,VV_binary);
-	TWO_OP (ST_VECTOR,ST_SCALAR_INT,VS_binary);
-
-	TWO_OP (ST_SCALAR_INT,ST_MATRIX,SM_binary);
-	TWO_OP (ST_SCALAR_INT,ST_VECTOR,SV_binary);
-	TWO_OP (ST_SCALAR_INT,ST_SCALAR_INT,SS_binary);      
-
-	TWO_OP (ST_SCALAR_FLT,ST_MATRIX,SM_binary);
-	TWO_OP (ST_SCALAR_FLT,ST_VECTOR,SV_binary);
-	TWO_OP (ST_SCALAR_FLT,ST_SCALAR_INT,SS_binary);      
+	TWO_OP (ST_VECTOR,ST_SCALAR_INT,VS_binary); // handles ST_SCALAR_INT and ST_SCALAR_FLT 
+
+	TWO_OP (ST_SCALAR_INT,ST_MATRIX,SM_binary); // handles ST_SCALAR_INT and ST_SCALAR_FLT 
+	TWO_OP (ST_SCALAR_INT,ST_VECTOR,SV_binary); // handles ST_SCALAR_INT and ST_SCALAR_FLT 
+	TWO_OP (ST_SCALAR_INT,ST_SCALAR_INT,SS_binary);       // handles ST_SCALAR_INT and ST_SCALAR_FLT 
+
+//      XXX: this block is not needed
+//	TWO_OP (ST_SCALAR_FLT,ST_MATRIX,SM_binary);
+//	TWO_OP (ST_SCALAR_FLT,ST_VECTOR,SV_binary);
+//	TWO_OP (ST_SCALAR_FLT,ST_SCALAR_INT,SS_binary);      
+
+	TWO_OP (ST_VECTOR,ST_STRING,LW_binary);      
+	TWO_OP (ST_STRING,ST_VECTOR,WL_binary);      
 
 	TWO_OP (ST_STRING,ST_STRING,WW_binary);      
@@ -350,6 +359,25 @@
 }
 
+// strip off surrounding " and return newly allocated string
+char *clean_stack_name (char *name) {
+
+  if (!name) return name;
+
+  char *tmpname = name;
+  if (name[0] == '"') tmpname ++;
+
+  char *output = strcreate (tmpname);
+
+  int Nchar = strlen(output);
+  if (Nchar == 0) return output; // empty string
+
+  // squash ending quotes:
+  if (output[Nchar - 1] == '"') output[Nchar - 1] = 0;
+
+  return output;
+}
+
 void assign_stack (StackVar *stack, char *name, StackVarType type) {
-  stack->name = strcreate (name);
+  stack->name = strcreate(name);
   stack->type = type;
 }
Index: /trunk/Ohana/src/opihi/lib.shell/stack_math.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/stack_math.c	(revision 41362)
+++ /trunk/Ohana/src/opihi/lib.shell/stack_math.c	(revision 41363)
@@ -272,4 +272,9 @@
   if (V1[0].vector[0].Nelements != V2[0].vector[0].Nelements) {
     return (FALSE);
+  }
+
+  if ((V1->vector->type == OPIHI_STR) && (V2->vector->type == OPIHI_STR)) {
+    int status = LL_binary (OUT, V1, V2, op);
+    return status;
   }
 
@@ -1315,4 +1320,163 @@
   return (TRUE);
 
+}
+
+// vector string OP scalar string (called if V1 is vector, V2 is string)
+// V1 MUST be a string-valued vector
+int LW_binary (StackVar *OUT, StackVar *V1, StackVar *V2, char *op) {
+
+  char line[512]; // this is only used to report an error 
+
+  if (V1->vector->type != OPIHI_STR) {
+    snprintf (line, 512, "error: binary operation between numerical vector and string not defined");
+    push_error (line);
+    return (FALSE);
+  }
+
+  /* only 'N' and 'E' are allowed for WW_binary operations. anything else is either a
+     syntax error or is a string which looks like a math expression. */
+
+  if ((op[0] != 'N') && (op[0] != 'E')) {
+    snprintf (line, 512, "error: op %c not defined for vector string operations!", op[0]);
+    push_error (line);
+    return (FALSE);
+  }
+
+  int Nx = V1[0].vector[0].Nelements;
+
+  OUT[0].vector = InitVector ();
+  OUT[0].type = ST_VECTOR_TMP;   /*** <<--- says this is a temporary matrix ***/
+
+  /* evaluate stack will only call WW_binary with one numerical value,
+     and only in the case that the string did not parse to a number 
+     thus: string == number -> false */
+
+  // output vector is an integer (result of strcmp test)
+  MatchVector (OUT[0].vector, V1[0].vector, OPIHI_INT);
+  opihi_int *out = OUT[0].vector[0].elements.Int;
+
+  // remove the quotes around the name (string value) here
+  char *M2 = clean_stack_name(V2[0].name);
+
+  for (int i = 0; i < Nx; i++, out++) {
+    char *M1 =  V1[0].vector[0].elements.Str[i];
+    if (op[0] == 'E') {
+      //     *out = (M1 == NULL) || strcmp(M1, M2) ? 0 : 1;
+      *out = strcmp(M1, M2) ? 0 : 1;
+    }
+    if (op[0] == 'N') {
+      *out = strcmp(M1, M2) ? 1 : 0;
+    }
+  }
+
+  clear_stack (V1);
+  clear_stack (V2);
+  FREE (M2);
+
+  /* at the end, V1 and V2 are deleted only if they were temporary */
+  return (TRUE);
+}
+
+// vector string OP scalar string (called if V2 is vector, V1 is string)
+// V2 MUST be a string-valued vector
+int WL_binary (StackVar *OUT, StackVar *V1, StackVar *V2, char *op) {
+
+  char line[512]; // this is only used to report an error 
+
+  if (V2->vector->type != OPIHI_STR) {
+    snprintf (line, 512, "error: binary operation between numerical vector and string not defined");
+    push_error (line);
+    return (FALSE);
+  }
+
+  /* only 'N' and 'E' are allowed for WW_binary operations. anything else is either a
+     syntax error or is a string which looks like a math expression. */
+
+  if ((op[0] != 'N') && (op[0] != 'E')) {
+    snprintf (line, 512, "error: op %c not defined for vector string operations!", op[0]);
+    push_error (line);
+    return (FALSE);
+  }
+
+  int Nx = V2[0].vector[0].Nelements;
+
+  OUT[0].vector = InitVector ();
+  OUT[0].type = ST_VECTOR_TMP;   /*** <<--- says this is a temporary matrix ***/
+
+  /* evaluate stack will only call WW_binary with one numerical value,
+     and only in the case that the string did not parse to a number 
+     thus: string == number -> false */
+
+  // output vector is an integer (result of strcmp test)
+  MatchVector (OUT[0].vector, V2[0].vector, OPIHI_INT);
+  opihi_int *out = OUT[0].vector[0].elements.Int;
+
+  // remove the quotes around the name (string value) here
+  char *M1 = clean_stack_name(V1[0].name);
+
+  for (int i = 0; i < Nx; i++, out++) {
+    char *M2 =  V2[0].vector[0].elements.Str[i];
+    if (op[0] == 'E') {
+      *out = strcmp(M1, M2) ? 0 : 1;
+    }
+    if (op[0] == 'N') {
+      *out = strcmp(M1, M2) ? 1 : 0;
+    }
+  }
+
+  clear_stack (V1);
+  clear_stack (V2);
+  FREE (M1);
+
+  /* at the end, V1 and V2 are deleted only if they were temporary */
+  return (TRUE);
+}
+
+// vector string OP vector string (called by VV_binary above if both V1 & V2 are vector strings)
+int LL_binary (StackVar *OUT, StackVar *V1, StackVar *V2, char *op) {
+
+  char line[512]; // this is only used to report an error 
+
+  if ((V1->vector->type != OPIHI_STR) || (V2->vector->type != OPIHI_STR)) {
+    snprintf (line, 512, "error: binary operations between numerical vector and string vector not defined");
+    push_error (line);
+    return (FALSE);
+  }
+
+  /* only 'N' and 'E' are allowed for WW_binary operations. anything else is either a
+     syntax error or is a string which looks like a math expression. */
+
+  if ((op[0] != 'N') && (op[0] != 'E')) {
+    snprintf (line, 512, "error: op %c not defined for vector string operations!", op[0]);
+    push_error (line);
+    return (FALSE);
+  }
+
+  int Nx = V1[0].vector[0].Nelements;
+
+  OUT[0].vector = InitVector ();
+  OUT[0].type = ST_VECTOR_TMP;   /*** <<--- says this is a temporary matrix ***/
+
+  // output vector is an integer (result of strcmp test)
+  MatchVector (OUT[0].vector, V1[0].vector, OPIHI_INT);
+  opihi_int *out = OUT[0].vector[0].elements.Int;
+
+  char **M1 =  V1[0].vector[0].elements.Str;
+  char **M2 =  V2[0].vector[0].elements.Str;
+
+  for (int i = 0; i < Nx; i++, out++, M1++, M2++) {
+    if (op[0] == 'E') {
+      *out = strcmp(*M1, *M2) ? 0 : 1;
+    }
+    if (op[0] == 'N') {
+      *out = strcmp(*M1, *M2) ? 1 : 0;
+    }
+  }
+
+  clear_stack (V1);
+  clear_stack (V2);
+
+  /* at the end, V1 and V2 are deleted only if they were temporary */
+  return (TRUE);
 }
 
