Index: /trunk/Ohana/src/opihi/include/dvomath.h
===================================================================
--- /trunk/Ohana/src/opihi/include/dvomath.h	(revision 15877)
+++ /trunk/Ohana/src/opihi/include/dvomath.h	(revision 15878)
@@ -49,4 +49,7 @@
 void          clean_stack	    PROTO((StackVar *stack, int Nstack));
 void          delete_stack	    PROTO((StackVar *stack, int Nstack));
+void          clear_stack 	    PROTO((StackVar *stack));
+void          assign_stack 	    PROTO((StackVar *stack, char *name, int type));
+
 int           VV_binary             PROTO((StackVar *OUT, StackVar *V1, StackVar *V2, char *op));
 int           SV_binary             PROTO((StackVar *OUT, StackVar *V1, StackVar *V2, char *op));
Index: /trunk/Ohana/src/opihi/include/shell.h
===================================================================
--- /trunk/Ohana/src/opihi/include/shell.h	(revision 15877)
+++ /trunk/Ohana/src/opihi/include/shell.h	(revision 15878)
@@ -132,4 +132,6 @@
 char         *thiscomm              	PROTO((char *));
 char         *nextcomm              	PROTO((char *));
+char         *opihi_append              PROTO((char *output, int *Noutput, char *start, char *stop));
+void          interpolate_slash         PROTO((char *line));
 
 /* macro functions (mapped to commands) */
Index: /trunk/Ohana/src/opihi/lib.shell/convert_to_RPN.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/convert_to_RPN.c	(revision 15877)
+++ /trunk/Ohana/src/opihi/lib.shell/convert_to_RPN.c	(revision 15878)
@@ -97,12 +97,10 @@
 	/* pop previous, higher operators from OP stack to stack */
 	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type > type); j--) {
-	  strcpy (stack[Nstack].name, op_stack[j].name);
-	  stack[Nstack].type = op_stack[j].type;
+	  move_stack (&stack[Nstack], &op_stack[j]);
 	  Nstack ++;
 	  Nop_stack --;
 	}
 	/* push operator on OP stack */
-	strcpy (op_stack[Nop_stack].name, argv[i]);
-	op_stack[Nop_stack].type = type;
+	assign_stack (&op_stack[Nop_stack], argv[i], type);
 	Nop_stack ++;
 	break;
@@ -115,18 +113,15 @@
 	/* pop previous, higher or equal operators from OP stack to stack */
 	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type >= type); j--) {
-	  strcpy (stack[Nstack].name, op_stack[j].name);
-	  stack[Nstack].type = op_stack[j].type;
+	  move_stack (&stack[Nstack], &op_stack[j]);
 	  Nstack ++;
 	  Nop_stack --;
 	}
 	/* push operator on OP stack */
-	strcpy (op_stack[Nop_stack].name, argv[i]);
-	op_stack[Nop_stack].type = type;
+	assign_stack (&op_stack[Nop_stack], argv[i], type);
 	Nop_stack ++;
 	break;
       case 2:  
 	/* push operator on OP stack */
-	strcpy (op_stack[Nop_stack].name, argv[i]);
-	op_stack[Nop_stack].type = type;
+	assign_stack (&op_stack[Nop_stack], argv[i], type);
 	Nop_stack ++;
 	break;
@@ -134,6 +129,5 @@
 	/* pop rest of operators from OP stack to stack, looking for '(' */
 	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type != 2); j--) {
-	  strcpy (stack[Nstack].name, op_stack[j].name);
-	  stack[Nstack].type = op_stack[j].type;
+	  move_stack (&stack[Nstack], &op_stack[j]);
 	  Nstack ++;
 	  Nop_stack --;
@@ -149,6 +143,5 @@
 	/* place the value (number or vector/matrix name) on stack */
 	/* value of 'X' is used as sentinel until we sort out values */
-	strcpy (stack[Nstack].name, argv[i]);
-	stack[Nstack].type = 'X';
+	assign_stack (&stack[Nstack], argv[i], 'X');
 	Nstack ++;
 	break;
@@ -163,6 +156,5 @@
       goto cleanup;
     }
