Index: trunk/mkstructinfo.awk
===================================================================
--- trunk/mkstructinfo.awk	(revision 3)
+++ trunk/mkstructinfo.awk	(revision 4)
@@ -22,5 +22,11 @@
 			# elms = elms " `" buffer[i] "'";
 			elm = elm "sizeof(((" instruct "*)NULL)->" buffer[i] ")";
-			elms = elms " " buffer[i] "";
+
+			if (elms == "") {
+				elms = buffer[i];
+			}
+			else {
+				elms = elms "," buffer[i];
+			}
 		}
 		printf "define(`ELEMENTSOF_%s', `%s')\n", instruct, elms;
Index: trunk/processor/hashtable.m4
===================================================================
--- trunk/processor/hashtable.m4	(revision 3)
+++ trunk/processor/hashtable.m4	(revision 4)
@@ -101,8 +101,8 @@
 				IFCOPY(`pnew->pData = &pnew->pDataPtr;')
 				dnl no alloc
-				STRUCT_P_EX(`$2', pnew->pData, (($2*)b->pData), `$3', ` ')
+				STRUCT_P_EX(`$2', pnew->pData, (($2*)b->pData), `', `$3', ` ')
 			}
 			else {
-				STRUCT_P_EX(`$2', pnew->pData, (($2*)b->pData), `$3')
+				STRUCT_P_EX(`$2', pnew->pData, (($2*)b->pData), `', `$3')
 				IFCOPY(`pnew->pDataPtr = NULL;')
 			}
Index: trunk/processor/head.m4
===================================================================
--- trunk/processor/head.m4	(revision 3)
+++ trunk/processor/head.m4	(revision 4)
@@ -7,4 +7,5 @@
 #include "zend_compile.h"
 #include "zend_API.h"
+#include "zend_ini.h"
 
 #include "xcache.h"
@@ -29,5 +30,5 @@
 #undef NDEBUG
 #include <assert.h>
-include(structinfo.m4)
+include(builddir`/structinfo.m4')
 ')
 #ifndef NDEBUG
Index: trunk/processor/main.m4
===================================================================
--- trunk/processor/main.m4	(revision 3)
+++ trunk/processor/main.m4	(revision 4)
@@ -87,14 +87,15 @@
 ')
 dnl }}}
