1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2008 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.57 2008/08/19 02:51:27 felipe 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 3120 : {
28 : zval **arg;
29 :
30 3120 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
31 2 : return;
32 : }
33 :
34 3118 : switch (Z_TYPE_PP(arg)) {
35 : case IS_NULL:
36 269 : RETVAL_ASCII_STRING("NULL", 1);
37 269 : break;
38 :
39 : case IS_BOOL:
40 309 : RETVAL_ASCII_STRING("boolean", 1);
41 309 : break;
42 :
43 : case IS_LONG:
44 377 : RETVAL_ASCII_STRING("integer", 1);
45 377 : break;
46 :
47 : case IS_DOUBLE:
48 504 : RETVAL_ASCII_STRING("double", 1);
49 504 : break;
50 :
51 : case IS_STRING:
52 220 : RETVAL_ASCII_STRING("string", 1);
53 220 : break;
54 :
55 : case IS_UNICODE:
56 1087 : RETVAL_ASCII_STRING("unicode", 1);
57 1087 : break;
58 :
59 : case IS_ARRAY:
60 196 : RETVAL_ASCII_STRING("array", 1);
61 196 : break;
62 :
63 : case IS_OBJECT:
64 150 : 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 150 : 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 : if (UG(unicode)) {
117 131 : convert_to_unicode(*var);
118 : } else {
119 0 : convert_to_string(*var);
120 : }
121 766 : } else if (!strcasecmp(new_type, "unicode")) { /* explicit unicode cast */
122 0 : convert_to_unicode(*var);
123 766 : } else if (!strcasecmp(new_type, "array")) {
124 131 : convert_to_array(*var);
125 635 : } else if (!strcasecmp(new_type, "object")) {
126 131 : convert_to_object(*var);
127 504 : } else if (!strcasecmp(new_type, "bool")) {
128 127 : convert_to_boolean(*var);
129 377 : } else if (!strcasecmp(new_type, "boolean")) {
130 125 : convert_to_boolean(*var);
131 252 : } else if (!strcasecmp(new_type, "null")) {
132 131 : convert_to_null(*var);
133 121 : } else if (!strcasecmp(new_type, "resource")) {
134 120 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot convert to resource type");
135 120 : RETURN_FALSE;
136 : } else {
137 1 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type");
138 1 : RETURN_FALSE;
139 : }
140 1252 : RETVAL_TRUE;
141 : }
142 : /* }}} */
143 :
144 : /* {{{ proto int intval(mixed var [, int base]) U
145 : Get the integer value of a variable using the optional base for the conversion */
146 : PHP_FUNCTION(intval)
147 3773 : {
148 : zval **num;
149 3773 : long arg_base = 0;
150 3773 : int base = 10;
151 :
152 3773 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|l", &num, &arg_base) == FAILURE) {
153 2 : return;
154 : }
155 :
156 3771 : if (ZEND_NUM_ARGS() == 2) {
157 54 : base = arg_base;
158 : }
159 :
160 3771 : RETVAL_ZVAL(*num, 1, 0);
161 3771 : convert_to_long_base(return_value, base);
162 : }
163 : /* }}} */
164 :
165 : /* {{{ proto float floatval(mixed var) U
166 : Get the float value of a variable */
167 : PHP_FUNCTION(floatval)
168 79 : {
169 : zval **num;
170 :
171 79 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &num) == FAILURE) {
172 4 : return;
173 : }
174 :
175 75 : RETVAL_ZVAL(*num, 1, 0);
176 75 : convert_to_double(return_value);
177 : }
178 : /* }}} */
179 :
180 : /* {{{ proto string strval(mixed var) U
181 : Get the string value of a variable */
182 : PHP_FUNCTION(strval)
183 100083 : {
184 : zval **num, *tmp;
185 : zval expr_copy;
186 : int use_copy;
187 :
188 100083 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &num) == FAILURE) {
189 2 : return;
190 : }
191 :
192 100081 : if (UG(unicode)) {
193 100081 : zend_make_unicode_zval(*num, &expr_copy, &use_copy);
194 : } else {
195 0 : zend_make_string_zval(*num, &expr_copy, &use_copy);
196 : }
197 100081 : if (use_copy) {
198 100058 : tmp = &expr_copy;
199 100058 : RETVAL_ZVAL(tmp, 0, 0);
200 : } else {
201 23 : RETVAL_ZVAL(*num, 1, 0);
202 : }
203 : }
204 : /* }}} */
205 :
206 : static void php_is_type(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
207 490999 : {
208 : zval *arg;
209 :
210 490999 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg) == FAILURE) {
211 20 : return;
212 : }
213 :
214 490979 : if (Z_TYPE_P(arg) == type) {
215 19721 : if (type == IS_OBJECT) {
216 : zend_class_entry *ce;
217 :
218 496 : if(Z_OBJ_HT_P(arg)->get_class_entry == NULL) {
219 : /* if there's no get_class_entry it's not a PHP object, so it can't be INCOMPLETE_CLASS */
220 0 : RETURN_TRUE;
221 : }
222 496 : ce = Z_OBJCE_P(arg);
223 :
224 496 : if (ce->name_length != sizeof(INCOMPLETE_CLASS) - 1) {
225 : /* We can get away with this because INCOMPLETE_CLASS is ascii and has a 1:1 relationship with unicode */
226 483 : RETURN_TRUE;
227 13 : } else if (UG(unicode)) {
228 : #ifndef PHP_WIN32
229 : U_STRING_DECL(uIncompleteClass, (INCOMPLETE_CLASS), sizeof(INCOMPLETE_CLASS) - 1);
230 13 : U_STRING_INIT(uIncompleteClass, (INCOMPLETE_CLASS), sizeof(INCOMPLETE_CLASS) - 1);
231 :
232 13 : if (!memcmp(ce->name.u, uIncompleteClass, UBYTES(sizeof(INCOMPLETE_CLASS)))) {
233 1 : RETURN_FALSE;
234 : }
235 : #else /* WIN32 -- U_STRING_DECL breaks under Win32 with string macros */
236 : char *ascii_name = zend_unicode_to_ascii(ce->name.u, ce->name_length TSRMLS_CC);
237 :
238 : if (ascii_name) {
239 : if (memcmp(INCOMPLETE_CLASS, ascii_name, sizeof(INCOMPLETE_CLASS) - 1) == 0) {
240 : efree(ascii_name);
241 : RETURN_FALSE;
242 : }
243 : efree(ascii_name);
244 : }
245 : /* Non-ascii class name means it can't be INCOMPLETE_CLASS and is therefore okay */
246 : #endif
247 : } else {
248 0 : if (!memcmp(ce->name.s, INCOMPLETE_CLASS, sizeof(INCOMPLETE_CLASS))) {
249 0 : RETURN_FALSE;
250 : }
251 : }
252 : }
253 19237 : if (type == IS_RESOURCE) {
254 : char *type_name;
255 83 : type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_P(arg) TSRMLS_CC);
256 83 : if (!type_name) {
257 1 : RETURN_FALSE;
258 : }
259 : }
260 19236 : RETURN_TRUE;
261 : } else {
262 471258 : RETURN_FALSE;
263 : }
264 : }
265 : /* }}} */
266 :
267 : /* {{{ proto bool is_null(mixed var) U
268 : Returns true if variable is null */
269 : PHP_FUNCTION(is_null)
270 12802 : {
271 12802 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_NULL);
272 12802 : }
273 : /* }}} */
274 :
275 : /* {{{ proto bool is_resource(mixed var) U
276 : Returns true if variable is a resource */
277 : PHP_FUNCTION(is_resource)
278 86 : {
279 86 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_RESOURCE);
280 86 : }
281 : /* }}} */
282 :
283 : /* {{{ proto bool is_bool(mixed var) U
284 : Returns true if variable is a boolean */
285 : PHP_FUNCTION(is_bool)
286 87 : {
287 87 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_BOOL);
288 87 : }
289 : /* }}} */
290 :
291 : /* {{{ proto bool is_long(mixed var) U
292 : Returns true if variable is a long (integer) */
293 : PHP_FUNCTION(is_long)
294 3268 : {
295 3268 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_LONG);
296 3268 : }
297 : /* }}} */
298 :
299 : /* {{{ proto bool is_float(mixed var) U
300 : Returns true if variable is float point*/
301 : PHP_FUNCTION(is_float)
302 372 : {
303 372 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_DOUBLE);
304 372 : }
305 : /* }}} */
306 :
307 : /* {{{ proto bool is_binary(mixed var) U
308 : Returns true if variable is a native (binary) string */
309 : PHP_FUNCTION(is_binary)
310 0 : {
311 0 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_STRING);
312 0 : }
313 : /* }}} */
314 :
315 : /* {{{ proto bool is_string(mixed var) U
316 : Returns true if variable is a Unicode or binary string */
317 : PHP_FUNCTION(is_string)
318 4525 : {
319 : zval *arg;
320 :
321 4525 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg) == FAILURE) {
322 2 : return;
323 : }
324 :
325 4523 : if (Z_TYPE_P(arg) == IS_UNICODE || Z_TYPE_P(arg) == IS_STRING) {
326 3744 : RETURN_TRUE;
327 : } else {
328 779 : RETURN_FALSE;
329 : }
330 : }
331 : /* }}} */
332 :
333 : /* {{{ proto bool is_unicode(mixed var) U
334 : Returns true if variable is a unicode string */
335 : PHP_FUNCTION(is_unicode)
336 0 : {
337 0 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_UNICODE);
338 0 : }
339 : /* }}} */
340 :
341 : /* {{{ proto bool is_buffer(mixed var) U
342 : Returns true if variable is a native, unicode or binary string */
343 : PHP_FUNCTION(is_buffer)
344 0 : {
345 : zval *arg;
346 :
347 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg) == FAILURE) {
348 0 : return;
349 : }
350 :
351 0 : if (Z_TYPE_P(arg) == IS_STRING || Z_TYPE_P(arg) == IS_UNICODE) {
352 0 : RETURN_TRUE;
353 : }
354 0 : RETURN_FALSE;
355 : }
356 : /* }}} */
357 :
358 : /* {{{ proto bool is_array(mixed var) U
359 : Returns true if variable is an array */
360 : PHP_FUNCTION(is_array)
361 473854 : {
362 473854 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_ARRAY);
363 473854 : }
364 : /* }}} */
365 :
366 : /* {{{ proto bool is_object(mixed var) U
367 : Returns true if variable is an object */
368 : PHP_FUNCTION(is_object)
369 530 : {
370 530 : php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_OBJECT);
371 530 : }
372 : /* }}} */
373 :
374 : /* {{{ proto bool is_numeric(mixed value) U
375 : Returns true if value is a number or a numeric string */
376 : PHP_FUNCTION(is_numeric)
377 109 : {
378 : zval **arg;
379 : int result;
380 :
381 109 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
382 2 : return;
383 : }
384 :
385 107 : switch (Z_TYPE_PP(arg)) {
386 : case IS_LONG:
387 : case IS_DOUBLE:
388 58 : RETURN_TRUE;
389 : break;
390 :
391 : case IS_STRING:
392 0 : result = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), NULL, NULL, 0);
393 0 : if (result == IS_LONG || result == IS_DOUBLE) {
394 0 : RETURN_TRUE;
395 : } else {
396 0 : RETURN_FALSE;
397 : }
398 : break;
399 :
400 : case IS_UNICODE:
401 36 : result = is_numeric_unicode(Z_USTRVAL_PP(arg), Z_USTRLEN_PP(arg), NULL, NULL, 0);
402 36 : if (result == IS_LONG || result == IS_DOUBLE) {
403 21 : RETURN_TRUE;
404 : } else {
405 15 : RETURN_FALSE;
406 : }
407 : break;
408 :
409 : default:
410 13 : RETURN_FALSE;
411 : break;
412 : }
413 : }
414 : /* }}} */
415 :
416 : /* {{{ proto bool is_scalar(mixed value) U
417 : Returns true if value is a scalar */
418 : PHP_FUNCTION(is_scalar)
419 62 : {
420 : zval **arg;
421 :
422 62 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
423 3 : return;
424 : }
425 :
426 59 : switch (Z_TYPE_PP(arg)) {
427 : case IS_BOOL:
428 : case IS_DOUBLE:
429 : case IS_LONG:
430 : case IS_STRING:
431 : case IS_UNICODE:
432 37 : RETURN_TRUE;
433 : break;
434 :
435 : default:
436 22 : RETURN_FALSE;
437 : break;
438 : }
439 : }
440 : /* }}} */
441 :
442 : /* {{{ proto bool is_callable(mixed var [, bool syntax_only [, string callable_name]]) U
443 : Returns true if var is callable. */
444 : PHP_FUNCTION(is_callable)
445 628 : {
446 : zval *var, **callable_name;
447 : zval name;
448 : zend_bool retval;
449 628 : zend_bool syntax_only = 0;
450 :
451 628 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|bZ", &var,
452 : &syntax_only, &callable_name) == FAILURE) {
453 2 : return;
454 : }
455 :
456 626 : syntax_only = syntax_only ? IS_CALLABLE_CHECK_SYNTAX_ONLY : 0;
457 626 : if (ZEND_NUM_ARGS() > 2) {
458 236 : retval = zend_is_callable(var, syntax_only, &name TSRMLS_CC);
459 236 : REPLACE_ZVAL_VALUE(callable_name, &name, 0);
460 : } else {
461 390 : retval = zend_is_callable(var, syntax_only, NULL TSRMLS_CC);
462 : }
463 :
464 626 : RETURN_BOOL(retval);
465 : }
466 : /* }}} */
467 :
468 : /*
469 : * Local variables:
470 : * tab-width: 4
471 : * c-basic-offset: 4
472 : * End:
473 : * vim600: sw=4 ts=4 fdm=marker
474 : * vim<600: sw=4 ts=4
475 : */
|