-    strcpy (stack[Nstack].name, op_stack[j].name);
-    stack[Nstack].type = op_stack[j].type;
+    move_stack (&stack[Nstack],  &op_stack[j]);
     Nstack ++;
   }
@@ -170,7 +162,11 @@
 cleanup: 
   /*** free up unused stack space ***/
-  clean_stack (op_stack, NSTACK);
+
+  // XXX there should not be any un-freed op_stacks at this point
+  // clean_stack (op_stack, NSTACK);
   free (op_stack);
-  clean_stack (&stack[Nstack], NSTACK - Nstack);
+
+  // XXX there should not be any data on higher stack entries
+  // clean_stack (&stack[Nstack], NSTACK - Nstack);
   REALLOCATE (stack, StackVar, MAX (Nstack, 1));
   *nstack = Nstack;
Index: /trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c	(revision 15877)
+++ /trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c	(revision 15878)
@@ -22,5 +22,5 @@
   if (*Nstack == 1) {
     if (stack[0].type == 'S') {
-      free (tmp_stack.name);
+      clear_stack (&tmp_stack);
       return (TRUE);
     }
@@ -38,5 +38,5 @@
     }
     push_error ("syntax error: not a math expression");
-    free (tmp_stack.name);
+    clear_stack (&tmp_stack);
     return (FALSE);
   }      
@@ -63,5 +63,5 @@
 	sprintf (line, "syntax error: binary operator with one operand: %s\n", stack[i].name);
 	push_error (line);
-	free (tmp_stack.name); 
+	clear_stack (&tmp_stack);
 	return (FALSE);
       }
@@ -84,5 +84,5 @@
 	sprintf (line, "syntax error: invalid operand for binary operation: %s or %s\n", stack[i-1].name, stack[i-2].name);
 	push_error (line);
-	free (tmp_stack.name);
+	clear_stack (&tmp_stack);
 	return (FALSE);
       }
@@ -90,5 +90,5 @@
       delete_stack (&stack[i-1], 2);
       for (j = i + 1; j < *Nstack; j++) {
-	copy_stack (&stack[j - 2], &stack[j]);
+	move_stack (&stack[j - 2], &stack[j]);
       }
       *Nstack -= 2;
@@ -103,8 +103,8 @@
       if (i < 1) {  /* need one variable to operate on */
 	push_error ("syntax error: unary operator with no operand");
-	free (tmp_stack.name);
-	return (FALSE);
-      }
-      
+	clear_stack (&tmp_stack);
+	return (FALSE);
+      }
+
       ONE_OP ("M", M_unary);
       ONE_OP ("V", V_unary);
@@ -114,5 +114,5 @@
       if (!strncasecmp (&stack[i - 1].type, "W", 1)) {
 	push_error ("syntax error: no valid string unary ops");
-	free (tmp_stack.name);
+	clear_stack (&tmp_stack);
 	return (FALSE);
       }
@@ -121,5 +121,5 @@
       delete_stack (&stack[i], 1);
       for (j = i + 1; j < *Nstack; j++) {
-	copy_stack (&stack[j - 1], &stack[j]);
+	move_stack (&stack[j - 1], &stack[j]);
       }
       init_stack (&tmp_stack);
@@ -129,5 +129,5 @@
     } 
   }
-  free (tmp_stack.name);
+  clear_stack (&tmp_stack);
 
   if (*Nstack > 1) {
@@ -153,7 +153,7 @@
 /* replace data with new stack variable */
 void move_stack (StackVar *stack1, StackVar *stack2) {
-  if (stack1[0].name != (char *) NULL) 
-    free (stack1[0].name);
+  clear_stack (stack1);
   copy_stack (stack1, stack2);
+  stack2[0].name = NULL;
 }
 
@@ -178,6 +178,5 @@
     }	
     if (VERBOSE) gprint (GP_ERR, "free %s (name) (%d) (%lx)\n", stack[i].name, i, (long) stack[i].name);
-    free (stack[i].name);
-    stack[i].name = NULL;
+    clear_stack (&stack[i]);
   }
 
@@ -188,5 +187,5 @@
   int i;
   for (i = 0; i < Nstack; i++) {
-    free (stack[i].name);
+    clear_stack (&stack[i]);
   }
 }
