Index: /branches/eam_branches/ohana.20150429/src/libohana/Makefile
===================================================================
--- /branches/eam_branches/ohana.20150429/src/libohana/Makefile	(revision 38376)
+++ /branches/eam_branches/ohana.20150429/src/libohana/Makefile	(revision 38377)
@@ -1,5 +1,5 @@
 default: install
 help:
-	@echo "make options: install libohana clean dist test typetest"
+	@echo "make options: install libohana clean dist test test.clean"
 
 include ../../Makefile.System
@@ -10,5 +10,6 @@
 MAN	=	$(HOME)/doc
 INC	=	$(HOME)/include
-TESTDIR =       $(HOME)/test
+TESTDIR	=	$(HOME)/test
+TESTBIN	=	$(HOME)/test
 include ../../Makefile.Common
 
@@ -17,7 +18,10 @@
 FULL_CPPFLAGS = $(BASE_CPPFLAGS)
 FULL_LDFLAGS  = $(BASE_LDFLAGS)
-TFLAGS        = $(FULL_CFLAGS) $(FULL_CPPFLAGS) $(FULL_LDFLAGS) -lohana -ltap_ohana
 
-install: $(DESTLIB)/libohana.a $(DESTLIB)/libohana.$(DLLTYPE) typetest
+TEST_CFLAGS   =	$(BASE_CFLAGS)
+TEST_CPPFLAGS =	$(BASE_CPPFLAGS)
+TEST_LDFLAGS  = $(BASE_LDFLAGS) -lohana -ltap_ohana
+
+install: $(DESTLIB)/libohana.a $(DESTLIB)/libohana.$(DLLTYPE)
 libohana: $(LIB)/libohana.$(ARCH).a $(LIB)/libohana.$(ARCH).$(DLLTYPE)
 
@@ -51,24 +55,4 @@
 # $(SRC)/gsl_utils.$(ARCH).o	 \
 
-TYPETEST = \
-$(TESTDIR)/typetest.$(ARCH)
-
-$(TYPETEST) : $(LIB)/libohana.$(ARCH).a
-
-typetest: $(TYPETEST)
-	for i in $(TYPETEST); do $$i || exit 1; done
-
-TEST = \
-$(TESTDIR)/memtest.$(ARCH)
-# $(TESTDIR)/string.$(ARCH)
-
-testcode: install $(TEST)
-test:
-	$(MAKE) testcode
-	for i in $(TEST); do $$i; done
-
-quicktest: 
-	for i in $(TEST); do $$i; done
-
 $(OBJS): $(INCS)
 
@@ -79,7 +63,7 @@
 $(DESTLIB)/libohana.$(DLLTYPE): $(LIB)/libohana.$(ARCH).$(DLLTYPE)
 
-$(TESTDIR)/%.$(ARCH) : $(TESTDIR)/%.c
-	$(CC) $^ -o $@ $(TFLAGS)
+TESTPROG = memtest typetest string 
+$(TESTPROG) : % : $(TESTBIN)/% $(OBJS)
+test: $(TESTPROG)
+	for i in $(TESTPROG); do $(TESTBIN)/$$i; done
 
-.PHONY: test
-
Index: /branches/eam_branches/ohana.20150429/src/libohana/include/ohana.h
===================================================================
--- /branches/eam_branches/ohana.20150429/src/libohana/include/ohana.h	(revision 38376)
+++ /branches/eam_branches/ohana.20150429/src/libohana/include/ohana.h	(revision 38377)
@@ -286,5 +286,5 @@
 char   *strcreate              PROTO((char *string));
 char   *strncreate             PROTO((char *string, int n));
-int     strextend              PROTO((char *input, char *format,...)) OHANA_FORMAT(printf, 2, 3);
+int     strextend              PROTO((char **input, char *format,...)) OHANA_FORMAT(printf, 2, 3);
 int     scan_line              PROTO((FILE *f, char *line)); 
 int     scan_line_maxlen       PROTO((FILE *f, char *line, int maxlen)); 
Index: /branches/eam_branches/ohana.20150429/src/libohana/src/string.c
===================================================================
--- /branches/eam_branches/ohana.20150429/src/libohana/src/string.c	(revision 38376)
+++ /branches/eam_branches/ohana.20150429/src/libohana/src/string.c	(revision 38377)
@@ -51,17 +51,4 @@
 }
 
-int strextend (char *input, char *format,...) {
-
-  char tmpextra[1024], tmpline[1024];
-  va_list argp;
-
-  va_start (argp, format);
-  vsnprintf (tmpextra, 1024, format, argp);
-  snprintf (tmpline, 1024, "%s %s", input, tmpextra);
-  strcpy (input, tmpline);
-
-  return TRUE;
-}
-
 /* create a new string of length n from this string */
 char *strncreate (char *string, int n) {
@@ -76,4 +63,32 @@
   line[n] = 0;
   return (line);
+}
+
+// extend input as needed to add the formatted pieces
+// if input is NULL, allocate a new line
+// the result of the format must be < 1024 bytes
+int strextend (char **input, char *format,...) {
+
+  int Nchar;
+  char tmpextra[1024], tmpline, *output;
+  va_list argp;
+
+  va_start (argp, format);
+  Nchar = vsnprintf (tmpextra, 1024, format, argp);
+  if (Nchar > 1024 - 1) return FALSE;
+
+  if (*input) {
+    Nchar = snprintf (&tmpline, 0, "%s %s", *input, tmpextra);
+    ALLOCATE (output, char, Nchar + 1);
+    snprintf (output, Nchar + 1, "%s %s", *input, tmpextra);
+    free (*input);
+  } else {
+    Nchar = strlen(tmpextra) + 1;
+    ALLOCATE (output, char, Nchar);
+    strcpy (output, tmpextra);
+  }
+  *input = output;
+
+  return TRUE;
 }
 
Index: /branches/eam_branches/ohana.20150429/src/libohana/test/string.c
===================================================================
--- /branches/eam_branches/ohana.20150429/src/libohana/test/string.c	(revision 38376)
+++ /branches/eam_branches/ohana.20150429/src/libohana/test/string.c	(revision 38377)
@@ -4,5 +4,5 @@
 int main (void) {
 
-  plan_tests (16);
+  plan_tests (20);
 
   diag ("libohana string.c tests");
@@ -67,4 +67,19 @@
     skip_end();
   }
+
+  /*** strextend ***/
+  {
+    int status;
+    char *string = NULL;
+
+    status = strextend(&string, "hello %s", "there");
+    ok (status, "strextend for NULL input");
+    ok (!strcmp(string, "hello there"), "strextend format");
+    
+    status = strextend(&string, "more words %d", 2);
+    ok (status, "strextend for non-NULL input");
+    ok (!strcmp(string, "hello there more words 2"), "strextend format");
+  }
+    
   return exit_status();
 }
