1/*
2   +----------------------------------------------------------------------+
3   | PHP Version 5                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 1997-2013 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$ */
20
21#include "php.h"
22#include "php_incomplete_class.h"
23
24/* {{{ proto string gettype(mixed var)
25   Returns the type of the variable */
26PHP_FUNCTION(gettype)
27{
28    zval **arg;
29
30    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
31        return;
32    }
33
34    switch (Z_TYPE_PP(arg)) {
35        case IS_NULL:
36            RETVAL_STRING("NULL", 1);
37            break;
38
39        case IS_BOOL:
40            RETVAL_STRING("boolean", 1);
41            break;
42
43        case IS_LONG:
44            RETVAL_STRING("integer", 1);
45            break;
46
47        case IS_DOUBLE:
48            RETVAL_STRING("double", 1);
49            break;
50
51        case IS_STRING:
52            RETVAL_STRING("string", 1);
53            break;
54
55        case IS_ARRAY:
56            RETVAL_STRING("array", 1);
57            break;
58
59        case IS_OBJECT:
60            RETVAL_STRING("object", 1);
61        /*
62           {
63           char *result;
64           int res_len;
65
66           res_len = sizeof("object of type ")-1 + Z_OBJCE_P(arg)->name_length;
67           spprintf(&result, 0, "object of type %s", Z_OBJCE_P(arg)->name);
68           RETVAL_STRINGL(result, res_len, 0);
69           }
70         */
71            break;
72
73        case IS_RESOURCE:
74            {
75                const char *type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(arg) TSRMLS_CC);
76
77                if (type_name) {
78                    RETVAL_STRING("resource", 1);
79                    break;
80                }
81            }
82
83        default:
84            RETVAL_STRING("unknown type", 1);
85    }
86}
87/* }}} */
88
89/* {{{ proto bool settype(mixed var, string type)
90   Set the type of the variable */
91PHP_FUNCTION(settype)
92{
93    zval **var;
94    char *type;
95    int type_len = 0;
96
97    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zs", &var, &type, &type_len) == FAILURE) {
98        return;
99    }
100
101    if (!strcasecmp(type, "integer")) {
102        convert_to_long(*var);
103    } else if (!strcasecmp(type, "int")) {
104        convert_to_long(*var);
105    } else if (!strcasecmp(type, "float")) {
106        convert_to_double(*var);
107    } else if (!strcasecmp(type, "double")) { /* deprecated */
108        convert_to_double(*var);
109    } else if (!strcasecmp(type, "string")) {
110        convert_to_string(*var);
111    } else if (!strcasecmp(type, "array")) {
112        convert_to_array(*var);
113    } else if (!strcasecmp(type, "object")) {
114        convert_to_object(*var);
115    } else if (!strcasecmp(type, "bool")) {
116        convert_to_boolean(*var);
117    } else if (!strcasecmp(type, "boolean")) {
118        convert_to_boolean(*var);
119    } else if (!strcasecmp(type, "null")) {
120        convert_to_null(*var);
121    } else if (!strcasecmp(type, "resource")) {
122        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot convert to resource type");
123        RETURN_FALSE;
124    } else {
125        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type");
126        RETURN_FALSE;
127    }
128    RETVAL_TRUE;
129}
130/* }}} */
131
132/* {{{ proto int intval(mixed var [, int base])
133   Get the integer value of a variable using the optional base for the conversion */
134PHP_FUNCTION(intval)
135{
136    zval **num;
137    long arg_base;
138    int base;
139
140    switch (ZEND_NUM_ARGS()) {
141        case 1:
142            if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &num) == FAILURE) {
143                return;
144            }
145            base = 10;
146            break;
147
148        case 2:
149            if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zl", &num, &arg_base) == FAILURE) {
150                return;
151            }
152            base = arg_base;
153            break;
154
155        default:
156            WRONG_PARAM_COUNT;
157    }
158
159    RETVAL_ZVAL(*num, 1, 0);
160    convert_to_long_base(return_value, base);
161}
162/* }}} */
163
164/* {{{ proto float floatval(mixed var)
165   Get the float value of a variable */
166PHP_FUNCTION(floatval)
167{
168    zval **num;
169
170    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &num) == FAILURE) {
171        return;
172    }
173
174    RETVAL_ZVAL(*num, 1, 0);
175    convert_to_double(return_value);
176}
177/* }}} */
178
179/* {{{ proto string strval(mixed var)
180   Get the string value of a variable */
181PHP_FUNCTION(strval)
182{
183    zval **num, *tmp;
184    zval expr_copy;
185    int use_copy;
186
187    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &num) == FAILURE) {
188        return;
189    }
190
191    zend_make_printable_zval(*num, &expr_copy, &use_copy);
192    if (use_copy) {
193        tmp = &expr_copy;
194        RETVAL_ZVAL(tmp, 0, 0);
195    } else {
196        RETVAL_ZVAL(*num, 1, 0);
197    }
198}
199/* }}} */
200
201static void php_is_type(INTERNAL_FUNCTION_PARAMETERS, int type)
202{
203    zval **arg;
204
205    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
206        RETURN_FALSE;
207    }
208
209    if (Z_TYPE_PP(arg) == type) {
210        if (type == IS_OBJECT) {
211            zend_class_entry *ce;
212            if(Z_OBJ_HT_PP(arg)->get_class_entry == NULL) {
213            /* if there's no get_class_entry it's not a PHP object, so it can't be INCOMPLETE_CLASS */
214                RETURN_TRUE;
215            }
216            ce = Z_OBJCE_PP(arg);
217            if (!strcmp(ce->name, INCOMPLETE_CLASS)) {
218                RETURN_FALSE;
219            }
220        }
221        if (type == IS_RESOURCE) {
222            const char *type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(arg) TSRMLS_CC);
223            if (!type_name) {
224                RETURN_FALSE;
225            }
226        }
227        RETURN_TRUE;
228    } else {
229        RETURN_FALSE;
230    }
231}
232
233
234/* {{{ proto bool is_null(mixed var)
235   Returns true if variable is null */
236PHP_FUNCTION(is_null)
237{
238    php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_NULL);
239}
240/* }}} */
241
242/* {{{ proto bool is_resource(mixed var)
243   Returns true if variable is a resource */
244PHP_FUNCTION(is_resource)
245{
246    php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_RESOURCE);
247}
248/* }}} */
249
250/* {{{ proto bool is_bool(mixed var)
251   Returns true if variable is a boolean */
252PHP_FUNCTION(is_bool)
253{
254    php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_BOOL);
255}
256/* }}} */
257
258/* {{{ proto bool is_long(mixed var)
259   Returns true if variable is a long (integer) */
260PHP_FUNCTION(is_long)
261{
262    php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_LONG);
263}
264/* }}} */
265
266/* {{{ proto bool is_float(mixed var)
267   Returns true if variable is float point*/
268PHP_FUNCTION(is_float)
269{
270    php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_DOUBLE);
271}
272/* }}} */
273
274/* {{{ proto bool is_string(mixed var)
275   Returns true if variable is a string */
276PHP_FUNCTION(is_string)
277{
278    php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_STRING);
279}
280/* }}} */
281
282/* {{{ proto bool is_array(mixed var)
283   Returns true if variable is an array */
284PHP_FUNCTION(is_array)
285{
286    php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_ARRAY);
287}
288/* }}} */
289
290/* {{{ proto bool is_object(mixed var)
291   Returns true if variable is an object */
292PHP_FUNCTION(is_object)
293{
294    php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_OBJECT);
295}
296/* }}} */
297
298/* {{{ proto bool is_numeric(mixed value)
299   Returns true if value is a number or a numeric string */
300PHP_FUNCTION(is_numeric)
301{
302    zval **arg;
303
304    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
305        return;
306    }
307
308    switch (Z_TYPE_PP(arg)) {
309        case IS_LONG:
310        case IS_DOUBLE:
311            RETURN_TRUE;
312            break;
313
314        case IS_STRING:
315            if (is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), NULL, NULL, 0)) {
316                RETURN_TRUE;
317            } else {
318                RETURN_FALSE;
319            }
320            break;
321
322        default:
323            RETURN_FALSE;
324            break;
325    }
326}
327/* }}} */
328
329/* {{{ proto bool is_scalar(mixed value)
330   Returns true if value is a scalar */
331PHP_FUNCTION(is_scalar)
332{
333    zval **arg;
334
335    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
336        return;
337    }
338
339    switch (Z_TYPE_PP(arg)) {
340        case IS_BOOL:
341        case IS_DOUBLE:
342        case IS_LONG:
343        case IS_STRING:
344            RETURN_TRUE;
345            break;
346
347        default:
348            RETURN_FALSE;
349            break;
350    }
351}
352/* }}} */
353
354/* {{{ proto bool is_callable(mixed var [, bool syntax_only [, string callable_name]])
355   Returns true if var is callable. */
356PHP_FUNCTION(is_callable)
357{
358    zval *var, **callable_name = NULL;
359    char *name;
360    char *error;
361    zend_bool retval;
362    zend_bool syntax_only = 0;
363    int check_flags = 0;
364
365    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|bZ", &var,
366                              &syntax_only, &callable_name) == FAILURE) {
367        return;
368    }
369
370    if (syntax_only) {
371        check_flags |= IS_CALLABLE_CHECK_SYNTAX_ONLY;
372    }
373    if (ZEND_NUM_ARGS() > 2) {
374        retval = zend_is_callable_ex(var, NULL, check_flags, &name, NULL, NULL, &error TSRMLS_CC);
375        zval_dtor(*callable_name);
376        ZVAL_STRING(*callable_name, name, 0);
377    } else {
378        retval = zend_is_callable_ex(var, NULL, check_flags, NULL, NULL, NULL, &error TSRMLS_CC);
379    }
380    if (error) {
381        /* ignore errors */
382        efree(error);
383    }
384
385    RETURN_BOOL(retval);
386}
387/* }}} */
388
389/*
390 * Local variables:
391 * tab-width: 4
392 * c-basic-offset: 4
393 * End:
394 * vim600: sw=4 ts=4 fdm=marker
395 * vim<600: sw=4 ts=4
396 */
397