@@ -195,4 +194,16 @@
   stack[0].buffer = NULL;
   stack[0].vector = NULL;
-  stack[0].name = strncreate ("tmp", NCHARS);
-}
+  stack[0].name = NULL;
+}
+
+void assign_stack (StackVar *stack, char *name, int type) {
+  stack->name = strcreate (name);
+  stack->type = type;
+}
+
+void clear_stack (StackVar *stack) {
+  if (stack->name == NULL) return;
+  free (stack->name);
+  stack->name = NULL;
+  return;
+}
Index: /trunk/Ohana/src/opihi/lib.shell/expand_vars.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/expand_vars.c	(revision 15877)
+++ /trunk/Ohana/src/opihi/lib.shell/expand_vars.c	(revision 15878)
@@ -4,5 +4,5 @@
 
   char *L, *N, *V0, *V1, *Val, *newline, *c, found;
-  int done, MacroDepth;
+  int done, MacroDepth, NLINE, Noff;
 
   if (line == NULL) return (NULL);
@@ -10,5 +10,6 @@
 
   found = FALSE;
-  ALLOCATE (newline, char, 1024);  /* WARNING: this limits the length of the input line */
+  NLINE = MAX (128, strlen(line));
+  ALLOCATE (newline, char, NLINE);  /* WARNING: this limits the length of the input line */
 
   V0 = thiscomm (line);
@@ -34,4 +35,10 @@
 	 L++; 
 	 N++;
+	 if (N - newline >= NLINE - 5) {
+	   Noff = N - newline;
+	   NLINE += 128;
+	   REALLOCATE (newline, char, NLINE);
+	   N = newline + Noff;
+	 }
       }
     }
@@ -46,4 +53,10 @@
     if (V0 == NULL) {
       *N = *L;
+      if (N - newline >= NLINE - 5) {
+	Noff = N - newline;
+	NLINE += 128;
+	REALLOCATE (newline, char, NLINE);
+	N = newline + Noff;
+      }
       continue;
     }
@@ -54,4 +67,10 @@
 	*N = *L;
 	free (V0);
+	if (N - newline >= NLINE - 5) {
+	  Noff = N - newline;
+	  NLINE += 128;
+	  REALLOCATE (newline, char, NLINE);
+	  N = newline + Noff;
+	}
 	continue;
       }
