Annotation of embedaddon/php/ext/standard/assert.c, revision 1.1.1.3

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
1.1.1.3 ! misho       5:    | Copyright (c) 1997-2013 The PHP Group                                |
1.1       misho       6:    +----------------------------------------------------------------------+
                      7:    | This source file is subject to version 3.01 of the PHP license,      |
                      8:    | that is bundled with this package in the file LICENSE, and is        |
                      9:    | available through the world-wide-web at the following url:           |
                     10:    | http://www.php.net/license/3_01.txt                                  |
                     11:    | If you did not receive a copy of the PHP license and are unable to   |
                     12:    | obtain it through the world-wide-web, please send a note to          |
                     13:    | license@php.net so we can mail you a copy immediately.               |
                     14:    +----------------------------------------------------------------------+
                     15:    | Author: Thies C. Arntzen <thies@thieso.net>                          |
                     16:    +----------------------------------------------------------------------+
                     17: */
                     18: 
1.1.1.2   misho      19: /* $Id$ */
1.1       misho      20: 
                     21: /* {{{ includes */
                     22: #include "php.h"
                     23: #include "php_assert.h"
                     24: #include "php_ini.h"
                     25: /* }}} */
                     26: 
                     27: ZEND_BEGIN_MODULE_GLOBALS(assert)
                     28:        long active;
                     29:        long bail;
                     30:        long warning;
                     31:        long quiet_eval;
                     32:        zval *callback;
                     33:        char *cb;
                     34: ZEND_END_MODULE_GLOBALS(assert)
                     35: 
                     36: ZEND_DECLARE_MODULE_GLOBALS(assert)
                     37: 
                     38: #ifdef ZTS
                     39: #define ASSERTG(v) TSRMG(assert_globals_id, zend_assert_globals *, v)
                     40: #else
                     41: #define ASSERTG(v) (assert_globals.v)
                     42: #endif
                     43: 
                     44: #define SAFE_STRING(s) ((s)?(s):"")
                     45: 
                     46: enum {
                     47:        ASSERT_ACTIVE=1,
                     48:        ASSERT_CALLBACK,
                     49:        ASSERT_BAIL,
                     50:        ASSERT_WARNING,
                     51:        ASSERT_QUIET_EVAL
                     52: };
                     53: 
                     54: static PHP_INI_MH(OnChangeCallback) /* {{{ */
                     55: {
                     56:        if (EG(in_execution)) {
                     57:                if (ASSERTG(callback)) {
                     58:                        zval_ptr_dtor(&ASSERTG(callback));
                     59:                        ASSERTG(callback) = NULL;
                     60:                }
                     61:                if (new_value && (ASSERTG(callback) || new_value_length)) {
                     62:                        MAKE_STD_ZVAL(ASSERTG(callback));
                     63:                        ZVAL_STRINGL(ASSERTG(callback), new_value, new_value_length, 1);
                     64:                }
                     65:        } else {
                     66:                if (ASSERTG(cb)) {
                     67:                        pefree(ASSERTG(cb), 1);
                     68:                }
                     69:                if (new_value && new_value_length) {
                     70:                        ASSERTG(cb) = pemalloc(new_value_length + 1, 1);
                     71:                        memcpy(ASSERTG(cb), new_value, new_value_length);
                     72:                        ASSERTG(cb)[new_value_length] = '\0';
                     73:                } else {
                     74:                        ASSERTG(cb) = NULL;
                     75:                }
                     76:        }
                     77:        return SUCCESS;
                     78: }
                     79: /* }}} */
                     80: 
                     81: PHP_INI_BEGIN()
                     82:         STD_PHP_INI_ENTRY("assert.active",             "1",    PHP_INI_ALL,    OnUpdateLong,           active,                         zend_assert_globals,            assert_globals)
                     83:         STD_PHP_INI_ENTRY("assert.bail",               "0",    PHP_INI_ALL,    OnUpdateLong,           bail,                           zend_assert_globals,            assert_globals)
                     84:         STD_PHP_INI_ENTRY("assert.warning",    "1",    PHP_INI_ALL,    OnUpdateLong,           warning,                        zend_assert_globals,            assert_globals)
                     85:         PHP_INI_ENTRY("assert.callback",               NULL,   PHP_INI_ALL,    OnChangeCallback)
                     86:         STD_PHP_INI_ENTRY("assert.quiet_eval", "0",    PHP_INI_ALL,    OnUpdateLong,           quiet_eval,                     zend_assert_globals,            assert_globals)
                     87: PHP_INI_END()
                     88: 
                     89: static void php_assert_init_globals(zend_assert_globals *assert_globals_p TSRMLS_DC) /* {{{ */
                     90: {
                     91:        assert_globals_p->callback = NULL;
                     92:        assert_globals_p->cb = NULL;
                     93: }
                     94: /* }}} */
                     95: 
                     96: PHP_MINIT_FUNCTION(assert) /* {{{ */
                     97: {
                     98:        ZEND_INIT_MODULE_GLOBALS(assert, php_assert_init_globals, NULL);
                     99: 
                    100:        REGISTER_INI_ENTRIES();
                    101: 
                    102:        REGISTER_LONG_CONSTANT("ASSERT_ACTIVE", ASSERT_ACTIVE, CONST_CS|CONST_PERSISTENT);
                    103:        REGISTER_LONG_CONSTANT("ASSERT_CALLBACK", ASSERT_CALLBACK, CONST_CS|CONST_PERSISTENT);
                    104:        REGISTER_LONG_CONSTANT("ASSERT_BAIL", ASSERT_BAIL, CONST_CS|CONST_PERSISTENT);
                    105:        REGISTER_LONG_CONSTANT("ASSERT_WARNING", ASSERT_WARNING, CONST_CS|CONST_PERSISTENT);
                    106:        REGISTER_LONG_CONSTANT("ASSERT_QUIET_EVAL", ASSERT_QUIET_EVAL, CONST_CS|CONST_PERSISTENT);
                    107: 
                    108:        return SUCCESS;
                    109: }
                    110: /* }}} */
                    111: 
                    112: PHP_MSHUTDOWN_FUNCTION(assert) /* {{{ */
                    113: {
                    114:        if (ASSERTG(cb)) {
                    115:                pefree(ASSERTG(cb), 1);
                    116:                ASSERTG(cb) = NULL;
                    117:        }
                    118:        return SUCCESS;
                    119: }
                    120: /* }}} */
                    121: 
                    122: PHP_RSHUTDOWN_FUNCTION(assert) /* {{{ */
                    123: {
                    124:        if (ASSERTG(callback)) {
                    125:                zval_ptr_dtor(&ASSERTG(callback));
                    126:                ASSERTG(callback) = NULL;
                    127:        }
                    128: 
                    129:        return SUCCESS;
                    130: }
                    131: /* }}} */
                    132: 
                    133: PHP_MINFO_FUNCTION(assert) /* {{{ */
                    134: {
                    135:        DISPLAY_INI_ENTRIES();
                    136: }
                    137: /* }}} */
                    138: 
