Annotation of embedaddon/php/ext/standard/var.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
                      5:    | Copyright (c) 1997-2012 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:    +----------------------------------------------------------------------+
1.1.1.2 ! misho      15:    | Authors: Jani Lehtimäki <jkl@njet.net>                               |
1.1       misho      16:    |          Thies C. Arntzen <thies@thieso.net>                         |
                     17:    |          Sascha Schumann <sascha@schumann.cx>                        |
                     18:    +----------------------------------------------------------------------+
                     19: */
                     20: 
1.1.1.2 ! misho      21: /* $Id$ */
1.1       misho      22: 
                     23: /* {{{ includes
                     24: */
                     25: #include <stdio.h>
                     26: #include <stdlib.h>
                     27: #include <errno.h>
                     28: #include "php.h"
                     29: #include "php_string.h"
                     30: #include "php_var.h"
                     31: #include "php_smart_str.h"
                     32: #include "basic_functions.h"
                     33: #include "php_incomplete_class.h"
                     34: 
                     35: #define COMMON (Z_ISREF_PP(struc) ? "&" : "")
                     36: /* }}} */
                     37: 
                     38: static int php_array_element_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
                     39: {
                     40:        int level;
                     41: 
                     42:        level = va_arg(args, int);
                     43: 
                     44:        if (hash_key->nKeyLength == 0) { /* numeric key */
                     45:                php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h);
                     46:        } else { /* string key */
                     47:                php_printf("%*c[\"", level + 1, ' ');
                     48:                PHPWRITE(hash_key->arKey, hash_key->nKeyLength - 1);
                     49:                php_printf("\"]=>\n");
                     50:        }
                     51:        php_var_dump(zv, level + 2 TSRMLS_CC);
                     52:        return 0;
                     53: }
                     54: /* }}} */
                     55: 
                     56: static int php_object_property_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
                     57: {
                     58:        int level;
1.1.1.2 ! misho      59:        const char *prop_name, *class_name;
1.1       misho      60: 
                     61:        level = va_arg(args, int);
                     62: 
                     63:        if (hash_key->nKeyLength == 0) { /* numeric key */
                     64:                php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h);
                     65:        } else { /* string key */
                     66:                int unmangle = zend_unmangle_property_name(hash_key->arKey, hash_key->nKeyLength - 1, &class_name, &prop_name);
                     67:                php_printf("%*c[", level + 1, ' ');
                     68: 
                     69:                if (class_name && unmangle == SUCCESS) {
                     70:                        if (class_name[0] == '*') {
                     71:                                php_printf("\"%s\":protected", prop_name);
                     72:                        } else {
                     73:                                php_printf("\"%s\":\"%s\":private", prop_name, class_name);
                     74:                        }
                     75:                } else {
                     76:                        php_printf("\"");
                     77:                        PHPWRITE(hash_key->arKey, hash_key->nKeyLength - 1);
                     78:                        php_printf("\"");
                     79:                }
                     80:                ZEND_PUTS("]=>\n");
                     81:        }
                     82:        php_var_dump(zv, level + 2 TSRMLS_CC);
                     83:        return 0;
                     84: }
                     85: /* }}} */
                     86: 
                     87: PHPAPI void php_var_dump(zval **struc, int level TSRMLS_DC) /* {{{ */
                     88: {
                     89:        HashTable *myht;
1.1.1.2 ! misho      90:        const char *class_name;
1.1       misho      91:        zend_uint class_name_len;
                     92:        int (*php_element_dump_func)(zval** TSRMLS_DC, int, va_list, zend_hash_key*);
                     93:        int is_temp;
                     94: 
                     95:        if (level > 1) {
                     96:                php_printf("%*c", level - 1, ' ');
                     97:        }
                     98: 
                     99:        switch (Z_TYPE_PP(struc)) {
                    100:        case IS_BOOL:
                    101:                php_printf("%sbool(%s)\n", COMMON, Z_LVAL_PP(struc) ? "true" : "false");
                    102:                break;
                    103:        case IS_NULL:
                    104:                php_printf("%sNULL\n", COMMON);
                    105:                break;
                    106:        case IS_LONG:
                    107:                php_printf("%sint(%ld)\n", COMMON, Z_LVAL_PP(struc));
                    108:                break;
                    109:        case IS_DOUBLE:
                    110:                php_printf("%sfloat(%.*G)\n", COMMON, (int) EG(precision), Z_DVAL_PP(struc));
                    111:                break;
                    112:        case IS_STRING:
                    113:                php_printf("%sstring(%d) \"", COMMON, Z_STRLEN_PP(struc));
                    114:                PHPWRITE(Z_STRVAL_PP(struc), Z_STRLEN_PP(struc));
                    115:                PUTS("\"\n");
                    116:                break;
                    117:        case IS_ARRAY:
                    118:                myht = Z_ARRVAL_PP(struc);
                    119:                if (++myht->nApplyCount > 1) {
                    120:                        PUTS("*RECURSION*\n");
                    121:                        --myht->nApplyCount;
                    122:                        return;
                    123:                }
                    124:                php_printf("%sarray(%d) {\n", COMMON, zend_hash_num_elements(myht));
                    125:                php_element_dump_func = php_array_element_dump;
                    126:                is_temp = 0;
                    127:                goto head_done;
                    128:        case IS_OBJECT:
                    129:                myht = Z_OBJDEBUG_PP(struc, is_temp);
                    130:                if (myht && ++myht->nApplyCount > 1) {
                    131:                        PUTS("*RECURSION*\n");
                    132:                        --myht->nApplyCount;
                    133:                        return;
                    134:                }
                    135: 
1.1.1.2 ! misho     136:                if (Z_OBJ_HANDLER(**struc, get_class_name)) {
        !           137:                        Z_OBJ_HANDLER(**struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC);
        !           138:                        php_printf("%sobject(%s)#%d (%d) {\n", COMMON, class_name, Z_OBJ_HANDLE_PP(struc), myht ? zend_hash_num_elements(myht) : 0);
        !           139:                        efree((char*)class_name);
        !           140:                } else {
        !           141:                        php_printf("%sobject(unknown class)#%d (%d) {\n", COMMON, Z_OBJ_HANDLE_PP(struc), myht ? zend_hash_num_elements(myht) : 0);
        !           142:                }
1.1       misho     143:                php_element_dump_func = php_object_property_dump;
                    144: head_done:
                    145:                if (myht) {
                    146:                        zend_hash_apply_with_arguments(myht TSRMLS_CC, (apply_func_args_t) php_element_dump_func, 1, level);
                    147:                        --myht->nApplyCount;
                    148:                        if (is_temp) {
                    149:                                zend_hash_destroy(myht);
                    150:                                efree(myht);
                    151:                        }
                    152:                }
                    153:                if (level > 1) {
                    154:                        php_printf("%*c", level-1, ' ');
                    155:                }
                    156:                PUTS("}\n");
                    157:                break;
                    158:        case IS_RESOURCE: {
1.1.1.2 ! misho     159:                const char *type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(struc) TSRMLS_CC);
1.1       misho     160:                php_printf("%sresource(%ld) of type (%s)\n", COMMON, Z_LVAL_PP(struc), type_name ? type_name : "Unknown");
                    161:                break;
                    162:        }
                    163:        default:
                    164:                php_printf("%sUNKNOWN:0\n", COMMON);
                    165:                break;
                    166:        }
                    167: }
                    168: /* }}} */
                    169: 
                    170: /* {{{ proto void var_dump(mixed var)
                    171:    Dumps a string representation of variable to output */
                    172: PHP_FUNCTION(var_dump)
                    173: {
                    174:        zval ***args;
                    175:        int argc;
                    176:        int     i;
                    177: 
                    178:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) {
                    179:                return;
                    180:        }
                    181: 
                    182:        for (i = 0; i < argc; i++) {
                    183:                php_var_dump(args[i], 1 TSRMLS_CC);
                    184:        }
                    185:        efree(args);
                    186: }
                    187: /* }}} */
                    188: 
                    189: static int zval_array_element_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
                    190: {
                    191:        int level;
                    192: 
                    193:        level = va_arg(args, int);
                    194: 
                    195:        if (hash_key->nKeyLength == 0) { /* numeric key */
                    196:                php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h);
                    197:        } else { /* string key */
                    198:                /* XXX: perphaps when we are inside the class we should permit access to
                    199:                 * private & protected values
                    200:                 */
                    201:                if (va_arg(args, int) && hash_key->arKey[0] == '\0') {
                    202:                        return 0;
                    203:                }
                    204:                php_printf("%*c[\"", level + 1, ' ');
                    205:                PHPWRITE(hash_key->arKey, hash_key->nKeyLength - 1);
                    206:                php_printf("\"]=>\n");
                    207:        }
                    208:        php_debug_zval_dump(zv, level + 2 TSRMLS_CC);
                    209:        return 0;
                    210: }
                    211: /* }}} */
                    212: 
                    213: static int zval_object_property_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
                    214: {
                    215:        int level;
1.1.1.2 ! misho     216:        const char *prop_name, *class_name;
1.1       misho     217: 
                    218:        level = va_arg(args, int);
                    219: 
                    220:        if (hash_key->nKeyLength == 0) { /* numeric key */
                    221:                php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h);
                    222:        } else { /* string key */
                    223:                zend_unmangle_property_name(hash_key->arKey, hash_key->nKeyLength - 1, &class_name, &prop_name);
                    224:                php_printf("%*c[", level + 1, ' ');
                    225: 
                    226:                if (class_name) {
                    227:                        if (class_name[0] == '*') {
                    228:                                php_printf("\"%s\":protected", prop_name);
                    229:                        } else {
                    230:                                php_printf("\"%s\":\"%s\":private", prop_name, class_name);
                    231:                        }
                    232:                } else {
                    233:                        php_printf("\"%s\"", prop_name);
                    234:                }
                    235:                ZEND_PUTS("]=>\n");
                    236:        }
                    237:        php_debug_zval_dump(zv, level + 2 TSRMLS_CC);
                    238:        return 0;
                    239: }
                    240: /* }}} */
                    241: 
                    242: PHPAPI void php_debug_zval_dump(zval **struc, int level TSRMLS_DC) /* {{{ */
                    243: {
                    244:        HashTable *myht = NULL;
1.1.1.2 ! misho     245:        const char *class_name;
1.1       misho     246:        zend_uint class_name_len;
                    247:        int (*zval_element_dump_func)(zval** TSRMLS_DC, int, va_list, zend_hash_key*);
                    248:        int is_temp = 0;
                    249: 
                    250:        if (level > 1) {
                    251:                php_printf("%*c", level - 1, ' ');
                    252:        }
                    253: 
                    254:        switch (Z_TYPE_PP(struc)) {
                    255:        case IS_BOOL:
                    256:                php_printf("%sbool(%s) refcount(%u)\n", COMMON, Z_LVAL_PP(struc)?"true":"false", Z_REFCOUNT_PP(struc));
                    257:                break;
                    258:        case IS_NULL:
                    259:                php_printf("%sNULL refcount(%u)\n", COMMON, Z_REFCOUNT_PP(struc));
                    260:                break;
                    261:        case IS_LONG:
                    262:                php_printf("%slong(%ld) refcount(%u)\n", COMMON, Z_LVAL_PP(struc), Z_REFCOUNT_PP(struc));
                    263:                break;
                    264:        case IS_DOUBLE:
                    265:                php_printf("%sdouble(%.*G) refcount(%u)\n", COMMON, (int) EG(precision), Z_DVAL_PP(struc), Z_REFCOUNT_PP(struc));
                    266:                break;
                    267:        case IS_STRING:
                    268:                php_printf("%sstring(%d) \"", COMMON, Z_STRLEN_PP(struc));
                    269:                PHPWRITE(Z_STRVAL_PP(struc), Z_STRLEN_PP(struc));
                    270:                php_printf("\" refcount(%u)\n", Z_REFCOUNT_PP(struc));
                    271:                break;
                    272:        case IS_ARRAY:
                    273:                myht = Z_ARRVAL_PP(struc);
                    274:                if (myht->nApplyCount > 1) {
                    275:                        PUTS("*RECURSION*\n");
                    276:                        return;
                    277:                }
                    278:                php_printf("%sarray(%d) refcount(%u){\n", COMMON, zend_hash_num_elements(myht), Z_REFCOUNT_PP(struc));
                    279:                zval_element_dump_func = zval_array_element_dump;
                    280:                goto head_done;
                    281:        case IS_OBJECT:
                    282:                myht = Z_OBJDEBUG_PP(struc, is_temp);
                    283:                if (myht && myht->nApplyCount > 1) {
                    284:                        PUTS("*RECURSION*\n");
                    285:                        return;
                    286:                }
1.1.1.2 ! misho     287:                Z_OBJ_HANDLER_PP(struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC);
        !           288:                php_printf("%sobject(%s)#%d (%d) refcount(%u){\n", COMMON, class_name, Z_OBJ_HANDLE_PP(struc), myht ? zend_hash_num_elements(myht) : 0, Z_REFCOUNT_PP(struc));
        !           289:                efree((char*)class_name);
1.1       misho     290:                zval_element_dump_func = zval_object_property_dump;
                    291: head_done:
                    292:                if (myht) {
                    293:                        zend_hash_apply_with_arguments(myht TSRMLS_CC, (apply_func_args_t) zval_element_dump_func, 1, level, (Z_TYPE_PP(struc) == IS_ARRAY ? 0 : 1));
                    294:                        if (is_temp) {
                    295:                                zend_hash_destroy(myht);
                    296:                                efree(myht);
                    297:                        }
                    298:                }
                    299:                if (level > 1) {
                    300:                        php_printf("%*c", level - 1, ' ');
                    301:                }
                    302:                PUTS("}\n");
                    303:                break;
                    304:        case IS_RESOURCE: {
1.1.1.2 ! misho     305:                const char *type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(struc) TSRMLS_CC);
1.1       misho     306:                php_printf("%sresource(%ld) of type (%s) refcount(%u)\n", COMMON, Z_LVAL_PP(struc), type_name ? type_name : "Unknown", Z_REFCOUNT_PP(struc));
                    307:                break;
                    308:        }
                    309:        default:
                    310:                php_printf("%sUNKNOWN:0\n", COMMON);
                    311:                break;
                    312:        }
                    313: }
                    314: /* }}} */
                    315: 
                    316: /* {{{ proto void debug_zval_dump(mixed var)
                    317:    Dumps a string representation of an internal zend value to output. */
                    318: PHP_FUNCTION(debug_zval_dump)
                    319: {
                    320:        zval ***args;
                    321:        int argc;
                    322:        int     i;
                    323: 
                    324:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) {
                    325:                return;
                    326:        }
                    327: 
                    328:        for (i = 0; i < argc; i++) {
                    329:                php_debug_zval_dump(args[i], 1 TSRMLS_CC);
                    330:        }
                    331:        efree(args);
                    332: }
                    333: /* }}} */
                    334: 
                    335: #define buffer_append_spaces(buf, num_spaces) \
                    336:        do { \
                    337:                char *tmp_spaces; \
                    338:                int tmp_spaces_len; \
                    339:                tmp_spaces_len = spprintf(&tmp_spaces, 0,"%*c", num_spaces, ' '); \
                    340:                smart_str_appendl(buf, tmp_spaces, tmp_spaces_len); \
                    341:                efree(tmp_spaces); \
                    342:        } while(0);
                    343: 
                    344: static int php_array_element_export(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
                    345: {
                    346:        int level;
                    347:        smart_str *buf;
                    348: 
                    349:        level = va_arg(args, int);
                    350:        buf = va_arg(args, smart_str *);
                    351: 
                    352:        if (hash_key->nKeyLength == 0) { /* numeric key */
                    353:                buffer_append_spaces(buf, level+1);
                    354:                smart_str_append_long(buf, (long) hash_key->h);
                    355:                smart_str_appendl(buf, " => ", 4);
1.1.1.2 ! misho     356: 
1.1       misho     357:        } else { /* string key */
                    358:                char *key, *tmp_str;
                    359:                int key_len, tmp_len;
                    360:                key = php_addcslashes(hash_key->arKey, hash_key->nKeyLength - 1, &key_len, 0, "'\\", 2 TSRMLS_CC);
                    361:                tmp_str = php_str_to_str_ex(key, key_len, "\0", 1, "' . \"\\0\" . '", 12, &tmp_len, 0, NULL);
                    362: 
                    363:                buffer_append_spaces(buf, level + 1);
                    364: 
                    365:                smart_str_appendc(buf, '\'');
                    366:                smart_str_appendl(buf, tmp_str, tmp_len);
                    367:                smart_str_appendl(buf, "' => ", 5);
                    368: 
                    369:                efree(key);
                    370:                efree(tmp_str);
                    371:        }
                    372:        php_var_export_ex(zv, level + 2, buf TSRMLS_CC);
                    373: 
                    374:        smart_str_appendc(buf, ',');
                    375:        smart_str_appendc(buf, '\n');
1.1.1.2 ! misho     376:        
1.1       misho     377:        return 0;
                    378: }
                    379: /* }}} */
                    380: 
                    381: static int php_object_element_export(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
                    382: {
                    383:        int level;
                    384:        smart_str *buf;
                    385: 
                    386:        level = va_arg(args, int);
                    387:        buf = va_arg(args, smart_str *);
                    388: 
                    389:        buffer_append_spaces(buf, level + 2);
                    390:        if (hash_key->nKeyLength != 0) {
1.1.1.2 ! misho     391:                const char *class_name; /* ignored, but must be passed to unmangle */
        !           392:                const char *pname;
        !           393:                char *pname_esc;
1.1       misho     394:                int  pname_esc_len;
                    395:                
                    396:                zend_unmangle_property_name(hash_key->arKey, hash_key->nKeyLength - 1,
                    397:                                &class_name, &pname);
                    398:                pname_esc = php_addcslashes(pname, strlen(pname), &pname_esc_len, 0,
                    399:                        "'\\", 2 TSRMLS_CC);
                    400: 
                    401:                smart_str_appendc(buf, '\'');
                    402:                smart_str_appendl(buf, pname_esc, pname_esc_len);
                    403:                smart_str_appendc(buf, '\'');
                    404:                efree(pname_esc);
                    405:        } else {
1.1.1.2 ! misho     406:                smart_str_append_long(buf, (long) hash_key->h);
1.1       misho     407:        }
                    408:        smart_str_appendl(buf, " => ", 4);
                    409:        php_var_export_ex(zv, level + 2, buf TSRMLS_CC);
                    410:        smart_str_appendc(buf, ',');
                    411:        smart_str_appendc(buf, '\n');
                    412:        return 0;
                    413: }
                    414: /* }}} */
                    415: 
                    416: PHPAPI void php_var_export_ex(zval **struc, int level, smart_str *buf TSRMLS_DC) /* {{{ */
                    417: {
                    418:        HashTable *myht;
                    419:        char *tmp_str, *tmp_str2;
                    420:        int tmp_len, tmp_len2;
1.1.1.2 ! misho     421:        const char *class_name;
1.1       misho     422:        zend_uint class_name_len;
                    423: 
                    424:        switch (Z_TYPE_PP(struc)) {
                    425:        case IS_BOOL:
1.1.1.2 ! misho     426:                if (Z_LVAL_PP(struc)) {
        !           427:                        smart_str_appendl(buf, "true", 4);
        !           428:                } else {
        !           429:                        smart_str_appendl(buf, "false", 5);
        !           430:                }
1.1       misho     431:                break;
                    432:        case IS_NULL:
                    433:                smart_str_appendl(buf, "NULL", 4);
                    434:                break;
                    435:        case IS_LONG:
                    436:                smart_str_append_long(buf, Z_LVAL_PP(struc));
                    437:                break;
                    438:        case IS_DOUBLE:
                    439:                tmp_len = spprintf(&tmp_str, 0,"%.*H", (int) EG(precision), Z_DVAL_PP(struc));
                    440:                smart_str_appendl(buf, tmp_str, tmp_len);
                    441:                efree(tmp_str);
                    442:                break;
                    443:        case IS_STRING:
                    444:                tmp_str = php_addcslashes(Z_STRVAL_PP(struc), Z_STRLEN_PP(struc), &tmp_len, 0, "'\\", 2 TSRMLS_CC);
                    445:                tmp_str2 = php_str_to_str_ex(tmp_str, tmp_len, "\0", 1, "' . \"\\0\" . '", 12, &tmp_len2, 0, NULL);
                    446: 
                    447:                smart_str_appendc(buf, '\'');
                    448:                smart_str_appendl(buf, tmp_str2, tmp_len2);
                    449:                smart_str_appendc(buf, '\'');
                    450: 
                    451:                efree(tmp_str2);
                    452:                efree(tmp_str);
                    453:                break;
                    454:        case IS_ARRAY:
                    455:                myht = Z_ARRVAL_PP(struc);
                    456:                if (level > 1) {
                    457:                        smart_str_appendc(buf, '\n');
                    458:                        buffer_append_spaces(buf, level - 1);
                    459:                }
                    460:                smart_str_appendl(buf, "array (\n", 8);
                    461:                zend_hash_apply_with_arguments(myht TSRMLS_CC, (apply_func_args_t) php_array_element_export, 2, level, buf);
                    462: 
                    463:                if (level > 1) {
                    464:                        buffer_append_spaces(buf, level - 1);
                    465:                }
                    466:                smart_str_appendc(buf, ')');
1.1.1.2 ! misho     467:     
1.1       misho     468:                break;
1.1.1.2 ! misho     469: 
1.1       misho     470:        case IS_OBJECT:
                    471:                myht = Z_OBJPROP_PP(struc);
                    472:                if (level > 1) {
                    473:                        smart_str_appendc(buf, '\n');
                    474:                        buffer_append_spaces(buf, level - 1);
                    475:                }
                    476:                Z_OBJ_HANDLER(**struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC);
                    477: 
                    478:                smart_str_appendl(buf, class_name, class_name_len);
                    479:                smart_str_appendl(buf, "::__set_state(array(\n", 21);
                    480: 
1.1.1.2 ! misho     481:                efree((char*)class_name);
1.1       misho     482:                if (myht) {
1.1.1.2 ! misho     483:                        zend_hash_apply_with_arguments(myht TSRMLS_CC, (apply_func_args_t) php_object_element_export, 1, level, buf);
1.1       misho     484:                }
                    485:                if (level > 1) {
                    486:                        buffer_append_spaces(buf, level - 1);
                    487:                }
                    488:                smart_str_appendl(buf, "))", 2);
                    489: 
                    490:                break;
                    491:        default:
                    492:                smart_str_appendl(buf, "NULL", 4);
                    493:                break;
                    494:        }
                    495: }
                    496: /* }}} */
                    497: 
                    498: /* FOR BC reasons, this will always perform and then print */
                    499: PHPAPI void php_var_export(zval **struc, int level TSRMLS_DC) /* {{{ */
                    500: {
                    501:        smart_str buf = {0};
                    502:        php_var_export_ex(struc, level, &buf TSRMLS_CC);
                    503:        smart_str_0 (&buf);
                    504:        PHPWRITE(buf.c, buf.len);
                    505:        smart_str_free(&buf);
                    506: }
                    507: /* }}} */
                    508: 
1.1.1.2 ! misho     509: 
1.1       misho     510: /* {{{ proto mixed var_export(mixed var [, bool return])
                    511:    Outputs or returns a string representation of a variable */
                    512: PHP_FUNCTION(var_export)
                    513: {
                    514:        zval *var;
                    515:        zend_bool return_output = 0;
                    516:        smart_str buf = {0};
                    517: 
                    518:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &var, &return_output) == FAILURE) {
                    519:                return;
                    520:        }
                    521: 
                    522:        php_var_export_ex(&var, 1, &buf TSRMLS_CC);
                    523:        smart_str_0 (&buf);
                    524: 
                    525:        if (return_output) {
                    526:                RETVAL_STRINGL(buf.c, buf.len, 1);
                    527:        } else {
                    528:                PHPWRITE(buf.c, buf.len);
                    529:        }
                    530:        smart_str_free(&buf);
                    531: }
                    532: /* }}} */
                    533: 
                    534: static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var_hash TSRMLS_DC);
                    535: 
                    536: static inline int php_add_var_hash(HashTable *var_hash, zval *var, void *var_old TSRMLS_DC) /* {{{ */
                    537: {
                    538:        ulong var_no;
                    539:        char id[32], *p;
                    540:        register int len;
                    541: 
                    542:        /* relies on "(long)" being a perfect hash function for data pointers,
                    543:         * however the actual identity of an object has had to be determined
                    544:         * by its object handle and the class entry since 5.0. */
                    545:        if ((Z_TYPE_P(var) == IS_OBJECT) && Z_OBJ_HT_P(var)->get_class_entry) {
                    546:                p = smart_str_print_long(id + sizeof(id) - 1,
                    547:                                (((size_t)Z_OBJCE_P(var) << 5)
                    548:                                | ((size_t)Z_OBJCE_P(var) >> (sizeof(long) * 8 - 5)))
                    549:                                + (long) Z_OBJ_HANDLE_P(var));
                    550:                *(--p) = 'O';
                    551:                len = id + sizeof(id) - 1 - p;
                    552:        } else {
                    553:                p = smart_str_print_long(id + sizeof(id) - 1, (long) var);
                    554:                len = id + sizeof(id) - 1 - p;
                    555:        }
                    556: 
                    557:        if (var_old && zend_hash_find(var_hash, p, len, var_old) == SUCCESS) {
                    558:                if (!Z_ISREF_P(var)) {
                    559:                        /* we still need to bump up the counter, since non-refs will
                    560:                         * be counted separately by unserializer */
                    561:                        var_no = -1;
                    562:                        zend_hash_next_index_insert(var_hash, &var_no, sizeof(var_no), NULL);
                    563:                }
1.1.1.2 ! misho     564: #if 0
        !           565:                fprintf(stderr, "- had var (%d): %lu\n", Z_TYPE_P(var), **(ulong**)var_old);
        !           566: #endif
1.1       misho     567:                return FAILURE;
                    568:        }
                    569: 
                    570:        /* +1 because otherwise hash will think we are trying to store NULL pointer */
                    571:        var_no = zend_hash_num_elements(var_hash) + 1;
                    572:        zend_hash_add(var_hash, p, len, &var_no, sizeof(var_no), NULL);
1.1.1.2 ! misho     573: #if 0
        !           574:        fprintf(stderr, "+ add var (%d): %lu\n", Z_TYPE_P(var), var_no);
        !           575: #endif
1.1       misho     576:        return SUCCESS;
                    577: }
                    578: /* }}} */
                    579: 
                    580: static inline void php_var_serialize_long(smart_str *buf, long val) /* {{{ */
                    581: {
                    582:        smart_str_appendl(buf, "i:", 2);
                    583:        smart_str_append_long(buf, val);
                    584:        smart_str_appendc(buf, ';');
                    585: }
                    586: /* }}} */
                    587: 
                    588: static inline void php_var_serialize_string(smart_str *buf, char *str, int len) /* {{{ */
                    589: {
                    590:        smart_str_appendl(buf, "s:", 2);
                    591:        smart_str_append_long(buf, len);
                    592:        smart_str_appendl(buf, ":\"", 2);
                    593:        smart_str_appendl(buf, str, len);
                    594:        smart_str_appendl(buf, "\";", 2);
                    595: }
                    596: /* }}} */
                    597: 
                    598: static inline zend_bool php_var_serialize_class_name(smart_str *buf, zval *struc TSRMLS_DC) /* {{{ */
                    599: {
                    600:        PHP_CLASS_ATTRIBUTES;
                    601: 
                    602:        PHP_SET_CLASS_ATTRIBUTES(struc);
                    603:        smart_str_appendl(buf, "O:", 2);
                    604:        smart_str_append_long(buf, (int)name_len);
                    605:        smart_str_appendl(buf, ":\"", 2);
                    606:        smart_str_appendl(buf, class_name, name_len);
                    607:        smart_str_appendl(buf, "\":", 2);
                    608:        PHP_CLEANUP_CLASS_ATTRIBUTES();
                    609:        return incomplete_class;
                    610: }
                    611: /* }}} */
                    612: 
                    613: static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_ptr, HashTable *var_hash TSRMLS_DC) /* {{{ */
                    614: {
                    615:        int count;
                    616:        zend_bool incomplete_class;
                    617: 
                    618:        incomplete_class = php_var_serialize_class_name(buf, struc TSRMLS_CC);
                    619:        /* count after serializing name, since php_var_serialize_class_name
                    620:         * changes the count if the variable is incomplete class */
                    621:        count = zend_hash_num_elements(HASH_OF(retval_ptr));
                    622:        if (incomplete_class) {
                    623:                --count;
                    624:        }
                    625:        smart_str_append_long(buf, count);
                    626:        smart_str_appendl(buf, ":{", 2);
                    627: 
                    628:        if (count > 0) {
                    629:                char *key;
                    630:                zval **d, **name;
                    631:                ulong index;
                    632:                HashPosition pos;
                    633:                int i;
                    634:                zval nval, *nvalp;
                    635: 
                    636:                ZVAL_NULL(&nval);
                    637:                nvalp = &nval;
                    638: 
                    639:                zend_hash_internal_pointer_reset_ex(HASH_OF(retval_ptr), &pos);
                    640: 
                    641:                for (;; zend_hash_move_forward_ex(HASH_OF(retval_ptr), &pos)) {
                    642:                        i = zend_hash_get_current_key_ex(HASH_OF(retval_ptr), &key, NULL, &index, 0, &pos);
                    643: 
                    644:                        if (i == HASH_KEY_NON_EXISTANT) {
                    645:                                break;
                    646:                        }
                    647: 
                    648:                        if (incomplete_class && strcmp(key, MAGIC_MEMBER) == 0) {
                    649:                                continue;
                    650:                        }
                    651:                        zend_hash_get_current_data_ex(HASH_OF(retval_ptr), (void **) &name, &pos);
                    652: 
                    653:                        if (Z_TYPE_PP(name) != IS_STRING) {
                    654:                                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "__sleep should return an array only containing the names of instance-variables to serialize.");
                    655:                                /* we should still add element even if it's not OK,
                    656:                                 * since we already wrote the length of the array before */
                    657:                                smart_str_appendl(buf,"N;", 2);
                    658:                                continue;
                    659:                        }
                    660:                        if (zend_hash_find(Z_OBJPROP_P(struc), Z_STRVAL_PP(name), Z_STRLEN_PP(name) + 1, (void *) &d) == SUCCESS) {
                    661:                                php_var_serialize_string(buf, Z_STRVAL_PP(name), Z_STRLEN_PP(name));
                    662:                                php_var_serialize_intern(buf, *d, var_hash TSRMLS_CC);
                    663:                        } else {
                    664:                                zend_class_entry *ce;
                    665:                                ce = zend_get_class_entry(struc TSRMLS_CC);
                    666:                                if (ce) {
                    667:                                        char *prot_name, *priv_name;
                    668:                                        int prop_name_length;
                    669: 
                    670:                                        do {
                    671:                                                zend_mangle_property_name(&priv_name, &prop_name_length, ce->name, ce->name_length, Z_STRVAL_PP(name), Z_STRLEN_PP(name), ce->type & ZEND_INTERNAL_CLASS);
                    672:                                                if (zend_hash_find(Z_OBJPROP_P(struc), priv_name, prop_name_length + 1, (void *) &d) == SUCCESS) {
                    673:                                                        php_var_serialize_string(buf, priv_name, prop_name_length);
                    674:                                                        pefree(priv_name, ce->type & ZEND_INTERNAL_CLASS);
                    675:                                                        php_var_serialize_intern(buf, *d, var_hash TSRMLS_CC);
                    676:                                                        break;
                    677:                                                }
                    678:                                                pefree(priv_name, ce->type & ZEND_INTERNAL_CLASS);
                    679:                                                zend_mangle_property_name(&prot_name, &prop_name_length, "*", 1, Z_STRVAL_PP(name), Z_STRLEN_PP(name), ce->type & ZEND_INTERNAL_CLASS);
                    680:                                                if (zend_hash_find(Z_OBJPROP_P(struc), prot_name, prop_name_length + 1, (void *) &d) == SUCCESS) {
                    681:                                                        php_var_serialize_string(buf, prot_name, prop_name_length);
                    682:                                                        pefree(prot_name, ce->type & ZEND_INTERNAL_CLASS);
                    683:                                                        php_var_serialize_intern(buf, *d, var_hash TSRMLS_CC);
                    684:                                                        break;
                    685:                                                }
                    686:                                                pefree(prot_name, ce->type & ZEND_INTERNAL_CLASS);
                    687:                                                php_var_serialize_string(buf, Z_STRVAL_PP(name), Z_STRLEN_PP(name));
                    688:                                                php_var_serialize_intern(buf, nvalp, var_hash TSRMLS_CC);
                    689:                                                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "\"%s\" returned as member variable from __sleep() but does not exist", Z_STRVAL_PP(name));
                    690:                                        } while (0);
                    691:                                } else {
                    692:                                        php_var_serialize_string(buf, Z_STRVAL_PP(name), Z_STRLEN_PP(name));
                    693:                                        php_var_serialize_intern(buf, nvalp, var_hash TSRMLS_CC);
                    694:                                }
                    695:                        }
                    696:                }
                    697:        }
                    698:        smart_str_appendc(buf, '}');
                    699: }
                    700: /* }}} */
                    701: 
                    702: static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var_hash TSRMLS_DC) /* {{{ */
                    703: {
                    704:        int i;
                    705:        ulong *var_already;
                    706:        HashTable *myht;
                    707: 
                    708:        if (var_hash && php_add_var_hash(var_hash, struc, (void *) &var_already TSRMLS_CC) == FAILURE) {
                    709:                if (Z_ISREF_P(struc)) {
                    710:                        smart_str_appendl(buf, "R:", 2);
                    711:                        smart_str_append_long(buf, (long)*var_already);
                    712:                        smart_str_appendc(buf, ';');
                    713:                        return;
                    714:                } else if (Z_TYPE_P(struc) == IS_OBJECT) {
                    715:                        smart_str_appendl(buf, "r:", 2);
                    716:                        smart_str_append_long(buf, (long)*var_already);
                    717:                        smart_str_appendc(buf, ';');
                    718:                        return;
                    719:                }
                    720:        }
                    721: 
                    722:        switch (Z_TYPE_P(struc)) {
                    723:                case IS_BOOL:
                    724:                        smart_str_appendl(buf, "b:", 2);
                    725:                        smart_str_append_long(buf, Z_LVAL_P(struc));
                    726:                        smart_str_appendc(buf, ';');
                    727:                        return;
                    728: 
                    729:                case IS_NULL:
                    730:                        smart_str_appendl(buf, "N;", 2);
                    731:                        return;
                    732: 
                    733:                case IS_LONG:
                    734:                        php_var_serialize_long(buf, Z_LVAL_P(struc));
                    735:                        return;
                    736: 
                    737:                case IS_DOUBLE: {
                    738:                                char *s;
                    739: 
                    740:                                smart_str_appendl(buf, "d:", 2);
                    741:                                s = (char *) safe_emalloc(PG(serialize_precision), 1, MAX_LENGTH_OF_DOUBLE + 1);
                    742:                                php_gcvt(Z_DVAL_P(struc), PG(serialize_precision), '.', 'E', s);
                    743:                                smart_str_appends(buf, s);
                    744:                                smart_str_appendc(buf, ';');
                    745:                                efree(s);
                    746:                                return;
                    747:                        }
                    748: 
                    749:                case IS_STRING:
                    750:                        php_var_serialize_string(buf, Z_STRVAL_P(struc), Z_STRLEN_P(struc));
                    751:                        return;
                    752: 
                    753:                case IS_OBJECT: {
                    754:                                zval *retval_ptr = NULL;
                    755:                                zval fname;
                    756:                                int res;
                    757:                                zend_class_entry *ce = NULL;
                    758: 
                    759:                                if (Z_OBJ_HT_P(struc)->get_class_entry) {
                    760:                                        ce = Z_OBJCE_P(struc);
                    761:                                }
                    762: 
                    763:                                if (ce && ce->serialize != NULL) {
                    764:                                        /* has custom handler */
                    765:                                        unsigned char *serialized_data = NULL;
                    766:                                        zend_uint serialized_length;
                    767: 
                    768:                                        if (ce->serialize(struc, &serialized_data, &serialized_length, (zend_serialize_data *)var_hash TSRMLS_CC) == SUCCESS) {
                    769:                                                smart_str_appendl(buf, "C:", 2);
                    770:                                                smart_str_append_long(buf, (int)Z_OBJCE_P(struc)->name_length);
                    771:                                                smart_str_appendl(buf, ":\"", 2);
                    772:                                                smart_str_appendl(buf, Z_OBJCE_P(struc)->name, Z_OBJCE_P(struc)->name_length);
                    773:                                                smart_str_appendl(buf, "\":", 2);
                    774: 
                    775:                                                smart_str_append_long(buf, (int)serialized_length);
                    776:                                                smart_str_appendl(buf, ":{", 2);
                    777:                                                smart_str_appendl(buf, serialized_data, serialized_length);
                    778:                                                smart_str_appendc(buf, '}');
                    779:                                        } else {
                    780:                                                smart_str_appendl(buf, "N;", 2);
                    781:                                        }
                    782:                                        if (serialized_data) {
                    783:                                                efree(serialized_data);
                    784:                                        }
                    785:                                        return;
                    786:                                }
                    787: 
                    788:                                if (ce && ce != PHP_IC_ENTRY && zend_hash_exists(&ce->function_table, "__sleep", sizeof("__sleep"))) {
                    789:                                        INIT_PZVAL(&fname);
                    790:                                        ZVAL_STRINGL(&fname, "__sleep", sizeof("__sleep") - 1, 0);
1.1.1.2 ! misho     791:                                        BG(serialize_lock)++;
1.1       misho     792:                                        res = call_user_function_ex(CG(function_table), &struc, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC);
1.1.1.2 ! misho     793:                                        BG(serialize_lock)--;
1.1       misho     794: 
                    795:                                        if (res == SUCCESS && !EG(exception)) {
                    796:                                                if (retval_ptr) {
                    797:                                                        if (HASH_OF(retval_ptr)) {
                    798:                                                                php_var_serialize_class(buf, struc, retval_ptr, var_hash TSRMLS_CC);
                    799:                                                        } else {
                    800:                                                                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "__sleep should return an array only containing the names of instance-variables to serialize");
                    801:                                                                /* we should still add element even if it's not OK,
                    802:                                                                 * since we already wrote the length of the array before */
                    803:                                                                smart_str_appendl(buf,"N;", 2);
                    804:                                                        }
                    805:                                                        zval_ptr_dtor(&retval_ptr);
                    806:                                                }
                    807:                                                return;
                    808:                                        }
                    809:                                }
                    810: 
                    811:                                if (retval_ptr) {
                    812:                                        zval_ptr_dtor(&retval_ptr);
                    813:                                }
                    814:                                /* fall-through */
                    815:                        }
                    816:                case IS_ARRAY: {
                    817:                        zend_bool incomplete_class = 0;
                    818:                        if (Z_TYPE_P(struc) == IS_ARRAY) {
                    819:                                smart_str_appendl(buf, "a:", 2);
                    820:                                myht = HASH_OF(struc);
                    821:                        } else {
                    822:                                incomplete_class = php_var_serialize_class_name(buf, struc TSRMLS_CC);
                    823:                                myht = Z_OBJPROP_P(struc);
                    824:                        }
                    825:                        /* count after serializing name, since php_var_serialize_class_name
                    826:                         * changes the count if the variable is incomplete class */
                    827:                        i = myht ? zend_hash_num_elements(myht) : 0;
                    828:                        if (i > 0 && incomplete_class) {
                    829:                                --i;
                    830:                        }
                    831:                        smart_str_append_long(buf, i);
                    832:                        smart_str_appendl(buf, ":{", 2);
                    833:                        if (i > 0) {
                    834:                                char *key;
                    835:                                zval **data;
                    836:                                ulong index;
                    837:                                uint key_len;
                    838:                                HashPosition pos;
                    839: 
                    840:                                zend_hash_internal_pointer_reset_ex(myht, &pos);
                    841:                                for (;; zend_hash_move_forward_ex(myht, &pos)) {
                    842:                                        i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos);
                    843:                                        if (i == HASH_KEY_NON_EXISTANT) {
                    844:                                                break;
                    845:                                        }
                    846:                                        if (incomplete_class && strcmp(key, MAGIC_MEMBER) == 0) {
                    847:                                                continue;
                    848:                                        }
                    849: 
                    850:                                        switch (i) {
                    851:                                                case HASH_KEY_IS_LONG:
                    852:                                                        php_var_serialize_long(buf, index);
                    853:                                                        break;
                    854:                                                case HASH_KEY_IS_STRING:
                    855:                                                        php_var_serialize_string(buf, key, key_len - 1);
                    856:                                                        break;
                    857:                                        }
                    858: 
                    859:                                        /* we should still add element even if it's not OK,
                    860:                                         * since we already wrote the length of the array before */
                    861:                                        if (zend_hash_get_current_data_ex(myht, (void **) &data, &pos) != SUCCESS
                    862:                                                || !data
                    863:                                                || data == &struc
                    864:                                                || (Z_TYPE_PP(data) == IS_ARRAY && Z_ARRVAL_PP(data)->nApplyCount > 1)
                    865:                                        ) {
                    866:                                                smart_str_appendl(buf, "N;", 2);
                    867:                                        } else {
                    868:                                                if (Z_TYPE_PP(data) == IS_ARRAY) {
                    869:                                                        Z_ARRVAL_PP(data)->nApplyCount++;
                    870:                                                }
                    871:                                                php_var_serialize_intern(buf, *data, var_hash TSRMLS_CC);
                    872:                                                if (Z_TYPE_PP(data) == IS_ARRAY) {
                    873:                                                        Z_ARRVAL_PP(data)->nApplyCount--;
                    874:                                                }
                    875:                                        }
                    876:                                }
                    877:                        }
                    878:                        smart_str_appendc(buf, '}');
                    879:                        return;
                    880:                }
                    881:                default:
                    882:                        smart_str_appendl(buf, "i:0;", 4);
                    883:                        return;
                    884:        }
                    885: }
                    886: /* }}} */
                    887: 
