Browse Source

runtime check for field list assertion to tell which is mismatch

git-svn-id: svn://svn.lighttpd.net/xcache/trunk@719 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
3.0
Xuefer 11 years ago
parent
commit
369b9eabbb
  1. 4
      mkstructinfo.awk
  2. 43
      processor/head.m4
  3. 17
      processor/main.m4
  4. 25
      processor/struct.m4

4
mkstructinfo.awk

@ -49,10 +49,10 @@ incomment {
sizeinfo = sizeinfo "sizeof(((" instruct "*)NULL)->" buffer[i] ")";
if (i == 0) {
elms = buffer[i];
elms = "\"" buffer[i] "\"";
}
else {
elms = elms "," buffer[i];
elms = elms "," "\"" buffer[i] "\"";
}
}
printf "define(`ELEMENTSOF_%s', `%s')\n", instruct, elms;

43
processor/head.m4

@ -305,6 +305,49 @@ static void xc_zend_extension_op_array_ctor_handler(zend_extension *extension, z
}
}
/* }}} */
/* {{{ field name checker */
IFASSERT(`dnl
int xc_check_names(const char *file, int line, const char *functionName, const char **assert_names, int assert_names_count, HashTable *done_names)
{
int errors = 0;
if (assert_names_count) {
int i;
Bucket *b;
for (i = 0; i < assert_names_count; ++i) {
if (!zend_hash_exists(done_names, assert_names[i], strlen(assert_names[i]) + 1)) {
fprintf(stderr
, "missing field at %s `#'%d %s`' : %s\n"
, file, line, functionName
, assert_names[i]
);
++errors;
}
}
for (b = done_names->pListHead; b != NULL; b = b->pListNext) {
int known = 0;
int i;
for (i = 0; i < assert_names_count; ++i) {
if (strcmp(assert_names[i], BUCKET_KEY_S(b)) == 0) {
known = 1;
break;
}
}
if (!known) {
fprintf(stderr
, "unknown field at %s `#'%d %s`' : %s\n"
, file, line, functionName
, BUCKET_KEY_S(b)
);
++errors;
}
}
}
return errors;
}
')
/* }}} */
dnl ================ export API
define(`DEFINE_STORE_API', `
/* export: $1 *xc_processor_store_$1($1 *src TSRMLS_DC); :export {{{ */

17
processor/main.m4

@ -205,12 +205,25 @@ foreach(`i', `($1)', `popdef(`item_'defn(`i'))')dnl
')
dnl }}}
dnl {{{ DONE_*
define(`DONE_SIZE', `IFASSERT(`
define(`DONE_SIZE', `IFASSERT(`dnl
done_size += $1`';
done_count ++;
')')
define(`DONE', `
define(`ELEMENTS_DONE', defn(`ELEMENTS_DONE')`,$1')
define(`ELEMENTS_DONE', defn(`ELEMENTS_DONE')`,"$1"')
IFASSERT(`dnl
if (zend_hash_exists(&done_names, "$1", sizeof("$1"))) {
fprintf(stderr
, "duplicate field at %s `#'%d FUNC_NAME`' : %s\n"
, __FILE__, __LINE__
, "$1"
);
}
else {
zend_uchar b = 1;
zend_hash_add(&done_names, "$1", sizeof("$1"), (void*)&b, sizeof(b), NULL);
}
')
DONE_SIZE(`sizeof(src->$1)')
')
define(`DISABLECHECK', `

25
processor/struct.m4

@ -29,11 +29,10 @@ define(`DEF_STRUCT_P_FUNC', `
DECL_STRUCT_P_FUNC(`$1', `$2', 1)
{
pushdef(`ELEMENTS_DONE')
ifdef(`SIZEOF_$1', , `m4_errprint(`AUTOCHECK WARN: $1: missing structinfo, dont panic')define(`SIZEOF_$1', 0)')
IFASSERT(`
/* {{{ init assert */
ifdef(`SIZEOF_$1', , `m4_errprint(`missing SIZEOF_$1, safe to ignore')define(`SIZEOF_$1', 0)')
ifdef(`COUNTOF_$1', , `m4_errprint(`missing COUNTOF_$1, safe to ignore')define(`COUNTOF_$1', 0)')
ifdef(`SIZEOF_$1', , `m4_errprint(`missing SIZEOF_$1, safe to ignore')')
ifdef(`COUNTOF_$1', , `m4_errprint(`missing COUNTOF_$1, safe to ignore'))')
dnl SIZEOF_x COUNTOF_x can be both defined or both not
ifdef(`SIZEOF_$1', `
ifdef(`COUNTOF_$1', , `m4_errprint(`AUTOCHECK WARN: missing COUNTOF_$1')')
@ -47,11 +46,15 @@ DECL_STRUCT_P_FUNC(`$1', `$2', 1)
')
int assert_size = SIZEOF_$1, assert_count = COUNTOF_$1;
int done_size = 0, done_count = 0;
const char *assert_names[] = { ifdef(`ELEMENTSOF_$1', `ELEMENTSOF_$1') };
HashTable done_names;
zend_hash_init(&done_names, 0, NULL, NULL, 0);
/* }}} */
IFRESTORE(`assert(xc_is_shm(src));')
IFCALCSTORE(`assert(!xc_is_shm(src));')
do {
')
ifdef(`SIZEOF_$1', , `m4_errprint(`AUTOCHECK WARN: $1: missing structinfo, dont panic')')
ifdef(`USEMEMCPY', `IFCOPY(`
memcpy(dst, src, sizeof($1));
@ -67,9 +70,17 @@ DECL_STRUCT_P_FUNC(`$1', `$2', 1)
indent --;
INDENT()fprintf(stderr, "}\n");
')
ifdef(`SKIPASSERT_ONCE', `undefine(`SKIPASSERT_ONCE')', `
ifdef(`SKIPASSERT_ONCE', `
undefine(`SKIPASSERT_ONCE')
IFASSERT(`
/* {{{ check assert */
zend_hash_destroy(&done_names);
')
', `
IFASSERT(`
/* {{{ check assert */ do {
int name_check_errors = xc_check_names(__FILE__, __LINE__, "FUNC_NAME", assert_names, sizeof(assert_names) / sizeof(assert_names[0]), &done_names);
zend_hash_destroy(&done_names);
if (done_count != assert_count) {
fprintf(stderr
, "count assertion failed at %s `#'%d FUNC_NAME`' : unexpected:%d - expecting:%d = %d != 0\n"
@ -84,10 +95,10 @@ DECL_STRUCT_P_FUNC(`$1', `$2', 1)
, done_size, assert_size, done_size - assert_size
);
}
if (done_count != assert_count || done_size != assert_size) {
if (name_check_errors || done_count != assert_count || done_size != assert_size) {
assert(0);
}
/* }}} */
} while (0); /* }}} */
')
ifdef(`ELEMENTSOF_$1', `
pushdef(`ELEMENTS_UNDONE', LIST_DIFF(defn(`ELEMENTSOF_$1'), defn(`ELEMENTS_DONE')))

Loading…
Cancel
Save