1.1.1.3 ! misho     139: /* {{{ proto int assert(string|bool assertion[, string description])
1.1       misho     140:    Checks if assertion is false */
                    141: PHP_FUNCTION(assert)
                    142: {
                    143:        zval **assertion;
1.1.1.3 ! misho     144:        int val, description_len = 0;
1.1       misho     145:        char *myeval = NULL;
1.1.1.3 ! misho     146:        char *compiled_string_description, *description = NULL;
1.1       misho     147: 
                    148:        if (! ASSERTG(active)) {
                    149:                RETURN_TRUE;
                    150:        }
                    151: 
1.1.1.3 ! misho     152:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|s", &assertion, &description, &description_len) == FAILURE) {
1.1       misho     153:                return;
                    154:        }
                    155: 
                    156:        if (Z_TYPE_PP(assertion) == IS_STRING) {
                    157:                zval retval;
                    158:                int old_error_reporting = 0; /* shut up gcc! */
                    159: 
                    160:                myeval = Z_STRVAL_PP(assertion);
                    161: 
                    162:                if (ASSERTG(quiet_eval)) {
                    163:                        old_error_reporting = EG(error_reporting);
                    164:                        EG(error_reporting) = 0;
                    165:                }
                    166: 
                    167:                compiled_string_description = zend_make_compiled_string_description("assert code" TSRMLS_CC);
                    168:                if (zend_eval_stringl(myeval, Z_STRLEN_PP(assertion), &retval, compiled_string_description TSRMLS_CC) == FAILURE) {
                    169:                        efree(compiled_string_description);
1.1.1.3 ! misho     170:                        if (description_len == 0) {
        !           171:                                php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "Failure evaluating code: %s%s", PHP_EOL, myeval);
        !           172:                        } else {
        !           173:                                php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "Failure evaluating code: %s%s:\"%s\"", PHP_EOL, description, myeval);
        !           174:                        }
