You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

323 lines
7.9 KiB

24 years ago
27 years ago
27 years ago
27 years ago
26 years ago
27 years ago
27 years ago
27 years ago
27 years ago
25 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
27 years ago
26 years ago
26 years ago
27 years ago
27 years ago
27 years ago
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2009 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. /* $Id$ */
  19. /* {{{ includes */
  20. #include "php.h"
  21. #include "php_assert.h"
  22. #include "php_ini.h"
  23. /* }}} */
  24. ZEND_BEGIN_MODULE_GLOBALS(assert)
  25. long active;
  26. long bail;
  27. long warning;
  28. long quiet_eval;
  29. zval *callback;
  30. char *cb;
  31. ZEND_END_MODULE_GLOBALS(assert)
  32. ZEND_DECLARE_MODULE_GLOBALS(assert)
  33. #ifdef ZTS
  34. #define ASSERTG(v) TSRMG(assert_globals_id, zend_assert_globals *, v)
  35. #else
  36. #define ASSERTG(v) (assert_globals.v)
  37. #endif
  38. #define SAFE_STRING(s) ((s)?(s):"")
  39. enum {
  40. ASSERT_ACTIVE=1,
  41. ASSERT_CALLBACK,
  42. ASSERT_BAIL,
  43. ASSERT_WARNING,
  44. ASSERT_QUIET_EVAL
  45. };
  46. static PHP_INI_MH(OnChangeCallback) /* {{{ */
  47. {
  48. if (EG(in_execution)) {
  49. if (ASSERTG(callback)) {
  50. zval_ptr_dtor(&ASSERTG(callback));
  51. ASSERTG(callback) = NULL;
  52. }
  53. if (new_value && (ASSERTG(callback) || new_value_length)) {
  54. MAKE_STD_ZVAL(ASSERTG(callback));
  55. ZVAL_STRINGL(ASSERTG(callback), new_value, new_value_length, 1);
  56. }
  57. } else {
  58. if (ASSERTG(cb)) {
  59. pefree(ASSERTG(cb), 1);
  60. }
  61. if (new_value && new_value_length) {
  62. ASSERTG(cb) = pemalloc(new_value_length + 1, 1);
  63. memcpy(ASSERTG(cb), new_value, new_value_length);
  64. ASSERTG(cb)[new_value_length] = '\0';
  65. } else {
  66. ASSERTG(cb) = NULL;
  67. }
  68. }
  69. return SUCCESS;
  70. }
  71. /* }}} */
  72. PHP_INI_BEGIN()
  73. STD_PHP_INI_ENTRY("assert.active", "1", PHP_INI_ALL, OnUpdateLong, active, zend_assert_globals, assert_globals)
  74. STD_PHP_INI_ENTRY("assert.bail", "0", PHP_INI_ALL, OnUpdateLong, bail, zend_assert_globals, assert_globals)
  75. STD_PHP_INI_ENTRY("assert.warning", "1", PHP_INI_ALL, OnUpdateLong, warning, zend_assert_globals, assert_globals)
  76. PHP_INI_ENTRY("assert.callback", NULL, PHP_INI_ALL, OnChangeCallback)
  77. STD_PHP_INI_ENTRY("assert.quiet_eval", "0", PHP_INI_ALL, OnUpdateLong, quiet_eval, zend_assert_globals, assert_globals)
  78. PHP_INI_END()
  79. static void php_assert_init_globals(zend_assert_globals *assert_globals_p TSRMLS_DC) /* {{{ */
  80. {
  81. assert_globals_p->callback = NULL;
  82. assert_globals_p->cb = NULL;
  83. }
  84. /* }}} */
  85. PHP_MINIT_FUNCTION(assert) /* {{{ */
  86. {
  87. ZEND_INIT_MODULE_GLOBALS(assert, php_assert_init_globals, NULL);
  88. REGISTER_INI_ENTRIES();
  89. REGISTER_LONG_CONSTANT("ASSERT_ACTIVE", ASSERT_ACTIVE, CONST_CS|CONST_PERSISTENT);
  90. REGISTER_LONG_CONSTANT("ASSERT_CALLBACK", ASSERT_CALLBACK, CONST_CS|CONST_PERSISTENT);
  91. REGISTER_LONG_CONSTANT("ASSERT_BAIL", ASSERT_BAIL, CONST_CS|CONST_PERSISTENT);
  92. REGISTER_LONG_CONSTANT("ASSERT_WARNING", ASSERT_WARNING, CONST_CS|CONST_PERSISTENT);
  93. REGISTER_LONG_CONSTANT("ASSERT_QUIET_EVAL", ASSERT_QUIET_EVAL, CONST_CS|CONST_PERSISTENT);
  94. return SUCCESS;
  95. }
  96. /* }}} */
  97. PHP_MSHUTDOWN_FUNCTION(assert) /* {{{ */
  98. {
  99. if (ASSERTG(cb)) {
  100. pefree(ASSERTG(cb), 1);
  101. ASSERTG(cb) = NULL;
  102. }
  103. return SUCCESS;
  104. }
  105. /* }}} */
  106. PHP_RSHUTDOWN_FUNCTION(assert) /* {{{ */
  107. {
  108. if (ASSERTG(callback)) {
  109. zval_ptr_dtor(&ASSERTG(callback));
  110. ASSERTG(callback) = NULL;
  111. }
  112. return SUCCESS;
  113. }
  114. /* }}} */
  115. PHP_MINFO_FUNCTION(assert) /* {{{ */
  116. {
  117. DISPLAY_INI_ENTRIES();
  118. }
  119. /* }}} */
  120. /* {{{ proto int assert(string|bool assertion)
  121. Checks if assertion is false */
  122. PHP_FUNCTION(assert)
  123. {
  124. zval **assertion;
  125. int val;
  126. char *myeval = NULL;
  127. char *compiled_string_description;
  128. if (! ASSERTG(active)) {
  129. RETURN_TRUE;
  130. }
  131. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &assertion) == FAILURE) {
  132. return;
  133. }
  134. if (Z_TYPE_PP(assertion) == IS_STRING) {
  135. zval retval;
  136. int old_error_reporting = 0; /* shut up gcc! */
  137. myeval = Z_STRVAL_PP(assertion);
  138. if (ASSERTG(quiet_eval)) {
  139. old_error_reporting = EG(error_reporting);
  140. EG(error_reporting) = 0;
  141. }
  142. compiled_string_description = zend_make_compiled_string_description("assert code" TSRMLS_CC);
  143. if (zend_eval_stringl(myeval, Z_STRLEN_PP(assertion), &retval, compiled_string_description TSRMLS_CC) == FAILURE) {
  144. efree(compiled_string_description);
  145. php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "Failure evaluating code: %s%s", PHP_EOL, myeval);
  146. if (ASSERTG(bail)) {
  147. zend_bailout();
  148. }
  149. RETURN_FALSE;
  150. }
  151. efree(compiled_string_description);
  152. if (ASSERTG(quiet_eval)) {
  153. EG(error_reporting) = old_error_reporting;
  154. }
  155. convert_to_boolean(&retval);
  156. val = Z_LVAL(retval);
  157. } else {
  158. convert_to_boolean_ex(assertion);
  159. val = Z_LVAL_PP(assertion);
  160. }
  161. if (val) {
  162. RETURN_TRUE;
  163. }
  164. if (!ASSERTG(callback) && ASSERTG(cb)) {
  165. MAKE_STD_ZVAL(ASSERTG(callback));
  166. ZVAL_STRING(ASSERTG(callback), ASSERTG(cb), 1);
  167. }
  168. if (ASSERTG(callback)) {
  169. zval *args[3];
  170. zval *retval;
  171. int i;
  172. uint lineno = zend_get_executed_lineno(TSRMLS_C);
  173. char *filename = zend_get_executed_filename(TSRMLS_C);
  174. MAKE_STD_ZVAL(args[0]);
  175. MAKE_STD_ZVAL(args[1]);
  176. MAKE_STD_ZVAL(args[2]);
  177. ZVAL_STRING(args[0], SAFE_STRING(filename), 1);
  178. ZVAL_LONG (args[1], lineno);
  179. ZVAL_STRING(args[2], SAFE_STRING(myeval), 1);
  180. MAKE_STD_ZVAL(retval);
  181. ZVAL_FALSE(retval);
  182. /* XXX do we want to check for error here? */
  183. call_user_function(CG(function_table), NULL, ASSERTG(callback), retval, 3, args TSRMLS_CC);
  184. for (i = 0; i <= 2; i++) {
  185. zval_ptr_dtor(&(args[i]));
  186. }
  187. zval_ptr_dtor(&retval);
  188. }
  189. if (ASSERTG(warning)) {
  190. if (myeval) {
  191. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Assertion \"%s\" failed", myeval);
  192. } else {
  193. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Assertion failed");
  194. }
  195. }
  196. if (ASSERTG(bail)) {
  197. zend_bailout();
  198. }
  199. }
  200. /* }}} */
  201. /* {{{ proto mixed assert_options(int what [, mixed value])
  202. Set/get the various assert flags */
  203. PHP_FUNCTION(assert_options)
  204. {
  205. zval **value = NULL;
  206. long what;
  207. int oldint;
  208. int ac = ZEND_NUM_ARGS();
  209. if (zend_parse_parameters(ac TSRMLS_CC, "l|Z", &what, &value) == FAILURE) {
  210. return;
  211. }
  212. switch (what) {
  213. case ASSERT_ACTIVE:
  214. oldint = ASSERTG(active);
  215. if (ac == 2) {
  216. convert_to_long_ex(value);
  217. ASSERTG(active) = Z_LVAL_PP(value);
  218. }
  219. RETURN_LONG(oldint);
  220. break;
  221. case ASSERT_BAIL:
  222. oldint = ASSERTG(bail);
  223. if (ac == 2) {
  224. convert_to_long_ex(value);
  225. ASSERTG(bail) = Z_LVAL_PP(value);
  226. }
  227. RETURN_LONG(oldint);
  228. break;
  229. case ASSERT_QUIET_EVAL:
  230. oldint = ASSERTG(quiet_eval);
  231. if (ac == 2) {
  232. convert_to_long_ex(value);
  233. ASSERTG(quiet_eval) = Z_LVAL_PP(value);
  234. }
  235. RETURN_LONG(oldint);
  236. break;
  237. case ASSERT_WARNING:
  238. oldint = ASSERTG(warning);
  239. if (ac == 2) {
  240. convert_to_long_ex(value);
  241. ASSERTG(warning) = Z_LVAL_PP(value);
  242. }
  243. RETURN_LONG(oldint);
  244. break;
  245. case ASSERT_CALLBACK:
  246. if (ASSERTG(callback) != NULL) {
  247. RETVAL_ZVAL(ASSERTG(callback), 1, 0);
  248. } else if (ASSERTG(cb)) {
  249. RETVAL_STRING(ASSERTG(cb), 1);
  250. } else {
  251. RETVAL_NULL();
  252. }
  253. if (ac == 2) {
  254. if (ASSERTG(callback)) {
  255. zval_ptr_dtor(&ASSERTG(callback));
  256. }
  257. ASSERTG(callback) = *value;
  258. zval_add_ref(value);
  259. }
  260. return;
  261. break;
  262. default:
  263. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown value %ld", what);
  264. break;
  265. }
  266. RETURN_FALSE;
  267. }
  268. /* }}} */
  269. /*
  270. * Local variables:
  271. * tab-width: 4
  272. * c-basic-offset: 4
  273. * End:
  274. * vim600: sw=4 ts=4 fdm=marker
  275. * vim<600: sw=4 ts=4
  276. */