1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 6 |
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: Rasmus Lerdorf <rasmus@php.net> |
16 : +----------------------------------------------------------------------+
17 : */
18 :
19 : /* $Id: type.c,v 1.62 2009/04/02 09:56:53 dmitry Exp $ */
20 :
21 : #include "php.h"
22 : #include "php_incomplete_class.h"
23 :
24 : /* {{{ proto string gettype(mixed var) U
25 : Returns the type of the variable */
26 : PHP_FUNCTION(gettype)
27 4298 : {
28 : zval **arg;
29 :
30 4298 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
31 2 : return;
32 : }
33 :
34 4296 : switch (Z_TYPE_PP(arg)) {
35 : case IS_NULL:
36 519 : RETVAL_ASCII_STRING("NULL", 1);
37 519 : break;
38 :
39 : case IS_BOOL:
40 332 : RETVAL_ASCII_STRING("boolean", 1);
41 332 : break;
42 :
43 : case IS_LONG:
44 503 : RETVAL_ASCII_STRING("integer", 1);
45 503 : break;
46 :
47 : case IS_DOUBLE:
48 528 : RETVAL_ASCII_STRING("double", 1);
49 528 : break;
50 :
51 : case IS_STRING:
52 304 : RETVAL_ASCII_STRING("string", 1);
53 304 : break;
54 :
55 : case IS_UNICODE:
56 1723 : RETVAL_ASCII_STRING("unicode", 1);
57 1723 : break;
58 :
59 : case IS_ARRAY:
60 230 : RETVAL_ASCII_STRING("array", 1);
61 230 : break;
62 :
63 : case IS_OBJECT:
64 151 : RETVAL_ASCII_STRING("object", 1);
65 : /*
66 : {
67 : char *result;
68 : int res_len;
69 :
70 : res_len = sizeof("object of type ")-1 + Z_OBJCE_P(arg)->name_length;
71 : spprintf(&result, 0, "object of type %s", Z_OBJCE_P(arg)->name);
72 : RETVAL_STRINGL(result, res_len, 0);
73 : }
74 : */
75 151 : break;
76 :
77 : case IS_RESOURCE:
78 : {
79 : char *type_name;
80 6 : type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(arg) TSRMLS_CC);
81 6 : if (type_name) {
82 5 : RETVAL_ASCII_STRING("resource", 1);
83 5 : break;
84 : }
85 : }
86 :
87 : default:
88 1 : RETVAL_ASCII_STRING("unknown type", 1);
89 : }
90 : }
91 : /* }}} */
92 :
93 : /* {{{ proto bool settype(mixed var, string type) U
94 : Set the type of the variable */
95 : PHP_FUNCTION(settype)
96 1375 : {
97 : zval **var;
98 : char *new_type;
99 : int new_type_len;
100 :
101 1375 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zs", &var, &new_type, &new_type_len) == FAILURE) {
102 2 : return;
103 : }
104 :
105 1373 : if (!strcasecmp(new_type, "integer")) {
106 118 : convert_to_long(*var);
107 1255 : } else if (!strcasecmp(new_type, "int")) {
108 120 : convert_to_long(*var);
109 1135 : } else if (!strcasecmp(new_type, "float")) {
110 107 : convert_to_double(*var);
111 1028 : } else if (!strcasecmp(new_type, "double")) { /* deprecated */
112 131 : convert_to_double(*var);
113 897 : } else if (!strcasecmp(new_type, "binary")) { /* explicit binary cast */
114 0 : convert_to_string(*var);
115 897 : } else if (!strcasecmp(new_type, "string")) { /* runtime string type */
116 131 : convert_to_unicode(*var);
117 766 : } else if (!strcasecmp(new_type, "unicode")) { /* explicit unicode cast */
118 0 : convert_to_unicode(*var);
119 766 : } else if (!strcasecmp(new_type, "array")) {
120 131 : convert_to_array(*var);
121 635 : } else if (!strcasecmp(new_type, "object")) {
122 131 : convert_to_object(*var);
123 504 : } else if (!strcasecmp(new_type, "bool")) {
124 127 : convert_to_boolean(*var);
125 377 : } else if (!strcasecmp(new_type, "boolean")) {
126 125 : convert_to_boolean(*var);
127 252 : } else if (!strcasecmp(new_type, "null")) {
128 131 : convert_to_null(*var);
129 121 : } else if (!strcasecmp(new_type, "resource")) {
130 120 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot convert to resource type");
131 120 : RETURN_FALSE;
132 : } else {
133 1 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type");
134 1 : RETURN_FALSE;
135 : }
136 1252 : RETVAL_TRUE;
137 : }
138 : /* }}} */
139 :
140 : /* {{{ proto int intval(mixed var [, int base]) U
141 : Get the integer value of a variable using the optional base for the conversion */
142 : PHP_FUNCTION(intval)
143 3831 : {
144 : zval **num;
145 3831 : long arg_base = 0;
146 3831 : int base = 10;
147 :
148 3831 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|l", &num, &arg_base) == FAILURE) {
149 14 : return;
150 : }
151 :
152 3817 : if (ZEND_NUM_ARGS() == 2) {
153 96 : base = arg_base;
154 : }
155 :
156 3817 : RETVAL_ZVAL(*num, 1, 0);
157 3817 : convert_to_long_base(return_value, base);
158 : }
159 : /* }}} */
160 :
161 : /* {{{ proto float floatval(mixed var) U
162 : Get the float value of a variable */
163 : PHP_FUNCTION(floatval)
164 153 : {
165 : zval **num;
166 :
167 153 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &num) == FAILURE) {
168 8 : return;
169 : }
170 :
171 145 : RETVAL_ZVAL(*num, 1, 0);
172 145 : convert_to_double(return_value);
173 : }
174 : /* }}} */
175 :
176 : /* {{{ proto string strval(mixed var) U
177 : Get the string value of a variable */
178 : PHP_FUNCTION(strval)
179 100148 : {
180 : zval **num, *tmp;
181 : zval expr_copy;
182 : int use_copy;
183 :
184 100148 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &num) == FAILURE) {
185 4 : return;
186 : }
187 :
188 100144 : zend_make_unicode_zval(*num, &expr_copy, &use_copy);
189 100143 : if (use_copy) {
190 100087 : tmp = &expr_copy;
191 100087 : RETVAL_ZVAL(tmp, 0, 0);
192 : } else {
193 56 : RETVAL_ZVAL(*num, 1, 0);
194 : }
195 : }
196 : /* }}} */
197 :
198 : static void php_is_type(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
199 690777 : {
200 : zval *arg;
201 :
202 690777 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg) == FAILURE) {
203 20 : return;
204 : }
205 :
206 690757 : if (Z_TYPE_P(arg) == type) {
207 26489 : if (type == IS_OBJECT) {
208 : zend_class_entry *ce;
209 :
210 759 : if(Z_OBJ_HT_P(arg)->get_class_entry == NULL) {
211 : /* if there's no get_class_entry it's not a PHP object, so it can't be INCOMPLETE_CLASS */
212 0 : RETURN_TRUE;
213 : }
214 759 : ce = Z_OBJCE_P(arg);
215 :
216 759 : if (ce->name_length != sizeof(INCOMPLETE_CLASS) - 1) {
217 : /* We can get away with this because INCOMPLETE_CLASS is ascii and has a 1:1 relationship with unicode */
218 746 : RETURN_TRUE;
219 : } else {
220 : #ifndef PHP_WIN32
221 : U_STRING_DECL(uIncompleteClass, (INCOMPLETE_CLASS), sizeof(INCOMPLETE_CLASS) - 1);
222 13 : U_STRING_INIT(uIncompleteClass, (INCOMPLETE_CLASS), sizeof(INCOMPLETE_CLASS) - 1);
223 :
224 13 : if (!memcmp(ce->name.u, uIncompleteClass, UBYTES(sizeof(INCOMPLETE_CLASS)))) {
225 1 : RETURN_FALSE;
226 : }
227 : #else /* WIN32 -- U_STRING_DECL breaks under Win32 with string macros */
228 : char *ascii_name = zend_unicode_to_ascii(ce->name.u, ce->name_length TSRMLS_CC);
229 :
230 : if (ascii_name) {
231 : if (memcmp(INCOMPLETE_CLASS, ascii_name, sizeof(INCOMPLETE_CLASS) - 1) == 0) {
232 : efree(ascii_name);
233 : RETURN_FALSE;
234 : }
235 : efree(ascii_name);
236 : }
237 : /* Non-ascii class name means it can't be INCOMPLETE_CLASS and is therefore okay */
238 : #endif
239 : }
240 : }
241 25742 : if (type == IS_RESOURCE) {
242 : char *type_name;
243 86 : type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_P(arg) TSRMLS_CC);
244 86 : if (!type_name) {
245 1 : RETURN_FALSE;
246 : }
247 : }
248 25741 : RETURN_TRUE;
249 : } else {
250 664268 : RETURN_FALSE;
251 : }
252 : }
253 : /* }}} */
254 :
255 : /* {{{ proto bool is_null(mixed var) U
256 : Returns true if variable is null */
257 : PHP_FUNCTION(is_null)
258 17303 : {
259 17303 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_NULL);
260 17303 : }
261 : /* }}} */
262 :
263 : /* {{{ proto bool is_resource(mixed var) U
264 : Returns true if variable is a resource */
265 : PHP_FUNCTION(is_resource)
266 89 : {
267 89 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_RESOURCE);
268 89 : }
269 : /* }}} */
270 :
271 : /* {{{ proto bool is_bool(mixed var) U
272 : Returns true if variable is a boolean */
273 : PHP_FUNCTION(is_bool)
274 595 : {
275 595 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_BOOL);
276 595 : }
277 : /* }}} */
278 :
279 : /* {{{ proto bool is_long(mixed var) U
280 : Returns true if variable is a long (integer) */
281 : PHP_FUNCTION(is_long)
282 3511 : {
283 3511 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_LONG);
284 3511 : }
285 : /* }}} */
286 :
287 : /* {{{ proto bool is_float(mixed var) U
288 : Returns true if variable is float point*/
289 : PHP_FUNCTION(is_float)
290 372 : {
291 372 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_DOUBLE);
292 372 : }
293 : /* }}} */
294 :
295 : /* {{{ proto bool is_binary(mixed var) U
296 : Returns true if variable is a native (binary) string */
297 : PHP_FUNCTION(is_binary)
298 0 : {
299 0 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_STRING);
300 0 : }
301 : /* }}} */
302 :
303 : /* {{{ proto bool is_string(mixed var) U
304 : Returns true if variable is a Unicode or binary string */
305 : PHP_FUNCTION(is_string)
306 4894 : {
307 : zval *arg;
308 :
309 4894 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg) == FAILURE) {
310 2 : return;
311 : }
312 :
313 4892 : if (Z_TYPE_P(arg) == IS_UNICODE || Z_TYPE_P(arg) == IS_STRING) {
314 4004 : RETURN_TRUE;
315 : } else {
316 888 : RETURN_FALSE;
317 : }
318 : }
319 : /* }}} */
320 :
321 : /* {{{ proto bool is_unicode(mixed var) U
322 : Returns true if variable is a unicode string */
323 : PHP_FUNCTION(is_unicode)
324 5 : {
325 5 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_UNICODE);
326 5 : }
327 : /* }}} */
328 :
329 : /* {{{ proto bool is_buffer(mixed var) U
330 : Returns true if variable is a native, unicode or binary string */
331 : PHP_FUNCTION(is_buffer)
332 0 : {
333 : zval *arg;
334 :
335 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg) == FAILURE) {
336 0 : return;
337 : }
338 :
339 0 : if (Z_TYPE_P(arg) == IS_STRING || Z_TYPE_P(arg) == IS_UNICODE) {
340 0 : RETURN_TRUE;
341 : }
342 0 : RETURN_FALSE;
343 : }
344 : /* }}} */
345 :
346 : /* {{{ proto bool is_array(mixed var) U
347 : Returns true if variable is an array */
348 : PHP_FUNCTION(is_array)
349 668109 : {
350 668109 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_ARRAY);
351 668109 : }
352 : /* }}} */
353 :
354 : /* {{{ proto bool is_object(mixed var) U
355 : Returns true if variable is an object */
356 : PHP_FUNCTION(is_object)
357 793 : {
358 793 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_OBJECT);
359 793 : }
360 : /* }}} */
361 :
362 : /* {{{ proto bool is_numeric(mixed value) U
363 : Returns true if value is a number or a numeric string */
364 : PHP_FUNCTION(is_numeric)
365 109 : {
366 : zval **arg;
367 : int result;
368 :
369 109 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
370 2 : return;
371 : }
372 :
373 107 : switch (Z_TYPE_PP(arg)) {
374 : case IS_LONG:
375 : case IS_DOUBLE:
376 58 : RETURN_TRUE;
377 : break;
378 :
379 : case IS_STRING:
380 0 : result = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), NULL, NULL, 0);
381 0 : if (result == IS_LONG || result == IS_DOUBLE) {
382 0 : RETURN_TRUE;
383 : } else {
384 0 : RETURN_FALSE;
385 : }
386 : break;
387 :
388 : case IS_UNICODE:
389 36 : result = is_numeric_unicode(Z_USTRVAL_PP(arg), Z_USTRLEN_PP(arg), NULL, NULL, 0);
390 36 : if (result == IS_LONG || result == IS_DOUBLE) {
391 21 : RETURN_TRUE;
392 : } else {
393 15 : RETURN_FALSE;
394 : }
395 : break;
396 :
397 : default:
398 13 : RETURN_FALSE;
399 : break;
400 : }
401 : }
402 : /* }}} */
403 :
404 : /* {{{ proto bool is_scalar(mixed value) U
405 : Returns true if value is a scalar */
406 : PHP_FUNCTION(is_scalar)
407 62 : {
408 : zval **arg;
409 :
410 62 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
411 3 : return;
412 : }
413 :
414 59 : switch (Z_TYPE_PP(arg)) {
415 : case IS_BOOL:
416 : case IS_DOUBLE:
417 : case IS_LONG:
418 : case IS_STRING:
419 : case IS_UNICODE:
420 37 : RETURN_TRUE;
421 : break;
422 :
423 : default:
424 22 : RETURN_FALSE;
425 : break;
426 : }
427 : }
428 : /* }}} */
429 :
430 : /* {{{ proto bool is_callable(mixed var [, bool syntax_only [, string callable_name]]) U
431 : Returns true if var is callable. */
432 : PHP_FUNCTION(is_callable)
433 630 : {
434 630 : zval *var, **callable_name = NULL;
435 : zval name;
436 : char *error;
437 : zend_bool retval;
438 630 : zend_bool syntax_only = 0;
439 630 : int check_flags = 0;
440 :
441 630 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|bZ", &var,
442 : &syntax_only, &callable_name) == FAILURE) {
443 2 : return;
444 : }
445 :
446 628 : if (syntax_only) {
447 233 : check_flags |= IS_CALLABLE_CHECK_SYNTAX_ONLY;
448 : }
449 628 : if (ZEND_NUM_ARGS() > 2) {
450 236 : retval = zend_is_callable_ex(var, NULL, check_flags, &name, NULL, &error TSRMLS_CC);
451 236 : REPLACE_ZVAL_VALUE(callable_name, &name, 0);
452 : } else {
453 392 : retval = zend_is_callable_ex(var, NULL, check_flags, NULL, NULL, &error TSRMLS_CC);
454 : }
455 628 : if (error) {
456 : /* ignore errors */
457 369 : efree(error);
458 : }
459 :
460 628 : RETURN_BOOL(retval);
461 : }
462 : /* }}} */
463 :
464 : /*
465 : * Local variables:
466 : * tab-width: 4
467 : * c-basic-offset: 4
468 : * End:
469 : * vim600: sw=4 ts=4 fdm=marker
470 : * vim<600: sw=4 ts=4
471 : */
|