1.1       misho     175:                        if (ASSERTG(bail)) {
                    176:                                zend_bailout();
                    177:                        }
                    178:                        RETURN_FALSE;
                    179:                }
                    180:                efree(compiled_string_description);
                    181: 
                    182:                if (ASSERTG(quiet_eval)) {
                    183:                        EG(error_reporting) = old_error_reporting;
                    184:                }
                    185: 
                    186:                convert_to_boolean(&retval);
                    187:                val = Z_LVAL(retval);
                    188:        } else {
                    189:                convert_to_boolean_ex(assertion);
                    190:                val = Z_LVAL_PP(assertion);
                    191:        }
                    192: 
                    193:        if (val) {
                    194:                RETURN_TRUE;
                    195:        }
                    196: 
                    197:        if (!ASSERTG(callback) && ASSERTG(cb)) {
                    198:                MAKE_STD_ZVAL(ASSERTG(callback));
                    199:                ZVAL_STRING(ASSERTG(callback), ASSERTG(cb), 1);
                    200:        }
                    201: 
                    202:        if (ASSERTG(callback)) {
1.1.1.3 ! misho     203:                zval **args = safe_emalloc(description_len == 0 ? 3 : 4, sizeof(zval **), 0);
1.1       misho     204:                zval *retval;
                    205:                int i;
                    206:                uint lineno = zend_get_executed_lineno(TSRMLS_C);
1.1.1.2   misho     207:                const char *filename = zend_get_executed_filename(TSRMLS_C);
1.1       misho     208: 
                    209:                MAKE_STD_ZVAL(args[0]);
                    210:                MAKE_STD_ZVAL(args[1]);
                    211:                MAKE_STD_ZVAL(args[2]);
                    212: 
                    213:                ZVAL_STRING(args[0], SAFE_STRING(filename), 1);
                    214:                ZVAL_LONG (args[1], lineno);
                    215:                ZVAL_STRING(args[2], SAFE_STRING(myeval), 1);
                    216: 
                    217:                MAKE_STD_ZVAL(retval);
                    218:                ZVAL_FALSE(retval);
                    219: 
                    220:                /* XXX do we want to check for error here? */
1.1.1.3 ! misho     221:                if (description_len == 0) {
        !           222:                        call_user_function(CG(function_table), NULL, ASSERTG(callback), retval, 3, args TSRMLS_CC);
        !           223:                        for (i = 0; i <= 2; i++) {
        !           224:                                zval_ptr_dtor(&(args[i]));
        !           225:                        }
        !           226:                } else {
        !           227:                        MAKE_STD_ZVAL(args[3]);
        !           228:                        ZVAL_STRINGL(args[3], SAFE_STRING(description), description_len, 1);
1.1       misho     229: 
1.1.1.3 ! misho     230:                        call_user_function(CG(function_table), NULL, ASSERTG(callback), retval, 4, args TSRMLS_CC);
        !           231:                        for (i = 0; i <= 3; i++) {
        !           232:                                zval_ptr_dtor(&(args[i]));
        !           233:                        }
1.1       misho     234:                }
1.1.1.3 ! misho     235: 
        !           236:                efree(args);
1.1       misho     237:                zval_ptr_dtor(&retval);
                    238:        }
                    239: 
                    240:        if (ASSERTG(warning)) {
1.1.1.3 ! misho     241:                if (description_len == 0) {
        !           242:                        if (myeval) {
        !           243:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Assertion \"%s\" failed", myeval);
        !           244:                        } else {
        !           245:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Assertion failed");
        !           246:                        }
1.1       misho     247:                } else {
1.1.1.3 ! misho     248:                        if (myeval) {
        !           249:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: \"%s\" failed", description, myeval);
        !           250:                        } else {
        !           251:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s failed", description);
        !           252:                        }