@@ -65,4 +84,5 @@
 	goto error;
       } else { /* if we are executing a macro, attach the list depth to the front, pass on down the line */
+	// XXX this is limiting!!!
 	ALLOCATE (c, char, 1024);
 	sprintf (c, "%d.%s", MacroDepth, V0);
@@ -79,4 +99,10 @@
     for (; *Val != 0; N++, Val++)  {
       *N = *Val; /* place the value of the variable in the newline */
+      if (N - newline >= NLINE - 5) {
+	Noff = N - newline;
+	NLINE += 128;
+	REALLOCATE (newline, char, NLINE);
+	N = newline + Noff;
+      }
     }
     N--; /* we overshoot on last loop */
Index: /trunk/Ohana/src/opihi/lib.shell/expand_vectors.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/expand_vectors.c	(revision 15877)
+++ /trunk/Ohana/src/opihi/lib.shell/expand_vectors.c	(revision 15878)
@@ -3,7 +3,7 @@
 char *expand_vectors (char *line) {
 
-  char *newline, *tmpline, *val;
+  char *newline, *tmpline, strValue[128], *val;
   char *L, *N, *p, *q, *w;
-  int n, I, size;
+  int n, I, size, showLength, NLINE, Noff;
   double f1;
   Vector *vec;
@@ -11,6 +11,6 @@
   if (line == NULL) return (NULL);
 
-  ALLOCATE (newline, char, 1024);  /* WARNING: this limits the length of the input line */
-  ALLOCATE (tmpline, char, 1024);  /* WARNING: this limits the length of the input line */
+  NLINE = MAX (128, strlen(line));
+  ALLOCATE (newline, char, NLINE);
 
   /* look for form fred[stuff] */
@@ -19,5 +19,4 @@
   if (L == NULL) {
     free (newline);
-    free (tmpline);
     return (line);
   }
@@ -35,17 +34,19 @@
     if (p > q) goto dumpline; /* odd state: unmatched pair: ][ */
     n = (int) (q - p - 1);
+    val = NULL;
+    showLength = FALSE;
     if (n == 0) {
-      ALLOCATE (val, char, 64);
-      sprintf (val, "-1");
-      /* this choice of sentinel prevents us from using 
-	 x[-1], x[-2], and is not really needed */
+      showLength = TRUE;
     } else {
-      strncpy (tmpline, p+1, n);
-      tmpline[n] = 0;
+      tmpline = strncreate (p+1, n);
       val = dvomath (1, &tmpline, &size, 0);
+      free (tmpline);
       if (val == NULL) goto dumpline; /* not a valid vector subscript */
     }
-    I = atoi (val);
-    free (val);
+    I = 0; 
+    if (val != NULL) {
+      I = atoi (val);
+      free (val);
+    }      
 
     /* find vector name */
@@ -53,28 +54,41 @@
     w ++;
     n = (int)(p - w);
-    strncpy (tmpline, w, n);
-    tmpline[n] = 0;
+    tmpline = strncreate (w, n);
     if ((vec = SelectVector (tmpline, OLDVECTOR, TRUE)) == NULL) goto dumpline;
+    free (tmpline);
 
     /* find vector element */
-    if (I >= vec[0].Nelements) {
+    if ((I >= vec[0].Nelements) || (I < -1*vec[0].Nelements)) {
       gprint (GP_ERR, "vector subscript out of range\n"); 
       goto escape;
     }
-    if (I < 0) {
+    if (showLength) {
       f1 = vec[0].Nelements;
     } else {
-      f1 = vec[0].elements[I];
+      if (I < 0) {
+	f1 = vec[0].elements[vec[0].Nelements+I];
+      } else {
+	f1 = vec[0].elements[I];
+      }
     }
     if ((int)f1 == f1) 
-      sprintf (tmpline, "%.0f", f1);
+      snprintf (strValue, 128, "%.0f", f1);
     else
-      sprintf (tmpline, "%.9g", f1);
-    /* interpolate vector element */
+      snprintf (strValue, 128, "%.9g", f1);
+
+    /* interpolate vector element into newline (being accumulated) */
+    size = (N - newline) + (w - L) + strlen(strValue);
+    if (size >= NLINE) {
+      Noff = N - newline;
+      NLINE += 128 + strlen(strValue) + (w - L);
+      REALLOCATE (newline, char, NLINE);
+      N = newline + Noff;
+    }
+
     n = (int) (w - L);
     strncpy (N, L, n);
     N += n;
-    n = strlen (tmpline);
-    strncpy (N, tmpline, n);
+    n = strlen (strValue);
+    strncpy (N, strValue, n);
     N += n;
     L = q + 1;
@@ -82,9 +96,16 @@
 
 dumpline:
+  size = (N - newline) + strlen(L);
+  if (size >= NLINE) {
+    Noff = N - newline;
+    NLINE += 128 + strlen(L);
+    REALLOCATE (newline, char, NLINE);
+    N = newline + Noff;
+  }
+
   n = strlen (L);
   strncpy (N, L, n);
   N[n] = 0;
   free (line);
-  free (tmpline);
   return (newline);
   
@@ -92,5 +113,4 @@
   free (line);
   free (newline);
-  free (tmpline);
   return (NULL);
 }
Index: /trunk/Ohana/src/opihi/lib.shell/isolate_elements.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/isolate_elements.c	(revision 15877)
+++ /trunk/Ohana/src/opihi/lib.shell/isolate_elements.c	(revision 15878)
@@ -8,6 +8,6 @@
 
 /* local private static variables */
-int Nchar, Nout, NOUT;
-char **out;
+int NCHAR, Nchar, Nout, NOUT;
+char **myOutput;
 
 char **isolate_elements (int Nin, char **in, int *nout) {
@@ -17,6 +17,7 @@
   NOUT = Nin;
   Nchar = Nout = 0;
-  ALLOCATE (out, char *, NOUT);
-  ALLOCATE (out[Nout], char, NCHARS);
+  NCHAR = 256;
+  ALLOCATE (myOutput, char *, NOUT);
+  ALLOCATE (myOutput[Nout], char, NCHAR);
 
   for (i = 0; i < Nin; i++) {
@@ -35,9 +36,9 @@
 	/* check previous entry on line */
 	if (Nchar) {
-	  OpStat = IsAnOp (out[Nout]);
-	  if (out[Nout][0] == ')') OpStat = FALSE;
+	  OpStat = IsAnOp (myOutput[Nout]);
+	  if (myOutput[Nout][0] == ')') OpStat = FALSE;
 	} else {
-	  OpStat = IsAnOp (out[Nout-1]);
-	  if (out[Nout-1][0] == ')') OpStat = FALSE;
+	  OpStat = IsAnOp (myOutput[Nout-1]);
+	  if (myOutput[Nout-1][0] == ')') OpStat = FALSE;
 	}
 	/* if - follows an operator, must be negator */
@@ -67,9 +68,9 @@
 	/* check previous entry on line */
 	if (Nchar) {
-	  OpStat = IsAnOp (out[Nout]);
-	  if (out[Nout][0] == ')') OpStat = FALSE;
+	  OpStat = IsAnOp (myOutput[Nout]);
+	  if (myOutput[Nout][0] == ')') OpStat = FALSE;
 	} else {
-	  OpStat = IsAnOp (out[Nout-1]);
-	  if (out[Nout-1][0] == ')') OpStat = FALSE;
+	  OpStat = IsAnOp (myOutput[Nout-1]);
+	  if (myOutput[Nout-1][0] == ')') OpStat = FALSE;
 	}
 	/* if + follows an operator, must be posator */
@@ -91,5 +92,5 @@
 	if (posate) continue;
 	EndOfString ();
-	/* copy operator to out[Nout] */
+	/* copy operator to myOutput[Nout] */
 	InsertValue (in[i][j]);
 	if (negate) InsertValue ('-');
@@ -131,19 +132,23 @@
 
   /* one extra entry is allocated, free here */
-  free (out[Nout]);
+  free (myOutput[Nout]);
   *nout = Nout;
-  return (out);
+  return (myOutput);
 
 }
 
 void InsertValue (char c) {
-  out[Nout][Nchar] = c;
+  myOutput[Nout][Nchar] = c;
   Nchar ++;
-  out[Nout][Nchar] = 0;
+  if (Nchar >= NCHAR - 2) {
+    NCHAR += 256;
+    REALLOCATE (myOutput[Nout], char, NCHAR);
+  }
+  myOutput[Nout][Nchar] = 0;
 }
 
 void EndOfString () {
   if (Nchar > 0) {
-    out[Nout][Nchar] = 0;
+    myOutput[Nout][Nchar] = 0;
     Nout ++;
     Nchar = 0;
@@ -151,7 +156,8 @@
     if (Nout >= NOUT - 1) {
       NOUT += 10; 
-      REALLOCATE (out, char *, NOUT); 
+      REALLOCATE (myOutput, char *, NOUT); 
     } 
-    ALLOCATE (out[Nout], char, NCHARS); 
+    NCHAR = 256;
+    ALLOCATE (myOutput[Nout], char, NCHAR); 
   }
 }
Index: /trunk/Ohana/src/opihi/lib.shell/parse.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/parse.c	(revision 15877)
+++ /trunk/Ohana/src/opihi/lib.shell/parse.c	(revision 15878)
@@ -1,11 +1,9 @@
 # include "opihi.h"
 
-void interpolate_slash (char *line);
-
 char *parse (char *line) {
 
   double fval;
-  char *newline, *N, *L, *val, *B, *V, *V0, *V1, *end, *c1, *c2;
-  int Nval, Nbytes, status, size;
+  char *newline, *N, *L, *val, *B, *V, *V0, *V1, *c1, *c2, *p;
+  int Nval, Nbytes, status, size, NLINE;
   FILE *f;
   Vector *vec;
@@ -64,4 +62,5 @@
 
       /* val will hold the result */
+      // XXX this is limiting!!!
       ALLOCATE (val, char, 1024);
 
@@ -153,19 +152,24 @@
 
   /* case 3: {expression} */
-  ALLOCATE (newline, char, 1024);
-  for (L = line, N = newline; *L != 0; L++, N++) { 
-
-    /* copy elements from L (line) to N (newline) until we hit a '{' */
-    for (; (*L != '{') && (*L != 0); L++, N++) *N = *L;
-    if (*L == 0) break;
-
-    if ((L != line) && (*(L-1) == 0x5c)) {
-      N--;
-      *N = *L;
+  NLINE = MAX (128, strlen (line));
+  ALLOCATE (newline, char, NLINE);
+  memset (newline, 0, NLINE);
+  for (L = line; *L != 0; ) { 
+
+    // copy elements from L (line) to newline up to first '{'
+    p = strchr (L, '{');
+    newline = opihi_append (newline, &NLINE, L, p);
+    if (p == NULL) break;
+    L = p + 1;
+
+    // check for \{ at this point, replace \ in newline with {
+    if ((p > line) && (*(p - 1) == 0x5c)) {
+      N = newline + strlen(newline) - 1;
+      *N = '{'; // replace \ with {
       continue;
     }
 
     /* check on the syntax of the line */
-    L++;
+    L = p + 1;
     c1 = strchr (L, '}');
     if (c1 == NULL) {
@@ -178,5 +182,4 @@
       goto escape;
     }
-    end = c1;
     *c1 = 0;
 
@@ -188,12 +191,13 @@
       goto escape;
     } 
+
+    /* interpolate vector element into newline (being accumulated) */
+    newline = opihi_append (newline, &NLINE, val, NULL);
+
     /* copy val to outline */
-    for (V = val; *V != 0; V++,N++) *N = *V;
-    L = end;
-    N--;
+    L = c1 + 1;
     free (val); val = (char *) NULL;
   }
-  
-  *N = 0;
+
   free (line); line = (char *) NULL;
 
@@ -204,8 +208,8 @@
   return (newline); 
 
-  error:
+error:
   gprint (GP_ERR, "syntax error\n");
 
-  escape:
+escape:
   if (line != (char *) NULL) free (line);
   if (val != (char *) NULL) free (val);
@@ -214,46 +218,33 @@
 }
 
-/* replace all instances of \A with A in line */
-void interpolate_slash (char *line) {
-
-  char *in, *out;
-
-  for (in = out = line; *in != 0; in++, out++) {
-    if (*in == 0x5c) in++;
-    *out = *in;
-    if (*in == 0) return;
-  }
-  *out = *in;
-}
-
-  /* this routine looks for math and/or logic expressions that 
-     need to be evaluated and passes them on to "parenthesis",
-     which evaluates the expression */
-
-  /* There are two situations now which define an expression to 
-     be evaluated:
-     1) $var = expression   -- everything after the = must be a math expression or a string
-     2) {expression}        -- everything within the {} must be a math expression
-   */
-
-  /* case 1: $var = expression.  test that
-     a) there is a $ as the first character
-     b) the variable defined by that $ is not null
-     c) there is an = sign following the variable
-     d) there is something following the = sign
-     */
+/* this routine looks for math and/or logic expressions that 
+   need to be evaluated and passes them on to "parenthesis",
+   which evaluates the expression */
+
+/* There are two situations now which define an expression to 
+   be evaluated:
+   1) $var = expression   -- everything after the = must be a math expression or a string
+   2) {expression}        -- everything within the {} must be a math expression
+*/
+
+/* case 1: $var = expression.  test that
+   a) there is a $ as the first character
+   b) the variable defined by that $ is not null
+   c) there is an = sign following the variable
+   d) there is something following the = sign
+*/
   
-  /* case 2: vect[N] = expression. check syntax:
-     a) last char must be ]
-     b) word must contain [
-     c) between [ & ] must be an integer
-     d) vector must exist
-     e) there is an = sign following the first word
-     f) there is something following the = sign
-  */
+/* case 2: vect[N] = expression. check syntax:
+   a) last char must be ]
+   b) word must contain [
+   c) between [ & ] must be an integer
+   d) vector must exist
+   e) there is an = sign following the first word
+   f) there is something following the = sign
+*/
      
 
-  /* case 3: we hunt for '{', and then the first '}' and pass everything
-     inbetween.  no nested {{}}s are allowed! */
+/* case 3: we hunt for '{', and then the first '}' and pass everything
+   inbetween.  no nested {{}}s are allowed! */
   
 /* thisword ALLOCATES
Index: /trunk/Ohana/src/opihi/lib.shell/parse_commands.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/parse_commands.c	(revision 15877)
+++ /trunk/Ohana/src/opihi/lib.shell/parse_commands.c	(revision 15878)
@@ -4,5 +4,5 @@
 char **parse_commands (char *line, int *argc) {
 
-  int i, j, NARG;
+  int i, NARG;
   char *c;
   char **argv;
@@ -21,11 +21,8 @@
   for (i = 1; c != (char *) NULL; i++) {
     argv[i] = thisword (c);
-    if (argv[i] == (char *) NULL) {
-      for (j = 0; j < i; j++) 
-	free (argv[i]);
-      free (argv);
-      *argc = 0;
-      return (argv);
-    }
+
+    /* if one of the words does not parse (eg, ""), skip it */
+    if (argv[i] == NULL) i--;
+
     c = nextword (c);
     if (i == NARG - 1) {
@@ -49,2 +46,11 @@
 
 
+
+/* old code:
+      for (j = 0; j < i; j++) 
+	free (argv[i]);
+      free (argv);
+      *argc = 0;
+      return (argv);
+    }
+*/
Index: /trunk/Ohana/src/opihi/lib.shell/stack_math.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/stack_math.c	(revision 15877)
+++ /trunk/Ohana/src/opihi/lib.shell/stack_math.c	(revision 15878)
@@ -30,5 +30,5 @@
   }
   OUT[0].type = 'v'; /*** <<--- says this is a temporary matrix ***/
-  strcpy (OUT[0].name, "tmp");
+
   M1  = V1[0].ptr;
   M2  = V2[0].ptr;
@@ -128,6 +128,8 @@
     free (V2[0].vector);
   }
-
   /* at the end, V1 and V2 are deleted only if they were temporary */
+
+  clear_stack (V1);
+  clear_stack (V2);
   return (TRUE);
 
@@ -150,5 +152,5 @@
   }
   OUT[0].type = 'v';   /*** <<--- says this is a temporary matrix ***/
-  strcpy (OUT[0].name, "tmp");
+
   M1  = V1[0].ptr;
   M2  = V2[0].ptr;
@@ -243,4 +245,7 @@
     free (V2[0].vector);
   }
+
+  clear_stack (V1);
+  clear_stack (V2);
 
   /* at the end, V1 and V2 are deleted only if they were temporary */
@@ -265,5 +270,5 @@
   }
   OUT[0].type = 'v';   /*** <<--- says this is a temporary matrix ***/
-  strcpy (OUT[0].name, "tmp");
+
   M1  = V1[0].ptr;
   M2  = V2[0].ptr;
@@ -359,4 +364,8 @@
     free (V1[0].vector);
   }
