root/ext/standard/assert.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. PHP_INI_MH
  2. PHP_INI_BEGIN
  3. PHP_MINIT_FUNCTION
  4. PHP_MSHUTDOWN_FUNCTION
  5. PHP_RSHUTDOWN_FUNCTION
  6. PHP_MINFO_FUNCTION
  7. PHP_FUNCTION
  8. PHP_FUNCTION

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 5                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 The PHP Group                                |
   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 
  19 /* $Id$ */
  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 
 139 /* {{{ proto int assert(string|bool assertion[, string description])
 140    Checks if assertion is false */
 141 PHP_FUNCTION(assert)
 142 {
 143         zval **assertion;
 144         int val, description_len = 0;
 145         char *myeval = NULL;
 146         char *compiled_string_description, *description = NULL;
 147 
 148         if (! ASSERTG(active)) {
 149                 RETURN_TRUE;
 150         }
 151 
 152         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|s", &assertion, &description, &description_len) == FAILURE) {
 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);
 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                         }
 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)) {
 203                 zval **args = safe_emalloc(description_len == 0 ? 3 : 4, sizeof(zval *), 0);
 204                 zval *retval;
 205                 int i;
 206                 uint lineno = zend_get_executed_lineno(TSRMLS_C);
 207                 const char *filename = zend_get_executed_filename(TSRMLS_C);
 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? */
 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);
 229 
 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                         }
 234                 }
 235 
 236                 efree(args);
 237                 zval_ptr_dtor(&retval);
 238         }
 239 
 240         if (ASSERTG(warning)) {
 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                         }
 247                 } else {
 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                         }
 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  */
 347 

/* [<][>][^][v][top][bottom][index][help] */