From fcf92e7e17a52d2e5c6c48b96c6138473d64e47d Mon Sep 17 00:00:00 2001 From: Marcus Boerger Date: Sun, 4 May 2003 19:24:24 +0000 Subject: [PATCH] Modify the abstract error message so that it shows up to three methods not implemented. # The solution is generic so that we could change the number of methods shown. But the #problem is that error message here have a maximum length of 1024 chars. --- Zend/zend_execute.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 3a9d6c9a50..bed9bd8a97 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -4039,13 +4039,47 @@ int zend_verify_instanceof_handler(ZEND_OPCODE_HANDLER_ARGS) } +#define MAX_ABSTRACT_INFO_CNT 3 +#define MAX_ABSTRACT_INFO_FMT "%s%s%s%s" + +#define DISPLAY_ABSTRACT_FN(idx) \ + ai.afn[idx] ? ZEND_FN_SCOPE_NAME(ai.afn[idx]) : "", \ + ai.afn[idx] ? "::" : "", \ + ai.afn[idx] ? ai.afn[idx]->common.function_name : "", \ + ai.afn[idx] && ai.afn[idx+1] ? ", " : (ai.afn[idx] && ai.cnt >= MAX_ABSTRACT_INFO_CNT ? ", ..." : "") + +typedef struct _zend_abstract_info { + zend_function *afn[MAX_ABSTRACT_INFO_CNT+1]; + int cnt; +} zend_abstract_info; + +int zend_verify_abstract_class_function(zend_function *fn, zend_abstract_info *ai TSRMLS_DC) +{ + if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) { + if (ai->cnt < MAX_ABSTRACT_INFO_CNT) { + ai->afn[ai->cnt] = fn; + } + ai->cnt++; + } + return 0; +} + int zend_verify_abstract_class(ZEND_OPCODE_HANDLER_ARGS) { zend_class_entry *ce = EX_T(EX(opline)->op1.u.var).EA.class_entry; + zend_abstract_info ai; - if ((ce->ce_flags & ZEND_ACC_ABSTRACT) - && !(ce->ce_flags & ZEND_ACC_ABSTRACT_CLASS)) { - zend_error(E_ERROR, "Class %s contains abstract methods and must be declared abstract", ce->name); + if ((ce->ce_flags & ZEND_ACC_ABSTRACT) && !(ce->ce_flags & ZEND_ACC_ABSTRACT_CLASS)) { + memset(&ai, 0, sizeof(ai)); + + zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t) zend_verify_abstract_class_function, &ai TSRMLS_CC); + + zend_error(E_ERROR, "Class %s contains %d abstract methods and must therefore be declared abstract (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")", + ce->name, ai.cnt, + DISPLAY_ABSTRACT_FN(0), + DISPLAY_ABSTRACT_FN(1), + DISPLAY_ABSTRACT_FN(2) + ); } NEXT_OPCODE(); -- 2.40.0