Index: tests/zombies/string-perf/Makefile
===================================================================
--- tests/zombies/string-perf/Makefile	(revision 97d58dca469f687e58f035bd4fc46d354069f72a)
+++ tests/zombies/string-perf/Makefile	(revision fefd77adcd0a40d9ea468278e2369a92cfd9e773)
@@ -8,38 +8,73 @@
 
 
-PERFPROGS = \
-	perfexp-cfa-hl-pta-share \
-	perfexp-cfa-hl-peq-share \
-	perfexp-cfa-ll-pta-share \
-	perfexp-cfa-ll-peq-share \
-	perfexp-cfa-hl-pta-noshare \
-	perfexp-cfa-hl-peq-noshare \
-	perfexp-cfa-ll-pta-noshare \
-	perfexp-cfa-ll-peq-noshare \
-	perfexp-stl-pta \
-	perfexp-stl-peq \
-	perfexp-buhr94-pta \
-	perfexp-buhr94-peq
-
-all : $(PERFPROGS)
-
-# upper-case conversion function
+# function: convert to upper case
 define uc
 $(shell echo $(1) | tr  '[:lower:]' '[:upper:]')
 endef
 
-perfexp-cfa-%: APILEVEL=$(call uc,$(word 3,$(subst -, ,$@)))
-perfexp-cfa-%: OPERATION=$(call uc,$(word 4,$(subst -, ,$@)))
-perfexp-cfa-%: SHARING=$(call uc,$(word 5,$(subst -, ,$@)))
+# function: project numbered element of filename named by hyphen-delimited tuple
+# (call hyphProj,q-w-e-r.txt,1) is Q
+define ucHyphProj
+$(call uc,$(word $(2),$(subst -, ,$(basename $(1)))))
+endef
+
+# function: cross two lists, adding hyphen delimiters
+# (call hyphCross,a b c,1 2) is a-1 a-2 b-1 b-2 c-1 c-2
+define hyphCross
+$(foreach x,$(1),$(foreach xs,$(2),$(x)-$(xs)))
+endef
+
+define hyphCross3
+$(call hyphCross,$(1),$(call hyphCross,$(2),$(3)))
+endef
+
+define hyphCross4
+$(call hyphCross,$(1),$(call hyphCross3,$(2),$(3),$(4)))
+endef
+
+define hyphCross5
+$(call hyphCross,$(1),$(call hyphCross4,$(2),$(3),$(4),$(5)))
+endef
+
+OPERATIONS=pta peq
+ALLOCS=reuse fresh
+CFA_APILEVELS=hl ll
+CFA_SHARINGS=share noshare
+PLATFORMS=cfa stl buhr94
+
+ifneq ($(filter cfa,$(PLATFORMS)),)
+	CFA_PERFPROGS=$(call hyphCross5,perfexp-cfa,$(CFA_APILEVELS),$(OPERATIONS),$(CFA_SHARINGS),$(ALLOCS))
+endif
+
+ifneq ($(filter stl,$(PLATFORMS)),)
+	STL_PERFPROGS=$(call hyphCross3,perfexp-stl,$(OPERATIONS),$(ALLOCS))
+endif
+
+ifneq ($(filter buhr94,$(PLATFORMS)),)
+	BUHR94_PERFPROGS=$(call hyphCross3,perfexp-buhr94,$(OPERATIONS),$(ALLOCS))
+endif
+
+PERFPROGS = $(CFA_PERFPROGS) $(STL_PERFPROGS) $(BUHR94_PERFPROGS)
+
+all : $(PERFPROGS)
+
+
+
+perfexp-cfa-%: CFA_APILEVEL=$(call ucHyphProj,$@,3)
+perfexp-cfa-%: OPERATION=$(call ucHyphProj,$@,4)
+perfexp-cfa-%: CFA_SHARING=$(call ucHyphProj,$@,5)
+perfexp-cfa-%: ALLOC=$(call ucHyphProj,$@,6)
 perfexp-cfa-%: prog.cfa $(LIBCFA)