+
+  clear_stack (V1);
+  clear_stack (V2);
+
   /* at the end, V1 and V2 are deleted only if they were temporary */
   return (TRUE);
@@ -387,5 +396,5 @@
   }
   OUT[0].type = 'm'; /*** <<--- says this is a temporary matrix ***/
-  strcpy (OUT[0].name, "tmp");
+
   M1  = V1[0].ptr;
   M2  = V2[0].ptr;
@@ -524,4 +533,8 @@
     free (V2[0].vector);
   }
+
+  clear_stack (V1);
+  clear_stack (V2);
+
   /* at the end, V1 and V2 are deleted only if they were temporary */
   return (TRUE);
@@ -551,5 +564,5 @@
   }
   OUT[0].type = 'm'; /*** <<--- says this is a temporary matrix ***/
-  strcpy (OUT[0].name, "tmp");
+
   M1  = V1[0].ptr;
   M2  = V2[0].ptr;
@@ -707,4 +720,8 @@
     free (V2[0].buffer);
   }
+
+  clear_stack (V1);
+  clear_stack (V2);
+
   /* at the end, V1 and V2 are deleted only if they were temporary */
   return (TRUE);
@@ -734,5 +751,5 @@
   }
   OUT[0].type = 'm'; /*** <<--- says this is a temporary matrix ***/