1.1       misho     253:                }
                    254:        }
                    255: 
                    256:        if (ASSERTG(bail)) {
                    257:                zend_bailout();
                    258:        }
                    259: }
                    260: /* }}} */
                    261: 
                    262: /* {{{ proto mixed assert_options(int what [, mixed value])
                    263:    Set/get the various assert flags */
                    264: PHP_FUNCTION(assert_options)
                    265: {
                    266:        zval **value = NULL;
                    267:        long what;
                    268:        int oldint;
                    269:        int ac = ZEND_NUM_ARGS();
                    270: 
                    271:        if (zend_parse_parameters(ac TSRMLS_CC, "l|Z", &what, &value) == FAILURE) {
                    272:                return;
                    273:        }
                    274: 
                    275:        switch (what) {
                    276:        case ASSERT_ACTIVE:
                    277:                oldint = ASSERTG(active);
                    278:                if (ac == 2) {
                    279:                        convert_to_string_ex(value);
                    280:                        zend_alter_ini_entry_ex("assert.active", sizeof("assert.active"), Z_STRVAL_PP(value), Z_STRLEN_PP(value), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC);
                    281:                }
                    282:                RETURN_LONG(oldint);
                    283:                break;
                    284: 
                    285:        case ASSERT_BAIL:
                    286:                oldint = ASSERTG(bail);
                    287:                if (ac == 2) {
                    288:                        convert_to_string_ex(value);
                    289:                        zend_alter_ini_entry_ex("assert.bail", sizeof("assert.bail"), Z_STRVAL_PP(value), Z_STRLEN_PP(value), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC);
                    290:                }
                    291:                RETURN_LONG(oldint);
                    292:                break;
                    293: 
                    294:        case ASSERT_QUIET_EVAL:
                    295:                oldint = ASSERTG(quiet_eval);
                    296:                if (ac == 2) {
                    297:                        convert_to_string_ex(value);
                    298:                        zend_alter_ini_entry_ex("assert.quiet_eval", sizeof("assert.quiet_eval"), Z_STRVAL_PP(value), Z_STRLEN_PP(value), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC);
                    299:                }
                    300:                RETURN_LONG(oldint);
                    301:                break;
                    302: 
                    303:        case ASSERT_WARNING:
                    304:                oldint = ASSERTG(warning);
                    305:                if (ac == 2) {
                    306:                        convert_to_string_ex(value);
                    307:                        zend_alter_ini_entry_ex("assert.warning", sizeof("assert.warning"), Z_STRVAL_PP(value), Z_STRLEN_PP(value), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC);
                    308:                }
                    309:                RETURN_LONG(oldint);
                    310:                break;
                    311: 
                    312:        case ASSERT_CALLBACK:
                    313:                if (ASSERTG(callback) != NULL) {
                    314:                        RETVAL_ZVAL(ASSERTG(callback), 1, 0);
                    315:                } else if (ASSERTG(cb)) {
                    316:                        RETVAL_STRING(ASSERTG(cb), 1);
                    317:                } else {
                    318:                        RETVAL_NULL();
                    319:                }
                    320:                if (ac == 2) {
                    321:                        if (ASSERTG(callback)) {
                    322:                                zval_ptr_dtor(&ASSERTG(callback));
                    323:                        }
                    324:                        ASSERTG(callback) = *value;
                    325:                        zval_add_ref(value);
                    326:                }
                    327:                return;
                    328:                break;
                    329: 
                    330:        default:
                    331:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown value %ld", what);
                    332:                break;
                    333:        }
                    334: 
                    335:        RETURN_FALSE;
                    336: }
                    337: /* }}} */
                    338: 
                    339: /*
                    340:  * Local variables:
                    341:  * tab-width: 4
                    342:  * c-basic-offset: 4
                    343:  * End:
                    344:  * vim600: sw=4 ts=4 fdm=marker
                    345:  * vim<600: sw=4 ts=4
                    346:  */
1.1.1.3 ! misho     347: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>