-	$(CFA) $(PERFFLAGS_CFA) $< -o $@ -DIMPL_CFA_$(APILEVEL)_$(SHARING) -DOP_$(OPERATION)
+	$(CFA) $(PERFFLAGS_CFA) $< -o $@ -DIMPL_CFA_$(CFA_APILEVEL)_$(CFA_SHARING) -DOP_$(OPERATION) -DALLOC_$(ALLOC)
 
-perfexp-stl-%: OPERATION=$(call uc,$(word 3,$(subst -, ,$@)))
+perfexp-stl-%: OPERATION=$(call ucHyphProj,$@,3)
+perfexp-stl-%: ALLOC=$(call ucHyphProj,$@,4)
 perfexp-stl-%: prog.cfa
-	$(CXX) -xc++ $(PERFFLAGS_CXX) $< -o $@ -DIMPL_STL -DOP_$(OPERATION)
+	$(CXX) -xc++ $(PERFFLAGS_CXX) $< -o $@ -DIMPL_STL -DOP_$(OPERATION) -DALLOC_$(ALLOC)
 
-perfexp-buhr94-%.o: OPERATION=$(call uc,$(word 3,$(subst -, ,$(basename $@))))
+perfexp-buhr94-%.o: OPERATION=$(call ucHyphProj,$@,3)
+perfexp-buhr94-%.o: ALLOC=$(call ucHyphProj,$@,4)
 perfexp-buhr94-%.o: prog.cfa
-	$(CXX) -xc++ -c $(PERFFLAGS_CXX) $< -o $@ -DIMPL_BUHR94 -DOP_$(OPERATION)
+	$(CXX) -xc++ -c $(PERFFLAGS_CXX) $< -o $@ -DIMPL_BUHR94 -DOP_$(OPERATION) -DALLOC_$(ALLOC)
 
 buhr94-string.o:
@@ -66,5 +101,5 @@
 			printed=`./$$prog 100 10 $$corpusbody` ; \
 			echo $$prog,$$corpus,$$printed  >>  $$tofile ; \
+			echo $$prog,$$corpus,$$printed  ; \
 		done ; \
-	done ; \
-	cat $$tofile
+	done
Index: tests/zombies/string-perf/prog.cfa
===================================================================
--- tests/zombies/string-perf/prog.cfa	(revision 97d58dca469f687e58f035bd4fc46d354069f72a)
+++ tests/zombies/string-perf/prog.cfa	(revision fefd77adcd0a40d9ea468278e2369a92cfd9e773)
@@ -108,15 +108,27 @@
     clock_t start, end_target, end_actual;
 
+    #if defined IMPL_CFA_LL && defined OP_PTA
+        string_res pta_ll_temp;
+    #endif
+
     #if defined IMPL_CFA_LL
-        string_res x = "starter";
-        string_res y;
-      #if defined OP_PTA
-        string_res z;
-      #endif
-        #define RESET y = x;
+      #define DECLS \
+        string_res initval = "starter"; \
+        string_res accum = { initval, COPY_VALUE };
     #else
-        string x = "starter";
-        string y;
-        #define RESET y = x;
+      #define DECLS \
+        string initval = "starter"; \
+        string accum = initval;
+    #endif
+
+    #if defined ALLOC_REUSE
+      DECLS
+      #define RESET \
+        accum = initval;
+    #elif defined ALLOC_FRESH
+      #define RESET \
+        DECLS
+    #else
+      #error bad alloc
     #endif
 
@@ -127,14 +139,14 @@
             RESET
             for ( volatile unsigned int i = 0; i < concatsPerReset; i += 1 ) {
-              MAYBE( PRINT(y) )
+              MAYBE( PRINT(accum) )
               char *toAppend = corpus[i % corpuslen]; // ? corpus[rand() % corpuslen]
               #if defined OP_PTA && defined IMPL_CFA_LL
-                 z = y;
-                 z += toAppend;
-                 y = z;
+                 pta_ll_temp = accum;
+                 pta_ll_temp += toAppend;
+                 accum = pta_ll_temp;
               #elif defined OP_PTA
-                 y = y + toAppend;
+                 accum = accum + toAppend;
               #elif defined OP_PEQ
-                 y += toAppend;
+                 accum += toAppend;
               #endif
             }