-  strcpy (OUT[0].name, "tmp");
+
   M1  = V1[0].ptr;
   M2  = V2[0].ptr;
@@ -834,4 +851,8 @@
     free (V2[0].buffer);
   }
+
+  clear_stack (V1);
+  clear_stack (V2);
+
   /* at the end, V1 and V2 are deleted only if they were temporary */
   return (TRUE);
@@ -858,5 +879,5 @@
   }
   OUT[0].type = 'm';      /*** <<--- says this is a temporary matrix ***/
-  strcpy (OUT[0].name, "tmp");
+
   M1  = V1[0].ptr;
   M2  = V2[0].ptr;
@@ -951,4 +972,7 @@
     free (V1[0].buffer);
   }
+  clear_stack (V1);
+  clear_stack (V2);
+
   return (TRUE);
 
@@ -973,5 +997,5 @@
   }
   OUT[0].type = 'm'; /*** <<--- says this is a temporary matrix ***/
-  strcpy (OUT[0].name, "tmp");
+
   M1  = V1[0].ptr;
   M2  = V2[0].ptr;
@@ -1066,4 +1090,7 @@
     free (V2[0].buffer);
   }
+  clear_stack (V1);
+  clear_stack (V2);
+
   return (TRUE);
 
@@ -1080,5 +1107,5 @@
   OUT[0].ptr = V1[0].ptr;
   out = OUT[0].ptr;
