Back to index

php5  5.3.10
assert.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Author: Thies C. Arntzen <thies@thieso.net>                          |
00016    +----------------------------------------------------------------------+
00017 */
00018 
00019 /* $Id: assert.c 321634 2012-01-01 13:15:04Z felipe $ */
00020 
00021 /* {{{ includes */
00022 #include "php.h"
00023 #include "php_assert.h"
00024 #include "php_ini.h"
00025 /* }}} */
00026 
00027 ZEND_BEGIN_MODULE_GLOBALS(assert)
00028        long active;
00029        long bail;
00030        long warning;
00031        long quiet_eval;
00032        zval *callback;
00033        char *cb;
00034 ZEND_END_MODULE_GLOBALS(assert)
00035 
00036 ZEND_DECLARE_MODULE_GLOBALS(assert)
00037 
00038 #ifdef ZTS
00039 #define ASSERTG(v) TSRMG(assert_globals_id, zend_assert_globals *, v)
00040 #else
00041 #define ASSERTG(v) (assert_globals.v)
00042 #endif
00043 
00044 #define SAFE_STRING(s) ((s)?(s):"")
00045 
00046 enum {
00047        ASSERT_ACTIVE=1,
00048        ASSERT_CALLBACK,
00049        ASSERT_BAIL,
00050        ASSERT_WARNING,
00051        ASSERT_QUIET_EVAL
00052 };
00053 
00054 static PHP_INI_MH(OnChangeCallback) /* {{{ */
00055 {
00056        if (EG(in_execution)) {
00057               if (ASSERTG(callback)) {
00058                      zval_ptr_dtor(&ASSERTG(callback));
00059                      ASSERTG(callback) = NULL;
00060               }
00061               if (new_value && (ASSERTG(callback) || new_value_length)) {
00062                      MAKE_STD_ZVAL(ASSERTG(callback));
00063                      ZVAL_STRINGL(ASSERTG(callback), new_value, new_value_length, 1);
00064               }
00065        } else {
00066               if (ASSERTG(cb)) {
00067                      pefree(ASSERTG(cb), 1);
00068               }
00069               if (new_value && new_value_length) {
00070                      ASSERTG(cb) = pemalloc(new_value_length + 1, 1);
00071                      memcpy(ASSERTG(cb), new_value, new_value_length);
00072                      ASSERTG(cb)[new_value_length] = '\0';
00073               } else {
00074                      ASSERTG(cb) = NULL;
00075               }
00076        }
00077        return SUCCESS;
00078 }
00079 /* }}} */
00080 
00081 PHP_INI_BEGIN()
00082         STD_PHP_INI_ENTRY("assert.active",              "1",   PHP_INI_ALL,  OnUpdateLong,        active,                            zend_assert_globals,        assert_globals)
00083         STD_PHP_INI_ENTRY("assert.bail",         "0",   PHP_INI_ALL,  OnUpdateLong,        bail,                       zend_assert_globals,        assert_globals)
00084         STD_PHP_INI_ENTRY("assert.warning",      "1",   PHP_INI_ALL,  OnUpdateLong,        warning,                    zend_assert_globals,        assert_globals)
00085         PHP_INI_ENTRY("assert.callback",         NULL,  PHP_INI_ALL,  OnChangeCallback)
00086         STD_PHP_INI_ENTRY("assert.quiet_eval", "0",     PHP_INI_ALL,  OnUpdateLong,        quiet_eval,                 zend_assert_globals,        assert_globals)
00087 PHP_INI_END()
00088 
00089 static void php_assert_init_globals(zend_assert_globals *assert_globals_p TSRMLS_DC) /* {{{ */
00090 {
00091        assert_globals_p->callback = NULL;
00092        assert_globals_p->cb = NULL;
00093 }
00094 /* }}} */
00095 
00096 PHP_MINIT_FUNCTION(assert) /* {{{ */
00097 {
00098        ZEND_INIT_MODULE_GLOBALS(assert, php_assert_init_globals, NULL);
00099 
00100        REGISTER_INI_ENTRIES();
00101 
00102        REGISTER_LONG_CONSTANT("ASSERT_ACTIVE", ASSERT_ACTIVE, CONST_CS|CONST_PERSISTENT);
00103        REGISTER_LONG_CONSTANT("ASSERT_CALLBACK", ASSERT_CALLBACK, CONST_CS|CONST_PERSISTENT);
00104        REGISTER_LONG_CONSTANT("ASSERT_BAIL", ASSERT_BAIL, CONST_CS|CONST_PERSISTENT);
00105        REGISTER_LONG_CONSTANT("ASSERT_WARNING", ASSERT_WARNING, CONST_CS|CONST_PERSISTENT);
00106        REGISTER_LONG_CONSTANT("ASSERT_QUIET_EVAL", ASSERT_QUIET_EVAL, CONST_CS|CONST_PERSISTENT);
00107 
00108        return SUCCESS;
00109 }
00110 /* }}} */
00111 
00112 PHP_MSHUTDOWN_FUNCTION(assert) /* {{{ */
00113 {
00114        if (ASSERTG(cb)) {
00115               pefree(ASSERTG(cb), 1);
00116               ASSERTG(cb) = NULL;
00117        }
00118        return SUCCESS;
00119 }
00120 /* }}} */
00121 
00122 PHP_RSHUTDOWN_FUNCTION(assert) /* {{{ */
00123 {
00124        if (ASSERTG(callback)) {
00125               zval_ptr_dtor(&ASSERTG(callback));
00126               ASSERTG(callback) = NULL;
00127        }
00128 
00129        return SUCCESS;
00130 }
00131 /* }}} */
00132 
00133 PHP_MINFO_FUNCTION(assert) /* {{{ */
00134 {
00135        DISPLAY_INI_ENTRIES();
00136 }
00137 /* }}} */
00138 
00139 /* {{{ proto int assert(string|bool assertion)
00140    Checks if assertion is false */
00141 PHP_FUNCTION(assert)
00142 {
00143        zval **assertion;
00144        int val;
00145        char *myeval = NULL;
00146        char *compiled_string_description;
00147 
00148        if (! ASSERTG(active)) {
00149               RETURN_TRUE;
00150        }
00151 
00152        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &assertion) == FAILURE) {
00153               return;
00154        }
00155 
00156        if (Z_TYPE_PP(assertion) == IS_STRING) {
00157               zval retval;
00158               int old_error_reporting = 0; /* shut up gcc! */
00159 
00160               myeval = Z_STRVAL_PP(assertion);
00161 
00162               if (ASSERTG(quiet_eval)) {
00163                      old_error_reporting = EG(error_reporting);
00164                      EG(error_reporting) = 0;
00165               }
00166 
00167               compiled_string_description = zend_make_compiled_string_description("assert code" TSRMLS_CC);
00168               if (zend_eval_stringl(myeval, Z_STRLEN_PP(assertion), &retval, compiled_string_description TSRMLS_CC) == FAILURE) {
00169                      efree(compiled_string_description);
00170                      php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "Failure evaluating code: %s%s", PHP_EOL, myeval);
00171                      if (ASSERTG(bail)) {
00172                             zend_bailout();
00173                      }
00174                      RETURN_FALSE;
00175               }
00176               efree(compiled_string_description);
00177 
00178               if (ASSERTG(quiet_eval)) {
00179                      EG(error_reporting) = old_error_reporting;
00180               }
00181 
00182               convert_to_boolean(&retval);
00183               val = Z_LVAL(retval);
00184        } else {
00185               convert_to_boolean_ex(assertion);
00186               val = Z_LVAL_PP(assertion);
00187        }
00188 
00189        if (val) {
00190               RETURN_TRUE;
00191        }
00192 
00193        if (!ASSERTG(callback) && ASSERTG(cb)) {
00194               MAKE_STD_ZVAL(ASSERTG(callback));
00195               ZVAL_STRING(ASSERTG(callback), ASSERTG(cb), 1);
00196        }
00197 
00198        if (ASSERTG(callback)) {
00199               zval *args[3];
00200               zval *retval;
00201               int i;
00202               uint lineno = zend_get_executed_lineno(TSRMLS_C);
00203               char *filename = zend_get_executed_filename(TSRMLS_C);
00204 
00205               MAKE_STD_ZVAL(args[0]);
00206               MAKE_STD_ZVAL(args[1]);
00207               MAKE_STD_ZVAL(args[2]);
00208 
00209               ZVAL_STRING(args[0], SAFE_STRING(filename), 1);
00210               ZVAL_LONG (args[1], lineno);
00211               ZVAL_STRING(args[2], SAFE_STRING(myeval), 1);
00212 
00213               MAKE_STD_ZVAL(retval);
00214               ZVAL_FALSE(retval);
00215 
00216               /* XXX do we want to check for error here? */
00217               call_user_function(CG(function_table), NULL, ASSERTG(callback), retval, 3, args TSRMLS_CC);
00218 
00219               for (i = 0; i <= 2; i++) {
00220                      zval_ptr_dtor(&(args[i]));
00221               }
00222               zval_ptr_dtor(&retval);
00223        }
00224 
00225        if (ASSERTG(warning)) {
00226               if (myeval) {
00227                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Assertion \"%s\" failed", myeval);
00228               } else {
00229                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Assertion failed");
00230               }
00231        }
00232 
00233        if (ASSERTG(bail)) {
00234               zend_bailout();
00235        }
00236 }
00237 /* }}} */
00238 
00239 /* {{{ proto mixed assert_options(int what [, mixed value])
00240    Set/get the various assert flags */
00241 PHP_FUNCTION(assert_options)
00242 {
00243        zval **value = NULL;
00244        long what;
00245        int oldint;
00246        int ac = ZEND_NUM_ARGS();
00247 
00248        if (zend_parse_parameters(ac TSRMLS_CC, "l|Z", &what, &value) == FAILURE) {
00249               return;
00250        }
00251 
00252        switch (what) {
00253        case ASSERT_ACTIVE:
00254               oldint = ASSERTG(active);
00255               if (ac == 2) {
00256                      convert_to_string_ex(value);
00257                      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);
00258               }
00259               RETURN_LONG(oldint);
00260               break;
00261 
00262        case ASSERT_BAIL:
00263               oldint = ASSERTG(bail);
00264               if (ac == 2) {
00265                      convert_to_string_ex(value);
00266                      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);
00267               }
00268               RETURN_LONG(oldint);
00269               break;
00270 
00271        case ASSERT_QUIET_EVAL:
00272               oldint = ASSERTG(quiet_eval);
00273               if (ac == 2) {
00274                      convert_to_string_ex(value);
00275                      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);
00276               }
00277               RETURN_LONG(oldint);
00278               break;
00279 
00280        case ASSERT_WARNING:
00281               oldint = ASSERTG(warning);
00282               if (ac == 2) {
00283                      convert_to_string_ex(value);
00284                      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);
00285               }
00286               RETURN_LONG(oldint);
00287               break;
00288 
00289        case ASSERT_CALLBACK:
00290               if (ASSERTG(callback) != NULL) {
00291                      RETVAL_ZVAL(ASSERTG(callback), 1, 0);
00292               } else if (ASSERTG(cb)) {
00293                      RETVAL_STRING(ASSERTG(cb), 1);
00294               } else {
00295                      RETVAL_NULL();
00296               }
00297               if (ac == 2) {
00298                      if (ASSERTG(callback)) {
00299                             zval_ptr_dtor(&ASSERTG(callback));
00300                      }
00301                      ASSERTG(callback) = *value;
00302                      zval_add_ref(value);
00303               }
00304               return;
00305               break;
00306 
00307        default:
00308               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown value %ld", what);
00309               break;
00310        }
00311 
00312        RETURN_FALSE;
00313 }
00314 /* }}} */
00315 
00316 /*
00317  * Local variables:
00318  * tab-width: 4
00319  * c-basic-offset: 4
00320  * End:
00321  * vim600: sw=4 ts=4 fdm=marker
00322  * vim<600: sw=4 ts=4
00323  */