-dnl {{{ PROC_CLASS_ENTRY_P
-define(`PROC_CLASS_ENTRY_P', `PROC_CLASS_ENTRY_P_EX(`dst->$1', `src->$1')`'DONE(`$1')')
+dnl {{{ PROC_CLASS_ENTRY_P(1:elm)
+define(`PROC_CLASS_ENTRY_P', `PROC_CLASS_ENTRY_P_EX(`dst->$1', `src->$1', `$1')`'DONE(`$1')')
+dnl PROC_CLASS_ENTRY_P_EX(1:dst, 2:src, 3:elm-name)
 define(`PROC_CLASS_ENTRY_P_EX', `
 	if ($2) {
 		IFSTORE(`$1 = (zend_class_entry *) xc_get_class_num(processor, $2);')
 		IFRESTORE(`$1 = xc_get_class(processor, (zend_uint) $2);')
-		IFDASM(`add_assoc_stringl_ex(dst, ZEND_STRS("patsubst(`$1', `dst->')"), $2->name, strlen($2->name), 1);')
+		IFDASM(`add_assoc_stringl_ex(dst, ZEND_STRS("$3"), $2->name, strlen($2->name), 1);')
 	}
 	else {
-		COPYNULL_EX($1)
+		COPYNULL_EX(`$1', `$3')
 	}
 ')
@@ -132,11 +133,39 @@
 define(`SETNULL', `SETNULL_EX(`dst->$1')DONE(`$1')')
 dnl }}}
-dnl {{{ COPYNULL_EX
+dnl {{{ COPYNULL_EX(1:dst, 2:elm-name)
 define(`COPYNULL_EX', `
-	IFDASM(`add_assoc_null_ex(dst, ZEND_STRS("patsubst(`$1', `dst->')"));')
+	IFDASM(`add_assoc_null_ex(dst, ZEND_STRS("$2"));')
 	IFNOTMEMCPY(`IFCOPY(`$1 = NULL;')')
 ')
+dnl }}}
+dnl {{{ COPYNULL(1:elm)
+# foreach(VAR, (LIST), STMT)
+m4_define([foreach],
+       [m4_pushdef([$1])_foreach([$1], [$2], [$3])m4_popdef([$1])])
+m4_define([_arg1], [$1])
+m4_define([_foreach],
+       [ifelse([$2], [()], ,
+       [m4_define([$1], _arg1$2)$3[]_foreach([$1],
+                                                       (shift$2),
+                                                       [$3])])])
 define(`COPYNULL', `
-	COPYNULL_EX(`dst->$1')DONE(`$1')
+	COPYNULL_EX(`dst->$1', `$2')DONE(`$1')
+')
+dnl }}}
+dnl {{{ LIST_DIFF(1:left-list, 2:right-list)
+define(`foreach',
+       `pushdef(`$1')_foreach(`$1', `$2', `$3')popdef(`$1')')
+define(`_arg1', `$1')
+define(`_foreach',                             
+       `ifelse(`$2', `()', ,                       
+       `define(`$1', _arg1$2)$3`'_foreach(`$1',
+                                                       (shift$2),
+                                                       `$3')')')
+define(`LIST_DIFF', `dnl
+foreach(`i', `($1)', `pushdef(`item_'defn(`i'))')dnl allocate variable for items in $1 
+foreach(`i', `($2)', `pushdef(`item_'defn(`i'))undefine(`item_'defn(`i'))')dnl allocate variable for items in $2, and undefine it 
+foreach(`i', `($1)', `ifdef(`item_'defn(`i'), `defn(`i') ')')dnl see what is still defined
+foreach(`i', `($2)', `popdef(`item_'defn(`i'))')dnl
+foreach(`i', `($1)', `popdef(`item_'defn(`i'))')dnl
 ')
 dnl }}}
@@ -147,6 +176,5 @@
 ')')
 define(`DONE', `
-	dnl ifelse(regexp(defn(`ELEMENTS'), ` $1'), -1, m4_errprint(`Unknown $1') m4exit(1))
-	define(`ELEMENTS', patsubst(defn(`ELEMENTS'), ` $1\>'))
+	define(`ELEMENTS_DONE', defn(`ELEMENTS_DONE')`,$1')
 	DONE_SIZE(`sizeof(src->$1)')
 ')
@@ -186,24 +214,24 @@
 EXPORT(`zval')
 
-include(hashtable.m4)
-include(string.m4)
-include(struct.m4)
-include(dispatch.m4)
-include(head.m4)
+include(srcdir`/processor/hashtable.m4')
+include(srcdir`/processor/string.m4')
+include(srcdir`/processor/struct.m4')
+include(srcdir`/processor/dispatch.m4')
+include(srcdir`/processor/head.m4')
 
 define(`IFNOTMEMCPY', `ifdef(`USEMEMCPY', `', `$1')')
-REDEF(`KIND', `calc') include(processor.m4)
-REDEF(`KIND', `store') include(processor.m4)
-REDEF(`KIND', `restore') include(processor.m4)
+REDEF(`KIND', `calc') include(srcdir`/processor/processor.m4')
+REDEF(`KIND', `store') include(srcdir`/processor/processor.m4')
+REDEF(`KIND', `restore') include(srcdir`/processor/processor.m4')
 
 REDEF(`IFNOTMEMCPY', `$1')
 #ifdef HAVE_XCACHE_DPRINT
-REDEF(`KIND', `dprint') include(processor.m4)
+REDEF(`KIND', `dprint') include(srcdir`/processor/processor.m4')
 #endif /* HAVE_XCACHE_DPRINT */
 #ifdef HAVE_XCACHE_DISASSEMBLER
-REDEF(`KIND', `dasm') include(processor.m4)
+REDEF(`KIND', `dasm') include(srcdir`/processor/processor.m4')
 #endif /* HAVE_XCACHE_DISASSEMBLER */
 #ifdef HAVE_XCACHE_ASSEMBLER
-REDEF(`KIND', `asm') include(processor.m4)
+REDEF(`KIND', `asm') include(srcdir`/processor/processor.m4')
 #endif /* HAVE_XCACHE_ASSEMBLER */
 
Index: trunk/processor/processor.m4
===================================================================
--- trunk/processor/processor.m4	(revision 3)
+++ trunk/processor/processor.m4	(revision 4)
@@ -184,5 +184,5 @@
 				dnl fprintf(stderr, "copy from %p to %p\n", src[0], dst[0]);
 			')
-			STRUCT_P_EX(zval, dst[0], src[0], `', ` ')
+			STRUCT_P_EX(zval, dst[0], src[0], `[0]', `', ` ')
 		} while (0);
 	')
@@ -284,7 +284,8 @@
 		if (src->num_interfaces) {
 			CALLOC(dst->interfaces, zend_class_entry*, src->num_interfaces)
+			DONE(`interfaces')
 		}
 		else {
-			COPYNULL_EX(dst->interfaces)
+			COPYNULL(interfaces)
 		}
 	')
@@ -302,10 +303,15 @@
 			add_assoc_zval_ex(dst, ZEND_STRS("interfaces"), arr);
 			*/
+			DONE(`interfaces')
 		}
 		else {
-			COPYNULL_EX(dst->interfaces)
-		}
-	')
-	DONE(`interfaces')
+			COPYNULL(interfaces)
+		}
+	')
+	IFRESTORE(`', `
+		IFDASM(`', `
+			DONE(`interfaces')
+		')
+	')
 	DISPATCH(zend_uint, num_interfaces)
 
@@ -534,5 +540,5 @@
 	dnl zend_cv.m4 is illegal to be made public, don not ask me for it
 	IFDASM(`
-		sinclude(`zend_cv.m4')
+		sinclude(srcdir`/processor/zend_cv.m4')
 		')
 #endif
@@ -647,5 +653,5 @@
 		}
 	')
-	STRUCT_P_EX(zval_ptr, dst->value, src->value, `', `&')
+	STRUCT_P_EX(zval_ptr, dst->value, src->value, `value', `', `&')
 	DONE(value)
 ')
Index: trunk/processor/struct.m4
===================================================================
--- trunk/processor/struct.m4	(revision 3)
+++ trunk/processor/struct.m4	(revision 4)
@@ -3,5 +3,5 @@
 ')
 dnl {{{ DECL_STRUCT_P_FUNC(1:type, 2:name, 3:comma=;)
-define(`DECL_STRUCT_P_FUNC', `patsubst(
+define(`DECL_STRUCT_P_FUNC', `translit(
 	pushdefFUNC_NAME(`$1', `$2')
 	define(`DEFINED_'ifelse(`$2', `', `$1', `$2'), `')
@@ -17,6 +17,6 @@
 	)ifelse(`$3', `', `;')
 	popdef(`FUNC_NAME')dnl
-, `[
-	 ]+', ` ')')
+, `
+', ` ')')
 dnl }}}
 dnl {{{ DEF_STRUCT_P_FUNC(1:type, 2:name, 3:body)
@@ -35,7 +35,5 @@
 			int assert_size = SIZEOF_$1, assert_count = COUNTOF_$1;
 			int done_size = 0, done_count = 0;
-			ifdef(`ELEMENTSOF_$1', `
-				define(`ELEMENTS', defn(`ELEMENTSOF_$1'))
-			')
+			pushdef(`ELEMENTS_DONE')
 			/* }}} */
 			IFRESTORE(`assert(xc_is_shm(src));')
@@ -75,14 +73,18 @@
 				}
 				ifdef(`ELEMENTSOF_$1', `
-					ifelse(ELEMENTS, , , `
+					pushdef(`ELEMENTS_UNDONE', LIST_DIFF(defn(`ELEMENTSOF_$1'), defn(`ELEMENTS_DONE')))
+					ifelse(defn(`ELEMENTS_UNDONE'), , , `
 						m4_errprint(`====' KIND `$1 =================')
-						m4_errprint(`expected:' ELEMENTSOF_$1)
-						m4_errprint(`missing :' ELEMENTS)
+						m4_errprint(`expected:' defn(`ELEMENTSOF_$1'))
+						m4_errprint(`missing :' defn(`ELEMENTS_UNDONE'))
 						define(`EXIT_PENDING', 1)
 					')
+					popdef(`ELEMENTS_UNDONE')
 				')
-				undefine(`ELEMENTS')
 				/* }}} */
 		')')
+		IFASSERT(`
+			undefine(`ELEMENTS_DONE')
+		')
 	}
 /* }`}'} */
@@ -90,11 +92,11 @@
 ')
 dnl }}}
-dnl {{{ STRUCT_P_EX(1:type, 2:dst, 3:src, 4:name=type, 5:&)
+dnl {{{ STRUCT_P_EX(1:type, 2:dst, 3:src, 4:elm-name, 5:name=type, 6:&)
 define(`STRUCT_P_EX', `
 	DBG(`$0($*)')
-	pushdefFUNC_NAME(`$1', `$4')
-	ifdef(`DEFINED_'ifelse(`$4', `', `$1', `$4'), `', `m4_errprint(`Unknown struct "'ifelse(`$4', `', `$1', `$4')`"')')
-	assert(sizeof($1) == sizeof(($5 $3)[0]));
-	ifelse(`$5', `', `ALLOC(`$2', `$1')')
+	pushdefFUNC_NAME(`$1', `$5')
+	ifdef(`DEFINED_'ifelse(`$5', `', `$1', `$5'), `', `m4_errprint(`Unknown struct "'ifelse(`$5', `', `$1', `$5')`"')')
+	assert(sizeof($1) == sizeof(($6 $3)[0]));
+	ifelse(`$6', `', `ALLOC(`$2', `$1')')
 	IFDASM(`do {
 		zval *zv;
@@ -103,18 +105,18 @@
 	')
 	FUNC_NAME`'(
-		IFDPRINT( `           $5 $3, indent')
-		IFCALC(   `processor, $5 $3')
-		IFSTORE(  `processor, $5 $2, $5 $3')
-		IFRESTORE(`processor, $5 $2, $5 $3')
-		IFDASM(   `zv, $5 $3')
-		IFASM(    `$5 $2, $5 $3')
+		IFDPRINT( `           $6 $3, indent')
+		IFCALC(   `processor, $6 $3')
+		IFSTORE(  `processor, $6 $2, $6 $3')
+		IFRESTORE(`processor, $6 $2, $6 $3')
+		IFDASM(   `zv, $6 $3')
+		IFASM(    `$6 $2, $6 $3')
 		TSRMLS_CC
 	);
 	IFDASM(`
-		add_assoc_zval_ex(dst, ZEND_STRS("patsubst(`$2', `dst->')"), zv);
+		add_assoc_zval_ex(dst, ZEND_STRS("$4"), zv);
 	} while (0);
 	')
 	popdef(`FUNC_NAME')
-	ifelse(`$5', , `FIXPOINTER_EX(`$1', `$2')')
+	ifelse(`$6', , `FIXPOINTER_EX(`$1', `$2')')
 ')
 dnl }}}
@@ -123,9 +125,9 @@
 	DBG(`$0($*)')
 	if (src->$2) {
-		STRUCT_P_EX(`$1', `dst->$2', `src->$2', `$3')
+		STRUCT_P_EX(`$1', `dst->$2', `src->$2', `$2', `$3')
 		IFDPRINT(`INDENT()`'fprintf(stderr, "$1:$2");')
 	}
 	else {
-		COPYNULL_EX(dst->$2)
+		COPYNULL_EX(`dst->$2', `$2')
 		IFDPRINT(`INDENT()`'fprintf(stderr, "$1:$2:\tNULL\n");')
 	}
@@ -138,5 +140,5 @@
 	assert(sizeof($1) == sizeof(src->$2));
 	IFDPRINT(`INDENT()`'fprintf(stderr, "$1:$2");')
-	STRUCT_P_EX(`$1', `dst->$2', `src->$2', `$3', `&')
+	STRUCT_P_EX(`$1', `dst->$2', `src->$2', `$2', `$3', `&')
 	DONE(`$2')
 ')