1.1.1.2 ! misho     888: PHPAPI void php_var_serialize(smart_str *buf, zval **struc, php_serialize_data_t *var_hash TSRMLS_DC) /* {{{ */
1.1       misho     889: {
1.1.1.2 ! misho     890:        php_var_serialize_intern(buf, *struc, *var_hash TSRMLS_CC);
1.1       misho     891:        smart_str_0(buf);
                    892: }
                    893: /* }}} */
                    894: 
                    895: /* {{{ proto string serialize(mixed variable)
                    896:    Returns a string representation of variable (which can later be unserialized) */
                    897: PHP_FUNCTION(serialize)
                    898: {
                    899:        zval **struc;
                    900:        php_serialize_data_t var_hash;
                    901:        smart_str buf = {0};
                    902: 
                    903:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &struc) == FAILURE) {
                    904:                return;
                    905:        }
                    906: 
                    907:        Z_TYPE_P(return_value) = IS_STRING;
                    908:        Z_STRVAL_P(return_value) = NULL;
                    909:        Z_STRLEN_P(return_value) = 0;
                    910: 
                    911:        PHP_VAR_SERIALIZE_INIT(var_hash);
                    912:        php_var_serialize(&buf, struc, &var_hash TSRMLS_CC);
                    913:        PHP_VAR_SERIALIZE_DESTROY(var_hash);
                    914: 
                    915:        if (buf.c) {
                    916:                RETURN_STRINGL(buf.c, buf.len, 0);
                    917:        } else {
                    918:                RETURN_NULL();
                    919:        }
                    920: }
                    921: /* }}} */
                    922: 
                    923: /* {{{ proto mixed unserialize(string variable_representation)
                    924:    Takes a string representation of variable and recreates it */
                    925: PHP_FUNCTION(unserialize)
                    926: {
                    927:        char *buf = NULL;
                    928:        int buf_len;
                    929:        const unsigned char *p;
                    930:        php_unserialize_data_t var_hash;
                    931: 
                    932:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) {
                    933:                RETURN_FALSE;
                    934:        }
                    935: 
                    936:        if (buf_len == 0) {
                    937:                RETURN_FALSE;
                    938:        }
                    939: 
                    940:        p = (const unsigned char*) buf;
                    941:        PHP_VAR_UNSERIALIZE_INIT(var_hash);
                    942:        if (!php_var_unserialize(&return_value, &p, p + buf_len, &var_hash TSRMLS_CC)) {
                    943:                PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
                    944:                zval_dtor(return_value);
                    945:                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len);
                    946:                RETURN_FALSE;
                    947:        }
                    948:        PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
                    949: }
                    950: /* }}} */
                    951: 
                    952: /* {{{ proto int memory_get_usage([real_usage])
                    953:    Returns the allocated by PHP memory */
                    954: PHP_FUNCTION(memory_get_usage) {
                    955:        zend_bool real_usage = 0;
                    956: 
                    957:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &real_usage) == FAILURE) {
                    958:                RETURN_FALSE;
                    959:        }
                    960: 
                    961:        RETURN_LONG(zend_memory_usage(real_usage TSRMLS_CC));
                    962: }
                    963: /* }}} */
                    964: 
                    965: /* {{{ proto int memory_get_peak_usage([real_usage])
                    966:    Returns the peak allocated by PHP memory */
                    967: PHP_FUNCTION(memory_get_peak_usage) {
                    968:        zend_bool real_usage = 0;
                    969: 
                    970:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &real_usage) == FAILURE) {
                    971:                RETURN_FALSE;
                    972:        }
                    973: 
                    974:        RETURN_LONG(zend_memory_peak_usage(real_usage TSRMLS_CC));
                    975: }
                    976: /* }}} */
                    977: 
                    978: /*
                    979:  * Local variables:
                    980:  * tab-width: 4
                    981:  * c-basic-offset: 4
                    982:  * End:
                    983:  * vim600: sw=4 ts=4 fdm=marker
                    984:  * vim<600: sw=4 ts=4
                    985:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>