-  strcpy (OUT[0].name, "tmp");
+
 
   switch (op[0]) { 
@@ -1147,4 +1174,8 @@
   OUT[0].Float = *(OUT[0].ptr);
   OUT[0].type = 'S';
+
+  clear_stack (V1);
+  clear_stack (V2);
+
   return (TRUE);
 
@@ -1192,8 +1223,10 @@
 
 escape:
-  strcpy (OUT[0].name, "tmp");
   OUT[0].Float = value;
   OUT[0].type = 'S';
   OUT[0].ptr = &OUT[0].Float;
+
+  clear_stack (V1);
+  clear_stack (V2);
   return (TRUE);
 
@@ -1244,4 +1277,6 @@
   OUT[0].Float = *out;
   OUT[0].type = 'S';
+
+  clear_stack (V1);
   return (TRUE);
 
@@ -1309,5 +1344,8 @@
     free (V1[0].vector[0].elements);
     free (V1[0].vector);
+    V1[0].vector = NULL;
   }  
+
+  clear_stack (V1);
   return (TRUE);
 
@@ -1390,4 +1428,6 @@
     free (V1[0].buffer);
   }
+
+  clear_stack (V1);
   return (TRUE);
 
Index: /trunk/Ohana/src/opihi/lib.shell/string.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/string.c	(revision 15877)
+++ /trunk/Ohana/src/opihi/lib.shell/string.c	(revision 15878)
@@ -249,2 +249,41 @@
   return (c);
 }
+
+// append string defined by range start - stop to the end of output, which
+// currently has an allocated size of Noutput.  if this operation would overshoot Noutput, 
+// output is reallocated to a sufficiently large size
+char *opihi_append (char *output, int *Noutput, char *start, char *stop) {
+
+  int N1, N2, outlen;
+
+  // a NULL end pointer means 'go to end of line'
+  if (stop == NULL) {
+    stop = start + strlen(start);
+  }
+
+  // enough space?
+  N1 = strlen(output);
+  N2 = stop - start;
+  outlen = N1 + N2;
+  if (outlen >= *Noutput) {
+    *Noutput = outlen + 128;
+    REALLOCATE (output, char, *Noutput);
+    memset (&output[N1], 0, N2 + 128);
+  }
+
+  strncat (output, start, stop - start);
+  return output;
+}
+
+/* replace all instances of \A with A in line */
+void interpolate_slash (char *line) {
+
+  char *in, *out;
+
+  for (in = out = line; *in != 0; in++, out++) {
+    if (*in == 0x5c) in++;
+    *out = *in;
+    if (*in == 0) return;
+  }
+  *out = *in;
+}
