Annotation of embedaddon/php/ext/mbstring/mbstring.c, revision 1.1

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:    +----------------------------------------------------------------------+
        !            15:    | Author: Tsukada Takuya <tsukada@fminn.nagano.nagano.jp>              |
        !            16:    |         Rui Hirokawa <hirokawa@php.net>                              |
        !            17:    +----------------------------------------------------------------------+
        !            18:  */
        !            19: 
        !            20: /* $Id: mbstring.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            21: 
        !            22: /*
        !            23:  * PHP 4 Multibyte String module "mbstring"
        !            24:  *
        !            25:  * History:
        !            26:  *   2000.5.19  Release php-4.0RC2_jstring-1.0
        !            27:  *   2001.4.1   Release php4_jstring-1.0.91
        !            28:  *   2001.4.30  Release php4_jstring-1.1 (contribute to The PHP Group)
        !            29:  *   2001.5.1   Renamed from jstring to mbstring (hirokawa@php.net)
        !            30:  */
        !            31: 
        !            32: /*
        !            33:  * PHP3 Internationalization support program.
        !            34:  *
        !            35:  * Copyright (c) 1999,2000 by the PHP3 internationalization team.
        !            36:  * All rights reserved.
        !            37:  *
        !            38:  * See README_PHP3-i18n-ja for more detail.
        !            39:  *
        !            40:  * Authors:
        !            41:  *    Hironori Sato <satoh@jpnnet.com>
        !            42:  *    Shigeru Kanemoto <sgk@happysize.co.jp>
        !            43:  *    Tsukada Takuya <tsukada@fminn.nagano.nagano.jp>
        !            44:  *    Rui Hirokawa <rui_hirokawa@ybb.ne.jp>
        !            45:  */
        !            46: 
        !            47: /* {{{ includes */
        !            48: #ifdef HAVE_CONFIG_H
        !            49: #include "config.h"
        !            50: #endif
        !            51: 
        !            52: #include "php.h"
        !            53: #include "php_ini.h"
        !            54: #include "php_variables.h"
        !            55: #include "mbstring.h"
        !            56: #include "ext/standard/php_string.h"
        !            57: #include "ext/standard/php_mail.h"
        !            58: #include "ext/standard/exec.h"
        !            59: #include "ext/standard/php_smart_str.h"
        !            60: #include "ext/standard/url.h"
        !            61: #include "main/php_output.h"
        !            62: #include "ext/standard/info.h"
        !            63: 
        !            64: #include "libmbfl/mbfl/mbfl_allocators.h"
        !            65: 
        !            66: #include "php_variables.h"
        !            67: #include "php_globals.h"
        !            68: #include "rfc1867.h"
        !            69: #include "php_content_types.h"
        !            70: #include "SAPI.h"
        !            71: #include "php_unicode.h"
        !            72: #include "TSRM.h"
        !            73: 
        !            74: #include "mb_gpc.h"
        !            75: 
        !            76: #if HAVE_MBREGEX
        !            77: #include "php_mbregex.h"
        !            78: #endif
        !            79: 
        !            80: #ifdef ZEND_MULTIBYTE
        !            81: #include "zend_multibyte.h"
        !            82: #endif /* ZEND_MULTIBYTE */
        !            83: 
        !            84: #if HAVE_ONIG
        !            85: #include "php_onig_compat.h"
        !            86: #include <oniguruma.h>
        !            87: #undef UChar
        !            88: #elif HAVE_PCRE || HAVE_BUNDLED_PCRE
        !            89: #include "ext/pcre/php_pcre.h"
        !            90: #endif
        !            91: /* }}} */
        !            92: 
        !            93: #if HAVE_MBSTRING
        !            94: 
        !            95: /* {{{ prototypes */
        !            96: ZEND_DECLARE_MODULE_GLOBALS(mbstring)
        !            97: 
        !            98: static PHP_GINIT_FUNCTION(mbstring);
        !            99: static PHP_GSHUTDOWN_FUNCTION(mbstring);
        !           100: 
        !           101: #ifdef ZEND_MULTIBYTE
        !           102: static size_t php_mb_oddlen(const unsigned char *string, size_t length, const char *encoding TSRMLS_DC);
        !           103: static int php_mb_encoding_converter(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length, const char *encoding_to, const char *encoding_from TSRMLS_DC);
        !           104: static char* php_mb_encoding_detector(const unsigned char *arg_string, size_t arg_length, char *arg_list TSRMLS_DC);
        !           105: static int php_mb_set_zend_encoding(TSRMLS_D);
        !           106: #endif
        !           107: /* }}} */
        !           108: 
        !           109: /* {{{ php_mb_default_identify_list */
        !           110: typedef struct _php_mb_nls_ident_list {
        !           111:        enum mbfl_no_language lang;
        !           112:        const enum mbfl_no_encoding* list;
        !           113:        int list_size;
        !           114: } php_mb_nls_ident_list;
        !           115: 
        !           116: static const enum mbfl_no_encoding php_mb_default_identify_list_ja[] = {
        !           117:        mbfl_no_encoding_ascii,
        !           118:        mbfl_no_encoding_jis,
        !           119:        mbfl_no_encoding_utf8,
        !           120:        mbfl_no_encoding_euc_jp,
        !           121:        mbfl_no_encoding_sjis
        !           122: };
        !           123: 
        !           124: static const enum mbfl_no_encoding php_mb_default_identify_list_cn[] = {
        !           125:        mbfl_no_encoding_ascii,
        !           126:        mbfl_no_encoding_utf8,
        !           127:        mbfl_no_encoding_euc_cn,
        !           128:        mbfl_no_encoding_cp936
        !           129: };
        !           130: 
        !           131: static const enum mbfl_no_encoding php_mb_default_identify_list_tw_hk[] = {
        !           132:        mbfl_no_encoding_ascii,
        !           133:        mbfl_no_encoding_utf8,
        !           134:        mbfl_no_encoding_euc_tw,
        !           135:        mbfl_no_encoding_big5
        !           136: };
        !           137: 
        !           138: static const enum mbfl_no_encoding php_mb_default_identify_list_kr[] = {
        !           139:        mbfl_no_encoding_ascii,
        !           140:        mbfl_no_encoding_utf8,
        !           141:        mbfl_no_encoding_euc_kr,
        !           142:        mbfl_no_encoding_uhc
        !           143: };
        !           144: 
        !           145: static const enum mbfl_no_encoding php_mb_default_identify_list_ru[] = {
        !           146:        mbfl_no_encoding_ascii,
        !           147:        mbfl_no_encoding_utf8,
        !           148:        mbfl_no_encoding_koi8r,
        !           149:        mbfl_no_encoding_cp1251,
        !           150:        mbfl_no_encoding_cp866
        !           151: };
        !           152: 
        !           153: static const enum mbfl_no_encoding php_mb_default_identify_list_hy[] = {
        !           154:        mbfl_no_encoding_ascii,
        !           155:        mbfl_no_encoding_utf8,
        !           156:        mbfl_no_encoding_armscii8
        !           157: };
        !           158: 
        !           159: static const enum mbfl_no_encoding php_mb_default_identify_list_tr[] = {
        !           160:        mbfl_no_encoding_ascii,
        !           161:        mbfl_no_encoding_utf8,
        !           162:        mbfl_no_encoding_cp1254,
        !           163:        mbfl_no_encoding_8859_9
        !           164: };
        !           165: 
        !           166: static const enum mbfl_no_encoding php_mb_default_identify_list_ua[] = {
        !           167:        mbfl_no_encoding_ascii,
        !           168:        mbfl_no_encoding_utf8,
        !           169:        mbfl_no_encoding_koi8u
        !           170: };
        !           171: 
        !           172: static const enum mbfl_no_encoding php_mb_default_identify_list_neut[] = {
        !           173:        mbfl_no_encoding_ascii,
        !           174:        mbfl_no_encoding_utf8
        !           175: };
        !           176: 
        !           177: 
        !           178: static const php_mb_nls_ident_list php_mb_default_identify_list[] = {
        !           179:        { mbfl_no_language_japanese, php_mb_default_identify_list_ja, sizeof(php_mb_default_identify_list_ja) / sizeof(php_mb_default_identify_list_ja[0]) },
        !           180:        { mbfl_no_language_korean, php_mb_default_identify_list_kr, sizeof(php_mb_default_identify_list_kr) / sizeof(php_mb_default_identify_list_kr[0]) },
        !           181:        { mbfl_no_language_traditional_chinese, php_mb_default_identify_list_tw_hk, sizeof(php_mb_default_identify_list_tw_hk) / sizeof(php_mb_default_identify_list_tw_hk[0]) },
        !           182:        { mbfl_no_language_simplified_chinese, php_mb_default_identify_list_cn, sizeof(php_mb_default_identify_list_cn) / sizeof(php_mb_default_identify_list_cn[0]) },
        !           183:        { mbfl_no_language_russian, php_mb_default_identify_list_ru, sizeof(php_mb_default_identify_list_ru) / sizeof(php_mb_default_identify_list_ru[0]) },
        !           184:        { mbfl_no_language_armenian, php_mb_default_identify_list_hy, sizeof(php_mb_default_identify_list_hy) / sizeof(php_mb_default_identify_list_hy[0]) },
        !           185:        { mbfl_no_language_turkish, php_mb_default_identify_list_tr, sizeof(php_mb_default_identify_list_tr) / sizeof(php_mb_default_identify_list_tr[0]) },
        !           186:        { mbfl_no_language_ukrainian, php_mb_default_identify_list_ua, sizeof(php_mb_default_identify_list_ua) / sizeof(php_mb_default_identify_list_ua[0]) },
        !           187:        { mbfl_no_language_neutral, php_mb_default_identify_list_neut, sizeof(php_mb_default_identify_list_neut) / sizeof(php_mb_default_identify_list_neut[0]) }
        !           188: };
        !           189: 
        !           190: /* }}} */
        !           191: 
        !           192: /* {{{ mb_overload_def mb_ovld[] */
        !           193: static const struct mb_overload_def mb_ovld[] = {
        !           194:        {MB_OVERLOAD_MAIL, "mail", "mb_send_mail", "mb_orig_mail"},
        !           195:        {MB_OVERLOAD_STRING, "strlen", "mb_strlen", "mb_orig_strlen"},
        !           196:        {MB_OVERLOAD_STRING, "strpos", "mb_strpos", "mb_orig_strpos"},
        !           197:        {MB_OVERLOAD_STRING, "strrpos", "mb_strrpos", "mb_orig_strrpos"},
        !           198:        {MB_OVERLOAD_STRING, "stripos", "mb_stripos", "mb_orig_stripos"},
        !           199:        {MB_OVERLOAD_STRING, "strripos", "mb_strripos", "mb_orig_strripos"},
        !           200:        {MB_OVERLOAD_STRING, "strstr", "mb_strstr", "mb_orig_strstr"},
        !           201:        {MB_OVERLOAD_STRING, "strrchr", "mb_strrchr", "mb_orig_strrchr"},
        !           202:        {MB_OVERLOAD_STRING, "stristr", "mb_stristr", "mb_orig_stristr"},
        !           203:        {MB_OVERLOAD_STRING, "substr", "mb_substr", "mb_orig_substr"},
        !           204:        {MB_OVERLOAD_STRING, "strtolower", "mb_strtolower", "mb_orig_strtolower"},
        !           205:        {MB_OVERLOAD_STRING, "strtoupper", "mb_strtoupper", "mb_orig_strtoupper"},
        !           206:        {MB_OVERLOAD_STRING, "substr_count", "mb_substr_count", "mb_orig_substr_count"},
        !           207: #if HAVE_MBREGEX
        !           208:        {MB_OVERLOAD_REGEX, "ereg", "mb_ereg", "mb_orig_ereg"},
        !           209:        {MB_OVERLOAD_REGEX, "eregi", "mb_eregi", "mb_orig_eregi"},
        !           210:        {MB_OVERLOAD_REGEX, "ereg_replace", "mb_ereg_replace", "mb_orig_ereg_replace"},
        !           211:        {MB_OVERLOAD_REGEX, "eregi_replace", "mb_eregi_replace", "mb_orig_eregi_replace"},
        !           212:        {MB_OVERLOAD_REGEX, "split", "mb_split", "mb_orig_split"},
        !           213: #endif
        !           214:        {0, NULL, NULL, NULL}
        !           215: }; 
        !           216: /* }}} */
        !           217: 
        !           218: /* {{{ arginfo */
        !           219: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_language, 0, 0, 0)
        !           220:        ZEND_ARG_INFO(0, language)
        !           221: ZEND_END_ARG_INFO()
        !           222: 
        !           223: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_internal_encoding, 0, 0, 0)
        !           224:        ZEND_ARG_INFO(0, encoding)
        !           225: ZEND_END_ARG_INFO()
        !           226: 
        !           227: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_http_input, 0, 0, 0)
        !           228:        ZEND_ARG_INFO(0, type)
        !           229: ZEND_END_ARG_INFO()
        !           230: 
        !           231: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_http_output, 0, 0, 0)
        !           232:        ZEND_ARG_INFO(0, encoding)
        !           233: ZEND_END_ARG_INFO()
        !           234: 
        !           235: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_detect_order, 0, 0, 0)
        !           236:        ZEND_ARG_INFO(0, encoding)
        !           237: ZEND_END_ARG_INFO()
        !           238: 
        !           239: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_substitute_character, 0, 0, 0)
        !           240:        ZEND_ARG_INFO(0, substchar)
        !           241: ZEND_END_ARG_INFO()
        !           242: 
        !           243: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_preferred_mime_name, 0, 0, 1)
        !           244:        ZEND_ARG_INFO(0, encoding)
        !           245: ZEND_END_ARG_INFO()
        !           246: 
        !           247: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_parse_str, 0, 0, 1)
        !           248:        ZEND_ARG_INFO(0, encoded_string)
        !           249:        ZEND_ARG_INFO(1, result)
        !           250: ZEND_END_ARG_INFO()
        !           251: 
        !           252: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_output_handler, 0, 0, 2)
        !           253:        ZEND_ARG_INFO(0, contents)
        !           254:        ZEND_ARG_INFO(0, status)
        !           255: ZEND_END_ARG_INFO()
        !           256: 
        !           257: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strlen, 0, 0, 1)
        !           258:        ZEND_ARG_INFO(0, str)
        !           259:        ZEND_ARG_INFO(0, encoding)
        !           260: ZEND_END_ARG_INFO()
        !           261: 
        !           262: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strpos, 0, 0, 2)
        !           263:        ZEND_ARG_INFO(0, haystack)
        !           264:        ZEND_ARG_INFO(0, needle)
        !           265:        ZEND_ARG_INFO(0, offset)
        !           266:        ZEND_ARG_INFO(0, encoding)
        !           267: ZEND_END_ARG_INFO()
        !           268: 
        !           269: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strrpos, 0, 0, 2)
        !           270:        ZEND_ARG_INFO(0, haystack)
        !           271:        ZEND_ARG_INFO(0, needle)
        !           272:        ZEND_ARG_INFO(0, offset)
        !           273:        ZEND_ARG_INFO(0, encoding)
        !           274: ZEND_END_ARG_INFO()
        !           275: 
        !           276: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_stripos, 0, 0, 2)
        !           277:        ZEND_ARG_INFO(0, haystack)
        !           278:        ZEND_ARG_INFO(0, needle)
        !           279:        ZEND_ARG_INFO(0, offset)
        !           280:        ZEND_ARG_INFO(0, encoding)
        !           281: ZEND_END_ARG_INFO()
        !           282: 
        !           283: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strripos, 0, 0, 2)
        !           284:        ZEND_ARG_INFO(0, haystack)
        !           285:        ZEND_ARG_INFO(0, needle)
        !           286:        ZEND_ARG_INFO(0, offset)
        !           287:        ZEND_ARG_INFO(0, encoding)
        !           288: ZEND_END_ARG_INFO()
        !           289: 
        !           290: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strstr, 0, 0, 2)
        !           291:        ZEND_ARG_INFO(0, haystack)
        !           292:        ZEND_ARG_INFO(0, needle)
        !           293:        ZEND_ARG_INFO(0, part)
        !           294:        ZEND_ARG_INFO(0, encoding)
        !           295: ZEND_END_ARG_INFO()
        !           296: 
        !           297: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strrchr, 0, 0, 2)
        !           298:        ZEND_ARG_INFO(0, haystack)
        !           299:        ZEND_ARG_INFO(0, needle)
        !           300:        ZEND_ARG_INFO(0, part)
        !           301:        ZEND_ARG_INFO(0, encoding)
        !           302: ZEND_END_ARG_INFO()
        !           303: 
        !           304: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_stristr, 0, 0, 2)
        !           305:        ZEND_ARG_INFO(0, haystack)
        !           306:        ZEND_ARG_INFO(0, needle)
        !           307:        ZEND_ARG_INFO(0, part)
        !           308:        ZEND_ARG_INFO(0, encoding)
        !           309: ZEND_END_ARG_INFO()
        !           310: 
        !           311: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strrichr, 0, 0, 2)
        !           312:        ZEND_ARG_INFO(0, haystack)
        !           313:        ZEND_ARG_INFO(0, needle)
        !           314:        ZEND_ARG_INFO(0, part)
        !           315:        ZEND_ARG_INFO(0, encoding)
        !           316: ZEND_END_ARG_INFO()
        !           317: 
        !           318: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_substr_count, 0, 0, 2)
        !           319:        ZEND_ARG_INFO(0, haystack)
        !           320:        ZEND_ARG_INFO(0, needle)
        !           321:        ZEND_ARG_INFO(0, encoding)
        !           322: ZEND_END_ARG_INFO()
        !           323: 
        !           324: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_substr, 0, 0, 2)
        !           325:        ZEND_ARG_INFO(0, str)
        !           326:        ZEND_ARG_INFO(0, start)
        !           327:        ZEND_ARG_INFO(0, length)
        !           328:        ZEND_ARG_INFO(0, encoding)
        !           329: ZEND_END_ARG_INFO()
        !           330: 
        !           331: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strcut, 0, 0, 2)
        !           332:        ZEND_ARG_INFO(0, str)
        !           333:        ZEND_ARG_INFO(0, start)
        !           334:        ZEND_ARG_INFO(0, length)
        !           335:        ZEND_ARG_INFO(0, encoding)
        !           336: ZEND_END_ARG_INFO()
        !           337: 
        !           338: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strwidth, 0, 0, 1)
        !           339:        ZEND_ARG_INFO(0, str)
        !           340:        ZEND_ARG_INFO(0, encoding)
        !           341: ZEND_END_ARG_INFO()
        !           342: 
        !           343: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strimwidth, 0, 0, 3)
        !           344:        ZEND_ARG_INFO(0, str)
        !           345:        ZEND_ARG_INFO(0, start)
        !           346:        ZEND_ARG_INFO(0, width)
        !           347:        ZEND_ARG_INFO(0, trimmarker)
        !           348:        ZEND_ARG_INFO(0, encoding)
        !           349: ZEND_END_ARG_INFO()
        !           350: 
        !           351: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_convert_encoding, 0, 0, 2)
        !           352:        ZEND_ARG_INFO(0, str)
        !           353:        ZEND_ARG_INFO(0, to)
        !           354:        ZEND_ARG_INFO(0, from)
        !           355: ZEND_END_ARG_INFO()
        !           356: 
        !           357: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_convert_case, 0, 0, 2)
        !           358:        ZEND_ARG_INFO(0, sourcestring)
        !           359:        ZEND_ARG_INFO(0, mode)
        !           360:        ZEND_ARG_INFO(0, encoding)
        !           361: ZEND_END_ARG_INFO()
        !           362: 
        !           363: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strtoupper, 0, 0, 1)
        !           364:        ZEND_ARG_INFO(0, sourcestring)
        !           365:        ZEND_ARG_INFO(0, encoding)
        !           366: ZEND_END_ARG_INFO()
        !           367: 
        !           368: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strtolower, 0, 0, 1)
        !           369:        ZEND_ARG_INFO(0, sourcestring)
        !           370:        ZEND_ARG_INFO(0, encoding)
        !           371: ZEND_END_ARG_INFO()
        !           372: 
        !           373: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_detect_encoding, 0, 0, 1)
        !           374:        ZEND_ARG_INFO(0, str)
        !           375:        ZEND_ARG_INFO(0, encoding_list)
        !           376:        ZEND_ARG_INFO(0, strict)
        !           377: ZEND_END_ARG_INFO()
        !           378: 
        !           379: ZEND_BEGIN_ARG_INFO(arginfo_mb_list_encodings, 0)
        !           380: ZEND_END_ARG_INFO()
        !           381: 
        !           382: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_encoding_aliases, 0, 0, 1)
        !           383:        ZEND_ARG_INFO(0, encoding)
        !           384: ZEND_END_ARG_INFO()
        !           385: 
        !           386: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_encode_mimeheader, 0, 0, 1)
        !           387:        ZEND_ARG_INFO(0, str)
        !           388:        ZEND_ARG_INFO(0, charset)
        !           389:        ZEND_ARG_INFO(0, transfer)
        !           390:        ZEND_ARG_INFO(0, linefeed)
        !           391:        ZEND_ARG_INFO(0, indent)
        !           392: ZEND_END_ARG_INFO()
        !           393: 
        !           394: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_decode_mimeheader, 0, 0, 1)
        !           395:        ZEND_ARG_INFO(0, string)
        !           396: ZEND_END_ARG_INFO()
        !           397: 
        !           398: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_convert_kana, 0, 0, 1)
        !           399:        ZEND_ARG_INFO(0, str)
        !           400:        ZEND_ARG_INFO(0, option)
        !           401:        ZEND_ARG_INFO(0, encoding)
        !           402: ZEND_END_ARG_INFO()
        !           403: 
        !           404: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_convert_variables, 1, 0, 3)
        !           405:        ZEND_ARG_INFO(0, to)
        !           406:        ZEND_ARG_INFO(0, from)
        !           407:        ZEND_ARG_INFO(1, ...)
        !           408: ZEND_END_ARG_INFO()
        !           409: 
        !           410: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_encode_numericentity, 0, 0, 2)
        !           411:        ZEND_ARG_INFO(0, string)
        !           412:        ZEND_ARG_INFO(0, convmap)
        !           413:        ZEND_ARG_INFO(0, encoding)
        !           414: ZEND_END_ARG_INFO()
        !           415: 
        !           416: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_decode_numericentity, 0, 0, 2)
        !           417:        ZEND_ARG_INFO(0, string)
        !           418:        ZEND_ARG_INFO(0, convmap)
        !           419:        ZEND_ARG_INFO(0, encoding)
        !           420: ZEND_END_ARG_INFO()
        !           421: 
        !           422: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_send_mail, 0, 0, 3)
        !           423:        ZEND_ARG_INFO(0, to)
        !           424:        ZEND_ARG_INFO(0, subject)
        !           425:        ZEND_ARG_INFO(0, message)
        !           426:        ZEND_ARG_INFO(0, additional_headers)
        !           427:        ZEND_ARG_INFO(0, additional_parameters)
        !           428: ZEND_END_ARG_INFO()
        !           429: 
        !           430: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_get_info, 0, 0, 0)
        !           431:        ZEND_ARG_INFO(0, type)
        !           432: ZEND_END_ARG_INFO()
        !           433: 
        !           434: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_check_encoding, 0, 0, 0)
        !           435:        ZEND_ARG_INFO(0, var)
        !           436:        ZEND_ARG_INFO(0, encoding)
        !           437: ZEND_END_ARG_INFO()
        !           438: 
        !           439: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_regex_encoding, 0, 0, 0)
        !           440:        ZEND_ARG_INFO(0, encoding)
        !           441: ZEND_END_ARG_INFO()
        !           442: 
        !           443: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg, 0, 0, 2)
        !           444:        ZEND_ARG_INFO(0, pattern)
        !           445:        ZEND_ARG_INFO(0, string)
        !           446:        ZEND_ARG_INFO(1, registers)
        !           447: ZEND_END_ARG_INFO()
        !           448: 
        !           449: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_eregi, 0, 0, 2)
        !           450:        ZEND_ARG_INFO(0, pattern)
        !           451:        ZEND_ARG_INFO(0, string)
        !           452:        ZEND_ARG_INFO(1, registers)
        !           453: ZEND_END_ARG_INFO()
        !           454: 
        !           455: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg_replace, 0, 0, 3)
        !           456:        ZEND_ARG_INFO(0, pattern)
        !           457:        ZEND_ARG_INFO(0, replacement)
        !           458:        ZEND_ARG_INFO(0, string)
        !           459:        ZEND_ARG_INFO(0, option)
        !           460: ZEND_END_ARG_INFO()
        !           461: 
        !           462: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_eregi_replace, 0, 0, 3)
        !           463:        ZEND_ARG_INFO(0, pattern)
        !           464:        ZEND_ARG_INFO(0, replacement)
        !           465:        ZEND_ARG_INFO(0, string)
        !           466: ZEND_END_ARG_INFO()
        !           467: 
        !           468: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_split, 0, 0, 2)
        !           469:        ZEND_ARG_INFO(0, pattern)
        !           470:        ZEND_ARG_INFO(0, string)
        !           471:        ZEND_ARG_INFO(0, limit)
        !           472: ZEND_END_ARG_INFO()
        !           473: 
        !           474: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg_match, 0, 0, 2)
        !           475:        ZEND_ARG_INFO(0, pattern)
        !           476:        ZEND_ARG_INFO(0, string)
        !           477:        ZEND_ARG_INFO(0, option)
        !           478: ZEND_END_ARG_INFO()
        !           479: 
        !           480: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg_search, 0, 0, 0)
        !           481:        ZEND_ARG_INFO(0, pattern)
        !           482:        ZEND_ARG_INFO(0, option)
        !           483: ZEND_END_ARG_INFO()
        !           484: 
        !           485: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg_search_pos, 0, 0, 0)
        !           486:        ZEND_ARG_INFO(0, pattern)
        !           487:        ZEND_ARG_INFO(0, option)
        !           488: ZEND_END_ARG_INFO()
        !           489: 
        !           490: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg_search_regs, 0, 0, 0)
        !           491:        ZEND_ARG_INFO(0, pattern)
        !           492:        ZEND_ARG_INFO(0, option)
        !           493: ZEND_END_ARG_INFO()
        !           494: 
        !           495: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg_search_init, 0, 0, 1)
        !           496:        ZEND_ARG_INFO(0, string)
        !           497:        ZEND_ARG_INFO(0, pattern)
        !           498:        ZEND_ARG_INFO(0, option)
        !           499: ZEND_END_ARG_INFO()
        !           500: 
        !           501: ZEND_BEGIN_ARG_INFO(arginfo_mb_ereg_search_getregs, 0)
        !           502: ZEND_END_ARG_INFO()
        !           503: 
        !           504: ZEND_BEGIN_ARG_INFO(arginfo_mb_ereg_search_getpos, 0)
        !           505: ZEND_END_ARG_INFO()
        !           506: 
        !           507: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg_search_setpos, 0, 0, 1)
        !           508:        ZEND_ARG_INFO(0, position)
        !           509: ZEND_END_ARG_INFO()
        !           510: 
        !           511: ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_regex_set_options, 0, 0, 0)
        !           512:        ZEND_ARG_INFO(0, options)
        !           513: ZEND_END_ARG_INFO()
        !           514: /* }}} */
        !           515: 
        !           516: /* {{{ zend_function_entry mbstring_functions[] */
        !           517: const zend_function_entry mbstring_functions[] = {
        !           518:        PHP_FE(mb_convert_case,                 arginfo_mb_convert_case)
        !           519:        PHP_FE(mb_strtoupper,                   arginfo_mb_strtoupper)
        !           520:        PHP_FE(mb_strtolower,                   arginfo_mb_strtolower)
        !           521:        PHP_FE(mb_language,                             arginfo_mb_language)
        !           522:        PHP_FE(mb_internal_encoding,    arginfo_mb_internal_encoding)
        !           523:        PHP_FE(mb_http_input,                   arginfo_mb_http_input)
        !           524:        PHP_FE(mb_http_output,                  arginfo_mb_http_output)
        !           525:        PHP_FE(mb_detect_order,                 arginfo_mb_detect_order)
        !           526:        PHP_FE(mb_substitute_character, arginfo_mb_substitute_character)
        !           527:        PHP_FE(mb_parse_str,                    arginfo_mb_parse_str)
        !           528:        PHP_FE(mb_output_handler,               arginfo_mb_output_handler)
        !           529:        PHP_FE(mb_preferred_mime_name,  arginfo_mb_preferred_mime_name)
        !           530:        PHP_FE(mb_strlen,                               arginfo_mb_strlen)
        !           531:        PHP_FE(mb_strpos,                               arginfo_mb_strpos)
        !           532:        PHP_FE(mb_strrpos,                              arginfo_mb_strrpos)
        !           533:        PHP_FE(mb_stripos,                              arginfo_mb_stripos)
        !           534:        PHP_FE(mb_strripos,                             arginfo_mb_strripos)
        !           535:        PHP_FE(mb_strstr,                               arginfo_mb_strstr)
        !           536:        PHP_FE(mb_strrchr,                              arginfo_mb_strrchr)
        !           537:        PHP_FE(mb_stristr,                              arginfo_mb_stristr)
        !           538:        PHP_FE(mb_strrichr,                             arginfo_mb_strrichr)
        !           539:        PHP_FE(mb_substr_count,                 arginfo_mb_substr_count)
        !           540:        PHP_FE(mb_substr,                               arginfo_mb_substr)
        !           541:        PHP_FE(mb_strcut,                               arginfo_mb_strcut)
        !           542:        PHP_FE(mb_strwidth,                             arginfo_mb_strwidth)
        !           543:        PHP_FE(mb_strimwidth,                   arginfo_mb_strimwidth)
        !           544:        PHP_FE(mb_convert_encoding,             arginfo_mb_convert_encoding)
        !           545:        PHP_FE(mb_detect_encoding,              arginfo_mb_detect_encoding)
        !           546:        PHP_FE(mb_list_encodings,               arginfo_mb_list_encodings)
        !           547:        PHP_FE(mb_encoding_aliases,             arginfo_mb_encoding_aliases)
        !           548:        PHP_FE(mb_convert_kana,                 arginfo_mb_convert_kana)
        !           549:        PHP_FE(mb_encode_mimeheader,    arginfo_mb_encode_mimeheader)
        !           550:        PHP_FE(mb_decode_mimeheader,    arginfo_mb_decode_mimeheader)
        !           551:        PHP_FE(mb_convert_variables,    arginfo_mb_convert_variables)
        !           552:        PHP_FE(mb_encode_numericentity, arginfo_mb_encode_numericentity)
        !           553:        PHP_FE(mb_decode_numericentity, arginfo_mb_decode_numericentity)
        !           554:        PHP_FE(mb_send_mail,                    arginfo_mb_send_mail)
        !           555:        PHP_FE(mb_get_info,                             arginfo_mb_get_info)
        !           556:        PHP_FE(mb_check_encoding,               arginfo_mb_check_encoding)
        !           557: #if HAVE_MBREGEX
        !           558:        PHP_MBREGEX_FUNCTION_ENTRIES
        !           559: #endif
        !           560:        PHP_FE_END
        !           561: };
        !           562: /* }}} */
        !           563: 
        !           564: /* {{{ zend_module_entry mbstring_module_entry */
        !           565: zend_module_entry mbstring_module_entry = {
        !           566:     STANDARD_MODULE_HEADER,
        !           567:        "mbstring",
        !           568:        mbstring_functions,
        !           569:        PHP_MINIT(mbstring),
        !           570:        PHP_MSHUTDOWN(mbstring),
        !           571:        PHP_RINIT(mbstring),
        !           572:        PHP_RSHUTDOWN(mbstring),
        !           573:        PHP_MINFO(mbstring),
        !           574:     NO_VERSION_YET,
        !           575:     PHP_MODULE_GLOBALS(mbstring),
        !           576:     PHP_GINIT(mbstring),
        !           577:     PHP_GSHUTDOWN(mbstring),
        !           578:     NULL,
        !           579:        STANDARD_MODULE_PROPERTIES_EX
        !           580: };
        !           581: /* }}} */
        !           582: 
        !           583: /* {{{ static sapi_post_entry php_post_entries[] */
        !           584: static sapi_post_entry php_post_entries[] = {
        !           585:        { DEFAULT_POST_CONTENT_TYPE, sizeof(DEFAULT_POST_CONTENT_TYPE)-1, sapi_read_standard_form_data, php_std_post_handler },
        !           586:        { MULTIPART_CONTENT_TYPE,    sizeof(MULTIPART_CONTENT_TYPE)-1,    NULL,                         rfc1867_post_handler },
        !           587:        { NULL, 0, NULL, NULL }
        !           588: };
        !           589: /* }}} */
        !           590: 
        !           591: #ifdef COMPILE_DL_MBSTRING
        !           592: ZEND_GET_MODULE(mbstring)
        !           593: #endif
        !           594: 
        !           595: /* {{{ allocators */
        !           596: static void *_php_mb_allocators_malloc(unsigned int sz)
        !           597: {
        !           598:        return emalloc(sz);
        !           599: }
        !           600: 
        !           601: static void *_php_mb_allocators_realloc(void *ptr, unsigned int sz)
        !           602: {
        !           603:        return erealloc(ptr, sz);
        !           604: }
        !           605: 
        !           606: static void *_php_mb_allocators_calloc(unsigned int nelems, unsigned int szelem)
        !           607: {
        !           608:        return ecalloc(nelems, szelem);
        !           609: }
        !           610: 
        !           611: static void _php_mb_allocators_free(void *ptr)
        !           612: {
        !           613:        efree(ptr);
        !           614: } 
        !           615: 
        !           616: static void *_php_mb_allocators_pmalloc(unsigned int sz)
        !           617: {
        !           618:        return pemalloc(sz, 1);
        !           619: }
        !           620: 
        !           621: static void *_php_mb_allocators_prealloc(void *ptr, unsigned int sz)
        !           622: {
        !           623:        return perealloc(ptr, sz, 1);
        !           624: }
        !           625: 
        !           626: static void _php_mb_allocators_pfree(void *ptr)
        !           627: {
        !           628:        pefree(ptr, 1);
        !           629: } 
        !           630: 
        !           631: static mbfl_allocators _php_mb_allocators = {
        !           632:        _php_mb_allocators_malloc,
        !           633:        _php_mb_allocators_realloc,
        !           634:        _php_mb_allocators_calloc,
        !           635:        _php_mb_allocators_free,
        !           636:        _php_mb_allocators_pmalloc,
        !           637:        _php_mb_allocators_prealloc,
        !           638:        _php_mb_allocators_pfree
        !           639: };
        !           640: /* }}} */
        !           641: 
        !           642: /* {{{ static sapi_post_entry mbstr_post_entries[] */
        !           643: static sapi_post_entry mbstr_post_entries[] = {
        !           644:        { DEFAULT_POST_CONTENT_TYPE, sizeof(DEFAULT_POST_CONTENT_TYPE)-1, sapi_read_standard_form_data, php_mb_post_handler },
        !           645:        { MULTIPART_CONTENT_TYPE,    sizeof(MULTIPART_CONTENT_TYPE)-1,    NULL,                         rfc1867_post_handler },
        !           646:        { NULL, 0, NULL, NULL }
        !           647: };
        !           648: /* }}} */
        !           649: 
        !           650: /* {{{ static int php_mb_parse_encoding_list()
        !           651:  *  Return 0 if input contains any illegal encoding, otherwise 1.
        !           652:  *  Even if any illegal encoding is detected the result may contain a list 
        !           653:  *  of parsed encodings.
        !           654:  */
        !           655: static int
        !           656: php_mb_parse_encoding_list(const char *value, int value_length, enum mbfl_no_encoding **return_list, int *return_size, int persistent TSRMLS_DC)
        !           657: {
        !           658:        int n, l, size, bauto, ret = 1;
        !           659:        char *p, *p1, *p2, *endp, *tmpstr;
        !           660:        enum mbfl_no_encoding no_encoding;
        !           661:        enum mbfl_no_encoding *src, *entry, *list;
        !           662: 
        !           663:        list = NULL;
        !           664:        if (value == NULL || value_length <= 0) {
        !           665:                if (return_list) {
        !           666:                        *return_list = NULL;
        !           667:                }
        !           668:                if (return_size) {
        !           669:                        *return_size = 0;
        !           670:                }
        !           671:                return 0;
        !           672:        } else {
        !           673:                enum mbfl_no_encoding *identify_list;
        !           674:                int identify_list_size;
        !           675: 
        !           676:                identify_list = MBSTRG(default_detect_order_list);
        !           677:                identify_list_size = MBSTRG(default_detect_order_list_size);
        !           678: 
        !           679:                /* copy the value string for work */
        !           680:                if (value[0]=='"' && value[value_length-1]=='"' && value_length>2) {
        !           681:                        tmpstr = (char *)estrndup(value+1, value_length-2);
        !           682:                        value_length -= 2;
        !           683:                }
        !           684:                else
        !           685:                        tmpstr = (char *)estrndup(value, value_length);
        !           686:                if (tmpstr == NULL) {
        !           687:                        return 0;
        !           688:                }
        !           689:                /* count the number of listed encoding names */
        !           690:                endp = tmpstr + value_length;
        !           691:                n = 1;
        !           692:                p1 = tmpstr;
        !           693:                while ((p2 = php_memnstr(p1, ",", 1, endp)) != NULL) {
        !           694:                        p1 = p2 + 1;
        !           695:                        n++;
        !           696:                }
        !           697:                size = n + identify_list_size;
        !           698:                /* make list */
        !           699:                list = (enum mbfl_no_encoding *)pecalloc(size, sizeof(int), persistent);
        !           700:                if (list != NULL) {
        !           701:                        entry = list;
        !           702:                        n = 0;
        !           703:                        bauto = 0;
        !           704:                        p1 = tmpstr;
        !           705:                        do {
        !           706:                                p2 = p = php_memnstr(p1, ",", 1, endp);
        !           707:                                if (p == NULL) {
        !           708:                                        p = endp;
        !           709:                                }
        !           710:                                *p = '\0';
        !           711:                                /* trim spaces */
        !           712:                                while (p1 < p && (*p1 == ' ' || *p1 == '\t')) {
        !           713:                                        p1++;
        !           714:                                }
        !           715:                                p--;
        !           716:                                while (p > p1 && (*p == ' ' || *p == '\t')) {
        !           717:                                        *p = '\0';
        !           718:                                        p--;
        !           719:                                }
        !           720:                                /* convert to the encoding number and check encoding */
        !           721:                                if (strcasecmp(p1, "auto") == 0) {
        !           722:                                        if (!bauto) {
        !           723:                                                bauto = 1;
        !           724:                                                l = identify_list_size;
        !           725:                                                src = identify_list;
        !           726:                                                while (l > 0) {
        !           727:                                                        *entry++ = *src++;
        !           728:                                                        l--;
        !           729:                                                        n++;
        !           730:                                                }
        !           731:                                        }
        !           732:                                } else {
        !           733:                                        no_encoding = mbfl_name2no_encoding(p1);
        !           734:                                        if (no_encoding != mbfl_no_encoding_invalid) {
        !           735:                                                *entry++ = no_encoding;
        !           736:                                                n++;
        !           737:                                        } else {
        !           738:                                                ret = 0;
        !           739:                                        }
        !           740:                                }
        !           741:                                p1 = p2 + 1;
        !           742:                        } while (n < size && p2 != NULL);
        !           743:                        if (n > 0) {
        !           744:                                if (return_list) {
        !           745:                                        *return_list = list;
        !           746:                                } else {
        !           747:                                        pefree(list, persistent);
        !           748:                                }
        !           749:                        } else {
        !           750:                                pefree(list, persistent);
        !           751:                                if (return_list) {
        !           752:                                        *return_list = NULL;
        !           753:                                }
        !           754:                                ret = 0;
        !           755:                        }
        !           756:                        if (return_size) {
        !           757:                                *return_size = n;
        !           758:                        }
        !           759:                } else {
        !           760:                        if (return_list) {
        !           761:                                *return_list = NULL;
        !           762:                        }
        !           763:                        if (return_size) {
        !           764:                                *return_size = 0;
        !           765:                        }
        !           766:                        ret = 0;
        !           767:                }
        !           768:                efree(tmpstr);
        !           769:        }
        !           770: 
        !           771:        return ret;
        !           772: }
        !           773: /* }}} */
        !           774: 
        !           775: /* {{{ MBSTRING_API php_mb_check_encoding_list */
        !           776: MBSTRING_API int php_mb_check_encoding_list(const char *encoding_list TSRMLS_DC) {
        !           777:        return php_mb_parse_encoding_list(encoding_list, strlen(encoding_list), NULL, NULL, 0 TSRMLS_CC);       
        !           778: }
        !           779: /* }}} */
        !           780: 
        !           781: /* {{{ static int php_mb_parse_encoding_array()
        !           782:  *  Return 0 if input contains any illegal encoding, otherwise 1.
        !           783:  *  Even if any illegal encoding is detected the result may contain a list 
        !           784:  *  of parsed encodings.
        !           785:  */
        !           786: static int
        !           787: php_mb_parse_encoding_array(zval *array, enum mbfl_no_encoding **return_list, int *return_size, int persistent TSRMLS_DC)
        !           788: {
        !           789:        zval **hash_entry;
        !           790:        HashTable *target_hash;
        !           791:        int i, n, l, size, bauto,ret = 1;
        !           792:        enum mbfl_no_encoding no_encoding;
        !           793:        enum mbfl_no_encoding *src, *list, *entry;
        !           794: 
        !           795:        list = NULL;
        !           796:        if (Z_TYPE_P(array) == IS_ARRAY) {
        !           797:                enum mbfl_no_encoding *identify_list;
        !           798:                int identify_list_size;
        !           799: 
        !           800:                identify_list = MBSTRG(default_detect_order_list);
        !           801:                identify_list_size = MBSTRG(default_detect_order_list_size);
        !           802: 
        !           803:                target_hash = Z_ARRVAL_P(array);
        !           804:                zend_hash_internal_pointer_reset(target_hash);
        !           805:                i = zend_hash_num_elements(target_hash);
        !           806:                size = i + identify_list_size;
        !           807:                list = (enum mbfl_no_encoding *)pecalloc(size, sizeof(int), persistent);
        !           808:                if (list != NULL) {
        !           809:                        entry = list;
        !           810:                        bauto = 0;
        !           811:                        n = 0;
        !           812:                        while (i > 0) {
        !           813:                                if (zend_hash_get_current_data(target_hash, (void **) &hash_entry) == FAILURE) {
        !           814:                                        break;
        !           815:                                }
        !           816:                                convert_to_string_ex(hash_entry);
        !           817:                                if (strcasecmp(Z_STRVAL_PP(hash_entry), "auto") == 0) {
        !           818:                                        if (!bauto) {
        !           819:                                                bauto = 1;
        !           820:                                                l = identify_list_size; 
        !           821:                                                src = identify_list;
        !           822:                                                while (l > 0) {
        !           823:                                                        *entry++ = *src++;
        !           824:                                                        l--;
        !           825:                                                        n++;
        !           826:                                                }
        !           827:                                        }
        !           828:                                } else {
        !           829:                                        no_encoding = mbfl_name2no_encoding(Z_STRVAL_PP(hash_entry));
        !           830:                                        if (no_encoding != mbfl_no_encoding_invalid) {
        !           831:                                                *entry++ = no_encoding;
        !           832:                                                n++;
        !           833:                                        } else {
        !           834:                                                ret = 0;
        !           835:                                        }
        !           836:                                }
        !           837:                                zend_hash_move_forward(target_hash);
        !           838:                                i--;
        !           839:                        }
        !           840:                        if (n > 0) {
        !           841:                                if (return_list) {
        !           842:                                        *return_list = list;
        !           843:                                } else {
        !           844:                                        pefree(list, persistent);
        !           845:                                }
        !           846:                        } else {
        !           847:                                pefree(list, persistent);
        !           848:                                if (return_list) {
        !           849:                                        *return_list = NULL;
        !           850:                                }
        !           851:                                ret = 0;
        !           852:                        }
        !           853:                        if (return_size) {
        !           854:                                *return_size = n;
        !           855:                        }
        !           856:                } else {
        !           857:                        if (return_list) {
        !           858:                                *return_list = NULL;
        !           859:                        }
        !           860:                        if (return_size) {
        !           861:                                *return_size = 0;
        !           862:                        }
        !           863:                        ret = 0;
        !           864:                }
        !           865:        }
        !           866: 
        !           867:        return ret;
        !           868: }
        !           869: /* }}} */
        !           870: 
        !           871: static void *_php_mb_compile_regex(const char *pattern TSRMLS_DC);
        !           872: static int _php_mb_match_regex(void *opaque, const char *str, size_t str_len);
        !           873: static void _php_mb_free_regex(void *opaque);
        !           874: 
        !           875: #if HAVE_ONIG
        !           876: /* {{{ _php_mb_compile_regex */
        !           877: static void *_php_mb_compile_regex(const char *pattern TSRMLS_DC)
        !           878: {
        !           879:        php_mb_regex_t *retval;
        !           880:        OnigErrorInfo err_info;
        !           881:        int err_code;
        !           882: 
        !           883:        if ((err_code = onig_new(&retval,
        !           884:                        (const OnigUChar *)pattern,
        !           885:                        (const OnigUChar *)pattern + strlen(pattern),
        !           886:                        ONIG_OPTION_IGNORECASE | ONIG_OPTION_DONT_CAPTURE_GROUP,
        !           887:                        ONIG_ENCODING_ASCII, &OnigSyntaxPerl, &err_info))) {
        !           888:                OnigUChar err_str[ONIG_MAX_ERROR_MESSAGE_LEN];
        !           889:                onig_error_code_to_str(err_str, err_code, err_info);
        !           890:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: %s", pattern, err_str);
        !           891:                retval = NULL;
        !           892:        }
        !           893:        return retval;
        !           894: }
        !           895: /* }}} */
        !           896: 
        !           897: /* {{{ _php_mb_match_regex */
        !           898: static int _php_mb_match_regex(void *opaque, const char *str, size_t str_len)
        !           899: {
        !           900:        return onig_search((php_mb_regex_t *)opaque, (const OnigUChar *)str,
        !           901:                        (const OnigUChar*)str + str_len, (const OnigUChar *)str,
        !           902:                        (const OnigUChar*)str + str_len, NULL, ONIG_OPTION_NONE) >= 0;
        !           903: }
        !           904: /* }}} */
        !           905: 
        !           906: /* {{{ _php_mb_free_regex */
        !           907: static void _php_mb_free_regex(void *opaque)
        !           908: {
        !           909:        onig_free((php_mb_regex_t *)opaque);
        !           910: }
        !           911: /* }}} */
        !           912: #elif HAVE_PCRE || HAVE_BUNDLED_PCRE
        !           913: /* {{{ _php_mb_compile_regex */
        !           914: static void *_php_mb_compile_regex(const char *pattern TSRMLS_DC)
        !           915: {
        !           916:        pcre *retval;
        !           917:        const char *err_str;
        !           918:        int err_offset;
        !           919: 
        !           920:        if (!(retval = pcre_compile(pattern,
        !           921:                        PCRE_CASELESS, &err_str, &err_offset, NULL))) {
        !           922:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (offset=%d): %s", pattern, err_offset, err_str);
        !           923:        }
        !           924:        return retval;
        !           925: }
        !           926: /* }}} */
        !           927: 
        !           928: /* {{{ _php_mb_match_regex */
        !           929: static int _php_mb_match_regex(void *opaque, const char *str, size_t str_len)
        !           930: {
        !           931:        return pcre_exec((pcre *)opaque, NULL, str, (int)str_len, 0,
        !           932:                        0, NULL, 0) >= 0;
        !           933: }
        !           934: /* }}} */
        !           935: 
        !           936: /* {{{ _php_mb_free_regex */
        !           937: static void _php_mb_free_regex(void *opaque)
        !           938: {
        !           939:        pcre_free(opaque);
        !           940: }
        !           941: /* }}} */
        !           942: #endif
        !           943: 
        !           944: /* {{{ php_mb_nls_get_default_detect_order_list */
        !           945: static int php_mb_nls_get_default_detect_order_list(enum mbfl_no_language lang, enum mbfl_no_encoding **plist, int* plist_size)
        !           946: {
        !           947:        size_t i;
        !           948: 
        !           949:        *plist = (enum mbfl_no_encoding *) php_mb_default_identify_list_neut;
        !           950:        *plist_size = sizeof(php_mb_default_identify_list_neut) / sizeof(php_mb_default_identify_list_neut[0]);
        !           951: 
        !           952:        for (i = 0; i < sizeof(php_mb_default_identify_list) / sizeof(php_mb_default_identify_list[0]); i++) {
        !           953:                if (php_mb_default_identify_list[i].lang == lang) {
        !           954:                        *plist = (enum mbfl_no_encoding *)php_mb_default_identify_list[i].list;
        !           955:                        *plist_size = php_mb_default_identify_list[i].list_size;
        !           956:                        return 1;
        !           957:                }
        !           958:        }
        !           959:        return 0;
        !           960: }
        !           961: /* }}} */
        !           962: 
        !           963: /* {{{ php.ini directive handler */
        !           964: /* {{{ static PHP_INI_MH(OnUpdate_mbstring_language) */
        !           965: static PHP_INI_MH(OnUpdate_mbstring_language)
        !           966: {
        !           967:        enum mbfl_no_language no_language;
        !           968: 
        !           969:        no_language = mbfl_name2no_language(new_value);
        !           970:        if (no_language == mbfl_no_language_invalid) {
        !           971:                MBSTRG(language) = mbfl_no_language_neutral;
        !           972:                return FAILURE;
        !           973:        }
        !           974:        MBSTRG(language) = no_language;
        !           975:        php_mb_nls_get_default_detect_order_list(no_language, &MBSTRG(default_detect_order_list), &MBSTRG(default_detect_order_list_size));
        !           976:        return SUCCESS;
        !           977: }
        !           978: /* }}} */
        !           979: 
        !           980: /* {{{ static PHP_INI_MH(OnUpdate_mbstring_detect_order) */
        !           981: static PHP_INI_MH(OnUpdate_mbstring_detect_order)
        !           982: {
        !           983:        enum mbfl_no_encoding *list;
        !           984:        int size;
        !           985: 
        !           986:        if (php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1 TSRMLS_CC)) {
        !           987:                if (MBSTRG(detect_order_list)) {
        !           988:                        free(MBSTRG(detect_order_list));
        !           989:                }
        !           990:                MBSTRG(detect_order_list) = list;
        !           991:                MBSTRG(detect_order_list_size) = size;
        !           992:        } else {
        !           993:                if (MBSTRG(detect_order_list)) {
        !           994:                        free(MBSTRG(detect_order_list));
        !           995:                        MBSTRG(detect_order_list) = NULL;
        !           996:                }
        !           997:                return FAILURE;
        !           998:        }
        !           999: 
        !          1000:        return SUCCESS;
        !          1001: }
        !          1002: /* }}} */
        !          1003: 
        !          1004: /* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_input) */
        !          1005: static PHP_INI_MH(OnUpdate_mbstring_http_input)
        !          1006: {
        !          1007:        enum mbfl_no_encoding *list;
        !          1008:        int size;
        !          1009: 
        !          1010:        if (php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1 TSRMLS_CC)) {
        !          1011:                if (MBSTRG(http_input_list)) {
        !          1012:                        free(MBSTRG(http_input_list));
        !          1013:                }
        !          1014:                MBSTRG(http_input_list) = list;
        !          1015:                MBSTRG(http_input_list_size) = size;
        !          1016:        } else {
        !          1017:                if (MBSTRG(http_input_list)) {
        !          1018:                        free(MBSTRG(http_input_list));
        !          1019:                        MBSTRG(http_input_list) = NULL;
        !          1020:                }
        !          1021:                MBSTRG(http_input_list_size) = 0;
        !          1022:                return FAILURE;
        !          1023:        }
        !          1024: 
        !          1025:        return SUCCESS;
        !          1026: }
        !          1027: /* }}} */
        !          1028: 
        !          1029: /* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_output) */
        !          1030: static PHP_INI_MH(OnUpdate_mbstring_http_output)
        !          1031: {
        !          1032:        enum mbfl_no_encoding no_encoding;
        !          1033: 
        !          1034:        no_encoding = mbfl_name2no_encoding(new_value);
        !          1035:        if (no_encoding != mbfl_no_encoding_invalid) {
        !          1036:                MBSTRG(http_output_encoding) = no_encoding;
        !          1037:                MBSTRG(current_http_output_encoding) = no_encoding;
        !          1038:        } else {
        !          1039:                MBSTRG(http_output_encoding) = mbfl_no_encoding_pass;
        !          1040:                MBSTRG(current_http_output_encoding) = mbfl_no_encoding_pass;
        !          1041:                if (new_value != NULL && new_value_length > 0) {
        !          1042:                        return FAILURE;
        !          1043:                }
        !          1044:        }
        !          1045: 
        !          1046:        return SUCCESS;
        !          1047: }
        !          1048: /* }}} */
        !          1049: 
        !          1050: /* {{{ static _php_mb_ini_mbstring_internal_encoding_set */
        !          1051: int _php_mb_ini_mbstring_internal_encoding_set(const char *new_value, uint new_value_length TSRMLS_DC)
        !          1052: {
        !          1053:        enum mbfl_no_encoding no_encoding;
        !          1054:        const char *enc_name = NULL;
        !          1055:        uint enc_name_len = 0;
        !          1056:    
        !          1057:        no_encoding = new_value ? mbfl_name2no_encoding(new_value):
        !          1058:                                mbfl_no_encoding_invalid;
        !          1059:        if (no_encoding != mbfl_no_encoding_invalid) {
        !          1060:                enc_name = new_value;
        !          1061:                enc_name_len = new_value_length;
        !          1062:        } else {
        !          1063:                switch (MBSTRG(language)) {
        !          1064:                        case mbfl_no_language_uni:
        !          1065:                                enc_name = "UTF-8";
        !          1066:                                enc_name_len = sizeof("UTF-8") - 1;
        !          1067:                                break;
        !          1068:                        case mbfl_no_language_japanese:
        !          1069:                                enc_name = "EUC-JP";
        !          1070:                                enc_name_len = sizeof("EUC-JP") - 1;
        !          1071:                                break;
        !          1072:                        case mbfl_no_language_korean:
        !          1073:                                enc_name = "EUC-KR";
        !          1074:                                enc_name_len = sizeof("EUC-KR") - 1;
        !          1075:                                break;
        !          1076:                        case mbfl_no_language_simplified_chinese:
        !          1077:                                enc_name = "EUC-CN";
        !          1078:                                enc_name_len = sizeof("EUC-CN") - 1;
        !          1079:                                break;
        !          1080:                        case mbfl_no_language_traditional_chinese:
        !          1081:                                enc_name = "EUC-TW";
        !          1082:                                enc_name_len = sizeof("EUC-TW") - 1;
        !          1083:                                break;
        !          1084:                        case mbfl_no_language_russian:
        !          1085:                                enc_name = "KOI8-R";
        !          1086:                                enc_name_len = sizeof("KOI8-R") - 1;
        !          1087:                                break;
        !          1088:                        case mbfl_no_language_german:
        !          1089:                                enc_name = "ISO-8859-15";
        !          1090:                                enc_name_len = sizeof("ISO-8859-15") - 1;
        !          1091:                                break;
        !          1092:                        case mbfl_no_language_armenian:
        !          1093:                                enc_name = "ArmSCII-8";
        !          1094:                                enc_name_len = sizeof("ArmSCII-8") - 1;
        !          1095:                                break;
        !          1096:                        case mbfl_no_language_turkish:
        !          1097:                                enc_name = "ISO-8859-9";
        !          1098:                                enc_name_len = sizeof("ISO-8859-9") - 1;
        !          1099:                                break;
        !          1100:                        default:
        !          1101:                                enc_name = "ISO-8859-1";
        !          1102:                                enc_name_len = sizeof("ISO-8859-1") - 1;
        !          1103:                                break;
        !          1104:                }
        !          1105:                no_encoding = mbfl_name2no_encoding(enc_name);
        !          1106:        }
        !          1107:        MBSTRG(internal_encoding) = no_encoding;
        !          1108:        MBSTRG(current_internal_encoding) = no_encoding;
        !          1109: #if HAVE_MBREGEX
        !          1110:        {
        !          1111:                const char *enc_name = new_value;
        !          1112:                if (FAILURE == php_mb_regex_set_default_mbctype(enc_name TSRMLS_CC)) {
        !          1113:                        /* falls back to EUC-JP if an unknown encoding name is given */
        !          1114:                        enc_name = "EUC-JP";
        !          1115:                        php_mb_regex_set_default_mbctype(enc_name TSRMLS_CC);
        !          1116:                }
        !          1117:                php_mb_regex_set_mbctype(new_value TSRMLS_CC);
        !          1118:        }
        !          1119: #endif
        !          1120:        return SUCCESS;
        !          1121: }
        !          1122: /* }}} */
        !          1123: 
        !          1124: /* {{{ static PHP_INI_MH(OnUpdate_mbstring_internal_encoding) */
        !          1125: static PHP_INI_MH(OnUpdate_mbstring_internal_encoding)
        !          1126: {
        !          1127:        if (stage == PHP_INI_STAGE_STARTUP || stage == PHP_INI_STAGE_SHUTDOWN
        !          1128:                        || stage == PHP_INI_STAGE_RUNTIME) {
        !          1129:                return _php_mb_ini_mbstring_internal_encoding_set(new_value, new_value_length TSRMLS_CC);
        !          1130:        } else {
        !          1131:                /* the corresponding mbstring globals needs to be set according to the
        !          1132:                 * ini value in the later stage because it never falls back to the
        !          1133:                 * default value if 1. no value for mbstring.internal_encoding is given,
        !          1134:                 * 2. mbstring.language directive is processed in per-dir or runtime
        !          1135:                 * context and 3. call to the handler for mbstring.language is done
        !          1136:                 * after mbstring.internal_encoding is handled. */
        !          1137:                return SUCCESS;
        !          1138:        }
        !          1139: }
        !          1140: /* }}} */
        !          1141: 
        !          1142: #ifdef ZEND_MULTIBYTE
        !          1143: /* {{{ static PHP_INI_MH(OnUpdate_mbstring_script_encoding) */
        !          1144: static PHP_INI_MH(OnUpdate_mbstring_script_encoding)
        !          1145: {
        !          1146:        int *list, size;
        !          1147: 
        !          1148:        if (php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1 TSRMLS_CC)) {
        !          1149:                if (MBSTRG(script_encoding_list) != NULL) {
        !          1150:                        free(MBSTRG(script_encoding_list));
        !          1151:                }
        !          1152:                MBSTRG(script_encoding_list) = list;
        !          1153:                MBSTRG(script_encoding_list_size) = size;
        !          1154:        } else {
        !          1155:                if (MBSTRG(script_encoding_list) != NULL) {
        !          1156:                        free(MBSTRG(script_encoding_list));
        !          1157:                }
        !          1158:                MBSTRG(script_encoding_list) = NULL;
        !          1159:                MBSTRG(script_encoding_list_size) = 0;
        !          1160:                return FAILURE;
        !          1161:        }
        !          1162: 
        !          1163:        return SUCCESS;
        !          1164: }
        !          1165: /* }}} */
        !          1166: #endif /* ZEND_MULTIBYTE */
        !          1167: 
        !          1168: /* {{{ static PHP_INI_MH(OnUpdate_mbstring_substitute_character) */
        !          1169: static PHP_INI_MH(OnUpdate_mbstring_substitute_character)
        !          1170: {
        !          1171:        int c;
        !          1172:        char *endptr = NULL;
        !          1173: 
        !          1174:        if (new_value != NULL) {
        !          1175:                if (strcasecmp("none", new_value) == 0) {
        !          1176:                        MBSTRG(filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE;
        !          1177:                        MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE;
        !          1178:                } else if (strcasecmp("long", new_value) == 0) {
        !          1179:                        MBSTRG(filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_LONG;
        !          1180:                        MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_LONG;
        !          1181:                } else if (strcasecmp("entity", new_value) == 0) {
        !          1182:                        MBSTRG(filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_ENTITY;
        !          1183:                        MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_ENTITY;
        !          1184:                } else {
        !          1185:                        MBSTRG(filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR;
        !          1186:                        MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR;
        !          1187:                        if (new_value_length >0) {
        !          1188:                                c = strtol(new_value, &endptr, 0);
        !          1189:                                if (*endptr == '\0') {
        !          1190:                                        MBSTRG(filter_illegal_substchar) = c;
        !          1191:                                        MBSTRG(current_filter_illegal_substchar) = c;
        !          1192:                                }
        !          1193:                        }
        !          1194:                }
        !          1195:        } else {
        !          1196:                MBSTRG(filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR;
        !          1197:                MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR;
        !          1198:                MBSTRG(filter_illegal_substchar) = 0x3f;        /* '?' */
        !          1199:                MBSTRG(current_filter_illegal_substchar) = 0x3f;        /* '?' */
        !          1200:        }
        !          1201: 
        !          1202:        return SUCCESS;
        !          1203: }
        !          1204: /* }}} */
        !          1205: 
        !          1206: /* {{{ static PHP_INI_MH(OnUpdate_mbstring_encoding_translation) */
        !          1207: static PHP_INI_MH(OnUpdate_mbstring_encoding_translation)
        !          1208: {
        !          1209:        if (new_value == NULL) {
        !          1210:           return FAILURE;
        !          1211:        }
        !          1212: 
        !          1213:        OnUpdateBool(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
        !          1214: 
        !          1215:        if (MBSTRG(encoding_translation)) {
        !          1216:                sapi_unregister_post_entry(php_post_entries TSRMLS_CC);
        !          1217:                sapi_register_post_entries(mbstr_post_entries TSRMLS_CC);
        !          1218:        } else {
        !          1219:                sapi_unregister_post_entry(mbstr_post_entries TSRMLS_CC);
        !          1220:                sapi_register_post_entries(php_post_entries TSRMLS_CC);
        !          1221:        }
        !          1222: 
        !          1223:        return SUCCESS;
        !          1224: }
        !          1225: /* }}} */
        !          1226: 
        !          1227: /* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_output_conv_mimetypes */
        !          1228: static PHP_INI_MH(OnUpdate_mbstring_http_output_conv_mimetypes)
        !          1229: {
        !          1230:        zval tmp;
        !          1231:        void *re = NULL;
        !          1232: 
        !          1233:        if (!new_value) {
        !          1234:                new_value = entry->orig_value;
        !          1235:                new_value_length = entry->orig_value_length;
        !          1236:        }
        !          1237:        php_trim(new_value, new_value_length, NULL, 0, &tmp, 3 TSRMLS_CC);
        !          1238: 
        !          1239:        if (Z_STRLEN(tmp) > 0) {
        !          1240:                if (!(re = _php_mb_compile_regex(Z_STRVAL(tmp) TSRMLS_CC))) {
        !          1241:                        zval_dtor(&tmp);
        !          1242:                        return FAILURE;
        !          1243:                }
        !          1244:        }
        !          1245: 
        !          1246:        if (MBSTRG(http_output_conv_mimetypes)) {
        !          1247:                _php_mb_free_regex(MBSTRG(http_output_conv_mimetypes));
        !          1248:        }
        !          1249: 
        !          1250:        MBSTRG(http_output_conv_mimetypes) = re;
        !          1251: 
        !          1252:        zval_dtor(&tmp);
        !          1253:        return SUCCESS;
        !          1254: }
        !          1255: /* }}} */
        !          1256: /* }}} */
        !          1257: 
        !          1258: /* {{{ php.ini directive registration */
        !          1259: PHP_INI_BEGIN()
        !          1260:        PHP_INI_ENTRY("mbstring.language", "neutral", PHP_INI_ALL, OnUpdate_mbstring_language)
        !          1261:        PHP_INI_ENTRY("mbstring.detect_order", NULL, PHP_INI_ALL, OnUpdate_mbstring_detect_order)
        !          1262:        PHP_INI_ENTRY("mbstring.http_input", "pass", PHP_INI_ALL, OnUpdate_mbstring_http_input)
        !          1263:        PHP_INI_ENTRY("mbstring.http_output", "pass", PHP_INI_ALL, OnUpdate_mbstring_http_output)
        !          1264:        PHP_INI_ENTRY("mbstring.internal_encoding", NULL, PHP_INI_ALL, OnUpdate_mbstring_internal_encoding)
        !          1265: #ifdef ZEND_MULTIBYTE
        !          1266:        PHP_INI_ENTRY("mbstring.script_encoding", NULL, PHP_INI_ALL, OnUpdate_mbstring_script_encoding)
        !          1267: #endif /* ZEND_MULTIBYTE */
        !          1268:        PHP_INI_ENTRY("mbstring.substitute_character", NULL, PHP_INI_ALL, OnUpdate_mbstring_substitute_character)
        !          1269:        STD_PHP_INI_ENTRY("mbstring.func_overload", "0", 
        !          1270:        PHP_INI_SYSTEM, OnUpdateLong, func_overload, zend_mbstring_globals, mbstring_globals)
        !          1271: 
        !          1272:        STD_PHP_INI_BOOLEAN("mbstring.encoding_translation", "0",
        !          1273:                PHP_INI_SYSTEM | PHP_INI_PERDIR,
        !          1274:                OnUpdate_mbstring_encoding_translation, 
        !          1275:                encoding_translation, zend_mbstring_globals, mbstring_globals)                                   
        !          1276:        PHP_INI_ENTRY("mbstring.http_output_conv_mimetypes",
        !          1277:                "^(text/|application/xhtml\\+xml)",
        !          1278:                PHP_INI_ALL,
        !          1279:                OnUpdate_mbstring_http_output_conv_mimetypes)
        !          1280: 
        !          1281:        STD_PHP_INI_BOOLEAN("mbstring.strict_detection", "0",
        !          1282:                PHP_INI_ALL,
        !          1283:                OnUpdateLong,
        !          1284:                strict_detection, zend_mbstring_globals, mbstring_globals)
        !          1285: PHP_INI_END()
        !          1286: /* }}} */
        !          1287: 
        !          1288: /* {{{ module global initialize handler */
        !          1289: static PHP_GINIT_FUNCTION(mbstring)
        !          1290: {
        !          1291:        mbstring_globals->language = mbfl_no_language_uni;
        !          1292:        mbstring_globals->internal_encoding = mbfl_no_encoding_invalid;
        !          1293:        mbstring_globals->current_internal_encoding = mbstring_globals->internal_encoding;
        !          1294: #ifdef ZEND_MULTIBYTE
        !          1295:        mbstring_globals->script_encoding_list = NULL;
        !          1296:        mbstring_globals->script_encoding_list_size = 0;
        !          1297: #endif /* ZEND_MULTIBYTE */
        !          1298:        mbstring_globals->http_output_encoding = mbfl_no_encoding_pass;
        !          1299:        mbstring_globals->current_http_output_encoding = mbfl_no_encoding_pass;
        !          1300:        mbstring_globals->http_input_identify = mbfl_no_encoding_invalid;
        !          1301:        mbstring_globals->http_input_identify_get = mbfl_no_encoding_invalid;
        !          1302:        mbstring_globals->http_input_identify_post = mbfl_no_encoding_invalid;
        !          1303:        mbstring_globals->http_input_identify_cookie = mbfl_no_encoding_invalid;
        !          1304:        mbstring_globals->http_input_identify_string = mbfl_no_encoding_invalid;
        !          1305:        mbstring_globals->http_input_list = NULL;
        !          1306:        mbstring_globals->http_input_list_size = 0;
        !          1307:        mbstring_globals->detect_order_list = NULL;
        !          1308:        mbstring_globals->detect_order_list_size = 0;
        !          1309:        mbstring_globals->current_detect_order_list = NULL;
        !          1310:        mbstring_globals->current_detect_order_list_size = 0;
        !          1311:        mbstring_globals->default_detect_order_list = (enum mbfl_no_encoding *) php_mb_default_identify_list_neut;
        !          1312:        mbstring_globals->default_detect_order_list_size = sizeof(php_mb_default_identify_list_neut) / sizeof(php_mb_default_identify_list_neut[0]);
        !          1313:        mbstring_globals->filter_illegal_mode = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR;
        !          1314:        mbstring_globals->filter_illegal_substchar = 0x3f;      /* '?' */
        !          1315:        mbstring_globals->current_filter_illegal_mode = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR;
        !          1316:        mbstring_globals->current_filter_illegal_substchar = 0x3f;      /* '?' */
        !          1317:        mbstring_globals->illegalchars = 0;
        !          1318:        mbstring_globals->func_overload = 0;
        !          1319:        mbstring_globals->encoding_translation = 0;
        !          1320:        mbstring_globals->strict_detection = 0;
        !          1321:        mbstring_globals->outconv = NULL;
        !          1322:        mbstring_globals->http_output_conv_mimetypes = NULL;
        !          1323: #if HAVE_MBREGEX
        !          1324:        mbstring_globals->mb_regex_globals = php_mb_regex_globals_alloc(TSRMLS_C);
        !          1325: #endif
        !          1326: }
        !          1327: /* }}} */
        !          1328: 
        !          1329: /* {{{ PHP_GSHUTDOWN_FUNCTION */
        !          1330: static PHP_GSHUTDOWN_FUNCTION(mbstring)
        !          1331: {
        !          1332:        if (mbstring_globals->http_input_list) {
        !          1333:                free(mbstring_globals->http_input_list);
        !          1334:        }
        !          1335: #ifdef ZEND_MULTIBYTE
        !          1336:        if (mbstring_globals->script_encoding_list) {
        !          1337:                free(mbstring_globals->script_encoding_list);
        !          1338:        }
        !          1339: #endif /* ZEND_MULTIBYTE */
        !          1340:        if (mbstring_globals->detect_order_list) {
        !          1341:                free(mbstring_globals->detect_order_list);
        !          1342:        }
        !          1343:        if (mbstring_globals->http_output_conv_mimetypes) {
        !          1344:                _php_mb_free_regex(mbstring_globals->http_output_conv_mimetypes);
        !          1345:        }
        !          1346: #if HAVE_MBREGEX
        !          1347:        php_mb_regex_globals_free(mbstring_globals->mb_regex_globals TSRMLS_CC);
        !          1348: #endif
        !          1349: }
        !          1350: /* }}} */
        !          1351: 
        !          1352: /* {{{ PHP_MINIT_FUNCTION(mbstring) */
        !          1353: PHP_MINIT_FUNCTION(mbstring)
        !          1354: {
        !          1355:        __mbfl_allocators = &_php_mb_allocators;
        !          1356: 
        !          1357:        REGISTER_INI_ENTRIES();
        !          1358: 
        !          1359:        /* This is a global handler. Should not be set in a per-request handler. */
        !          1360:        sapi_register_treat_data(mbstr_treat_data);
        !          1361: 
        !          1362:        /* Post handlers are stored in the thread-local context. */
        !          1363:        if (MBSTRG(encoding_translation)) {
        !          1364:                sapi_register_post_entries(mbstr_post_entries TSRMLS_CC);
        !          1365:        }
        !          1366: 
        !          1367:        REGISTER_LONG_CONSTANT("MB_OVERLOAD_MAIL", MB_OVERLOAD_MAIL, CONST_CS | CONST_PERSISTENT);
        !          1368:        REGISTER_LONG_CONSTANT("MB_OVERLOAD_STRING", MB_OVERLOAD_STRING, CONST_CS | CONST_PERSISTENT);
        !          1369:        REGISTER_LONG_CONSTANT("MB_OVERLOAD_REGEX", MB_OVERLOAD_REGEX, CONST_CS | CONST_PERSISTENT);
        !          1370: 
        !          1371:        REGISTER_LONG_CONSTANT("MB_CASE_UPPER", PHP_UNICODE_CASE_UPPER, CONST_CS | CONST_PERSISTENT);
        !          1372:        REGISTER_LONG_CONSTANT("MB_CASE_LOWER", PHP_UNICODE_CASE_LOWER, CONST_CS | CONST_PERSISTENT);
        !          1373:        REGISTER_LONG_CONSTANT("MB_CASE_TITLE", PHP_UNICODE_CASE_TITLE, CONST_CS | CONST_PERSISTENT);
        !          1374: 
        !          1375: #if HAVE_MBREGEX
        !          1376:        PHP_MINIT(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);
        !          1377: #endif
        !          1378:        return SUCCESS;
        !          1379: }
        !          1380: /* }}} */
        !          1381: 
        !          1382: /* {{{ PHP_MSHUTDOWN_FUNCTION(mbstring) */
        !          1383: PHP_MSHUTDOWN_FUNCTION(mbstring)
        !          1384: {
        !          1385:        UNREGISTER_INI_ENTRIES();
        !          1386:        
        !          1387: #if HAVE_MBREGEX
        !          1388:        PHP_MSHUTDOWN(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);
        !          1389: #endif
        !          1390: 
        !          1391:        return SUCCESS;
        !          1392: }
        !          1393: /* }}} */
        !          1394: 
        !          1395: /* {{{ PHP_RINIT_FUNCTION(mbstring) */
        !          1396: PHP_RINIT_FUNCTION(mbstring)
        !          1397: {
        !          1398:        int n;
        !          1399:        enum mbfl_no_encoding *list=NULL, *entry;
        !          1400:        zend_function *func, *orig;
        !          1401:        const struct mb_overload_def *p;
        !          1402: 
        !          1403:        MBSTRG(current_internal_encoding) = MBSTRG(internal_encoding);
        !          1404:        MBSTRG(current_http_output_encoding) = MBSTRG(http_output_encoding);
        !          1405:        MBSTRG(current_filter_illegal_mode) = MBSTRG(filter_illegal_mode);
        !          1406:        MBSTRG(current_filter_illegal_substchar) = MBSTRG(filter_illegal_substchar);
        !          1407: 
        !          1408:        MBSTRG(illegalchars) = 0;
        !          1409: 
        !          1410:        n = 0;
        !          1411:        if (MBSTRG(detect_order_list)) {
        !          1412:                list = MBSTRG(detect_order_list);
        !          1413:                n = MBSTRG(detect_order_list_size);
        !          1414:        }
        !          1415:        if (n <= 0) {
        !          1416:                list = MBSTRG(default_detect_order_list);
        !          1417:                n = MBSTRG(default_detect_order_list_size);
        !          1418:        }
        !          1419:        entry = (enum mbfl_no_encoding *)safe_emalloc(n, sizeof(int), 0);
        !          1420:        MBSTRG(current_detect_order_list) = entry;
        !          1421:        MBSTRG(current_detect_order_list_size) = n;
        !          1422:        while (n > 0) {
        !          1423:                *entry++ = *list++;
        !          1424:                n--;
        !          1425:        }
        !          1426: 
        !          1427:        /* override original function. */
        !          1428:        if (MBSTRG(func_overload)){
        !          1429:                p = &(mb_ovld[0]);
        !          1430:                
        !          1431:                while (p->type > 0) {
        !          1432:                        if ((MBSTRG(func_overload) & p->type) == p->type && 
        !          1433:                                zend_hash_find(EG(function_table), p->save_func,
        !          1434:                                        strlen(p->save_func)+1, (void **)&orig) != SUCCESS) {
        !          1435: 
        !          1436:                                zend_hash_find(EG(function_table), p->ovld_func, strlen(p->ovld_func)+1 , (void **)&func);
        !          1437:                                
        !          1438:                                if (zend_hash_find(EG(function_table), p->orig_func, strlen(p->orig_func)+1, (void **)&orig) != SUCCESS) {
        !          1439:                                        php_error_docref("ref.mbstring" TSRMLS_CC, E_WARNING, "mbstring couldn't find function %s.", p->orig_func);
        !          1440:                                        return FAILURE;
        !          1441:                                } else {
        !          1442:                                        zend_hash_add(EG(function_table), p->save_func, strlen(p->save_func)+1, orig, sizeof(zend_function), NULL);
        !          1443: 
        !          1444:                                        if (zend_hash_update(EG(function_table), p->orig_func, strlen(p->orig_func)+1, func, sizeof(zend_function), 
        !          1445:                                                NULL) == FAILURE) {
        !          1446:                                                php_error_docref("ref.mbstring" TSRMLS_CC, E_WARNING, "mbstring couldn't replace function %s.", p->orig_func);
        !          1447:                                                return FAILURE;
        !          1448:                                        }
        !          1449:                                }
        !          1450:                        }
        !          1451:                        p++;
        !          1452:                }
        !          1453:        }
        !          1454: #if HAVE_MBREGEX
        !          1455:        PHP_RINIT(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);
        !          1456: #endif
        !          1457: #ifdef ZEND_MULTIBYTE
        !          1458:        zend_multibyte_set_internal_encoding(mbfl_no_encoding2name(MBSTRG(internal_encoding)) TSRMLS_CC);
        !          1459:        php_mb_set_zend_encoding(TSRMLS_C);
        !          1460: #endif /* ZEND_MULTIBYTE */
        !          1461: 
        !          1462:        return SUCCESS;
        !          1463: }
        !          1464: /* }}} */
        !          1465: 
        !          1466: /* {{{ PHP_RSHUTDOWN_FUNCTION(mbstring) */
        !          1467: PHP_RSHUTDOWN_FUNCTION(mbstring)
        !          1468: {
        !          1469:        const struct mb_overload_def *p;
        !          1470:        zend_function *orig;
        !          1471: 
        !          1472:        if (MBSTRG(current_detect_order_list) != NULL) {
        !          1473:                efree(MBSTRG(current_detect_order_list));
        !          1474:                MBSTRG(current_detect_order_list) = NULL;
        !          1475:                MBSTRG(current_detect_order_list_size) = 0;
        !          1476:        }
        !          1477:        if (MBSTRG(outconv) != NULL) {
        !          1478:                MBSTRG(illegalchars) += mbfl_buffer_illegalchars(MBSTRG(outconv));
        !          1479:                mbfl_buffer_converter_delete(MBSTRG(outconv));
        !          1480:                MBSTRG(outconv) = NULL;
        !          1481:        }
        !          1482: 
        !          1483:        /* clear http input identification. */
        !          1484:        MBSTRG(http_input_identify) = mbfl_no_encoding_invalid;
        !          1485:        MBSTRG(http_input_identify_post) = mbfl_no_encoding_invalid;
        !          1486:        MBSTRG(http_input_identify_get) = mbfl_no_encoding_invalid;
        !          1487:        MBSTRG(http_input_identify_cookie) = mbfl_no_encoding_invalid;
        !          1488:        MBSTRG(http_input_identify_string) = mbfl_no_encoding_invalid;
        !          1489: 
        !          1490:        /*  clear overloaded function. */
        !          1491:        if (MBSTRG(func_overload)){
        !          1492:                p = &(mb_ovld[0]);
        !          1493:                while (p->type > 0) {
        !          1494:                        if ((MBSTRG(func_overload) & p->type) == p->type && 
        !          1495:                                zend_hash_find(EG(function_table), p->save_func,
        !          1496:                                                           strlen(p->save_func)+1, (void **)&orig) == SUCCESS) {
        !          1497:                                
        !          1498:                                zend_hash_update(EG(function_table), p->orig_func, strlen(p->orig_func)+1, orig, sizeof(zend_function), NULL);
        !          1499:                                zend_hash_del(EG(function_table), p->save_func, strlen(p->save_func)+1);
        !          1500:                        }
        !          1501:                        p++;
        !          1502:                }
        !          1503:        }
        !          1504: 
        !          1505: #if HAVE_MBREGEX
        !          1506:        PHP_RSHUTDOWN(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);
        !          1507: #endif
        !          1508: 
        !          1509:        return SUCCESS;
        !          1510: }
        !          1511: /* }}} */
        !          1512: 
        !          1513: /* {{{ PHP_MINFO_FUNCTION(mbstring) */
        !          1514: PHP_MINFO_FUNCTION(mbstring)
        !          1515: {
        !          1516:        php_info_print_table_start();
        !          1517:        php_info_print_table_row(2, "Multibyte Support", "enabled");
        !          1518:        php_info_print_table_row(2, "Multibyte string engine", "libmbfl");
        !          1519:        php_info_print_table_row(2, "HTTP input encoding translation", MBSTRG(encoding_translation) ? "enabled": "disabled");   
        !          1520:        php_info_print_table_end();
        !          1521: 
        !          1522:        php_info_print_table_start();
        !          1523:        php_info_print_table_header(1, "mbstring extension makes use of \"streamable kanji code filter and converter\", which is distributed under the GNU Lesser General Public License version 2.1.");
        !          1524:        php_info_print_table_end();
        !          1525: 
        !          1526: #if HAVE_MBREGEX
        !          1527:        PHP_MINFO(mb_regex)(ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU);
        !          1528: #endif
        !          1529: 
        !          1530:        DISPLAY_INI_ENTRIES();
        !          1531: }
        !          1532: /* }}} */
        !          1533: 
        !          1534: /* {{{ proto string mb_language([string language])
        !          1535:    Sets the current language or Returns the current language as a string */
        !          1536: PHP_FUNCTION(mb_language)
        !          1537: {
        !          1538:        char *name = NULL;
        !          1539:        int name_len = 0;
        !          1540: 
        !          1541:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE) {
        !          1542:                return;
        !          1543:        }
        !          1544:        if (name == NULL) {
        !          1545:                RETVAL_STRING((char *)mbfl_no_language2name(MBSTRG(language)), 1);
        !          1546:        } else {
        !          1547:                if (FAILURE == zend_alter_ini_entry(
        !          1548:                                "mbstring.language", sizeof("mbstring.language"),
        !          1549:                                name, name_len, PHP_INI_USER, PHP_INI_STAGE_RUNTIME)) {
        !          1550:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown language \"%s\"", name);
        !          1551:                        RETVAL_FALSE;
        !          1552:                } else {
        !          1553:                        RETVAL_TRUE;
        !          1554:                }
        !          1555:        }
        !          1556: }
        !          1557: /* }}} */
        !          1558: 
        !          1559: /* {{{ proto string mb_internal_encoding([string encoding])
        !          1560:    Sets the current internal encoding or Returns the current internal encoding as a string */
        !          1561: PHP_FUNCTION(mb_internal_encoding)
        !          1562: {
        !          1563:        char *name = NULL;
        !          1564:        int name_len;
        !          1565:        enum mbfl_no_encoding no_encoding;
        !          1566: 
        !          1567:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE) {
        !          1568:                RETURN_FALSE;
        !          1569:        }
        !          1570:        if (name == NULL) {
        !          1571:                name = (char *)mbfl_no_encoding2name(MBSTRG(current_internal_encoding));
        !          1572:                if (name != NULL) {
        !          1573:                        RETURN_STRING(name, 1);
        !          1574:                } else {
        !          1575:                        RETURN_FALSE;
        !          1576:                }
        !          1577:        } else {
        !          1578:                no_encoding = mbfl_name2no_encoding(name);
        !          1579:                if (no_encoding == mbfl_no_encoding_invalid) {
        !          1580:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", name);
        !          1581:                        RETURN_FALSE;
        !          1582:                } else {
        !          1583:                        MBSTRG(current_internal_encoding) = no_encoding;
        !          1584: #ifdef ZEND_MULTIBYTE
        !          1585:                        /* TODO: make independent from mbstring.encoding_translation? */
        !          1586:                        if (MBSTRG(encoding_translation)) {
        !          1587:                                zend_multibyte_set_internal_encoding(name TSRMLS_CC);
        !          1588:                        }
        !          1589: #endif /* ZEND_MULTIBYTE */
        !          1590:                        RETURN_TRUE;
        !          1591:                }
        !          1592:        }
        !          1593: }
        !          1594: /* }}} */
        !          1595: 
        !          1596: /* {{{ proto mixed mb_http_input([string type])
        !          1597:    Returns the input encoding */
        !          1598: PHP_FUNCTION(mb_http_input)
        !          1599: {
        !          1600:        char *typ = NULL;
        !          1601:        int typ_len;
        !          1602:        int retname, n;
        !          1603:        char *name, *list, *temp;
        !          1604:        enum mbfl_no_encoding *entry;
        !          1605:        enum mbfl_no_encoding result = mbfl_no_encoding_invalid;
        !          1606: 
        !          1607:        retname = 1;
        !          1608:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &typ, &typ_len) == FAILURE) {
        !          1609:                RETURN_FALSE;
        !          1610:        }
        !          1611:        if (typ == NULL) {
        !          1612:                result = MBSTRG(http_input_identify);
        !          1613:        } else {
        !          1614:                switch (*typ) {
        !          1615:                case 'G':
        !          1616:                case 'g':
        !          1617:                        result = MBSTRG(http_input_identify_get);
        !          1618:                        break;
        !          1619:                case 'P':
        !          1620:                case 'p':
        !          1621:                        result = MBSTRG(http_input_identify_post);
        !          1622:                        break;
        !          1623:                case 'C':
        !          1624:                case 'c':
        !          1625:                        result = MBSTRG(http_input_identify_cookie);
        !          1626:                        break;
        !          1627:                case 'S':
        !          1628:                case 's':
        !          1629:                        result = MBSTRG(http_input_identify_string);
        !          1630:                        break;
        !          1631:                case 'I':
        !          1632:                case 'i':
        !          1633:                        array_init(return_value);
        !          1634:                        entry = MBSTRG(http_input_list);
        !          1635:                        n = MBSTRG(http_input_list_size);
        !          1636:                        while (n > 0) {
        !          1637:                                name = (char *)mbfl_no_encoding2name(*entry);
        !          1638:                                if (name) {
        !          1639:                                        add_next_index_string(return_value, name, 1);
        !          1640:                                }
        !          1641:                                entry++;
        !          1642:                                n--;
        !          1643:                        }
        !          1644:                        retname = 0;
        !          1645:                        break;
        !          1646:                case 'L':
        !          1647:                case 'l':
        !          1648:                        entry = MBSTRG(http_input_list);
        !          1649:                        n = MBSTRG(http_input_list_size);
        !          1650:                        list = NULL;
        !          1651:                        while (n > 0) {
        !          1652:                                name = (char *)mbfl_no_encoding2name(*entry);
        !          1653:                                if (name) {
        !          1654:                                        if (list) {
        !          1655:                                                temp = list;
        !          1656:                                                spprintf(&list, 0, "%s,%s", temp, name);
        !          1657:                                                efree(temp);
        !          1658:                                                if (!list) { 
        !          1659:                                                        break;
        !          1660:                                                }
        !          1661:                                        } else {
        !          1662:                                                list = estrdup(name);
        !          1663:                                        }
        !          1664:                                }
        !          1665:                                entry++;
        !          1666:                                n--;
        !          1667:                        }
        !          1668:                        if (!list) {
        !          1669:                                RETURN_FALSE;
        !          1670:                        }
        !          1671:                        RETVAL_STRING(list, 0);
        !          1672:                        retname = 0;
        !          1673:                        break;
        !          1674:                default:
        !          1675:                        result = MBSTRG(http_input_identify);
        !          1676:                        break;
        !          1677:                }
        !          1678:        }
        !          1679: 
        !          1680:        if (retname) {
        !          1681:                if (result != mbfl_no_encoding_invalid &&
        !          1682:                        (name = (char *)mbfl_no_encoding2name(result)) != NULL) {
        !          1683:                        RETVAL_STRING(name, 1);
        !          1684:                } else {
        !          1685:                        RETVAL_FALSE;
        !          1686:                }
        !          1687:        }
        !          1688: }
        !          1689: /* }}} */
        !          1690: 
        !          1691: /* {{{ proto string mb_http_output([string encoding])
        !          1692:    Sets the current output_encoding or returns the current output_encoding as a string */
        !          1693: PHP_FUNCTION(mb_http_output)
        !          1694: {
        !          1695:        char *name = NULL;
        !          1696:        int name_len;
        !          1697:        enum mbfl_no_encoding no_encoding;
        !          1698: 
        !          1699:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", (char **)&name, &name_len) == FAILURE) {
        !          1700:                RETURN_FALSE;
        !          1701:        }
        !          1702: 
        !          1703:        if (name == NULL) {
        !          1704:                name = (char *)mbfl_no_encoding2name(MBSTRG(current_http_output_encoding));
        !          1705:                if (name != NULL) {
        !          1706:                        RETURN_STRING(name, 1);
        !          1707:                } else {
        !          1708:                        RETURN_FALSE;
        !          1709:                }
        !          1710:        } else {
        !          1711:                no_encoding = mbfl_name2no_encoding(name);
        !          1712:                if (no_encoding == mbfl_no_encoding_invalid) {
        !          1713:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", name);
        !          1714:                        RETURN_FALSE;
        !          1715:                } else {
        !          1716:                        MBSTRG(current_http_output_encoding) = no_encoding;
        !          1717:                        RETURN_TRUE;
        !          1718:                }
        !          1719:        }
        !          1720: }
        !          1721: /* }}} */
        !          1722: 
        !          1723: /* {{{ proto bool|array mb_detect_order([mixed encoding-list])
        !          1724:    Sets the current detect_order or Return the current detect_order as a array */
        !          1725: PHP_FUNCTION(mb_detect_order)
        !          1726: {
        !          1727:        zval **arg1 = NULL;
        !          1728:        int n, size;
        !          1729:        enum mbfl_no_encoding *list, *entry;
        !          1730:        char *name;
        !          1731: 
        !          1732:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|Z", &arg1) == FAILURE) {
        !          1733:                return;
        !          1734:        }
        !          1735: 
        !          1736:        if (!arg1) {
        !          1737:                array_init(return_value);
        !          1738:                entry = MBSTRG(current_detect_order_list);
        !          1739:                n = MBSTRG(current_detect_order_list_size);
        !          1740:                while (n > 0) {
        !          1741:                        name = (char *)mbfl_no_encoding2name(*entry);
        !          1742:                        if (name) {
        !          1743:                                add_next_index_string(return_value, name, 1);
        !          1744:                        }
        !          1745:                        entry++;
        !          1746:                        n--;
        !          1747:                }
        !          1748:        } else {
        !          1749:                list = NULL;
        !          1750:                size = 0;
        !          1751:                switch (Z_TYPE_PP(arg1)) {
        !          1752:                case IS_ARRAY:
        !          1753:                        if (!php_mb_parse_encoding_array(*arg1, &list, &size, 0 TSRMLS_CC)) {
        !          1754:                                if (list) {
        !          1755:                                        efree(list);
        !          1756:                                }
        !          1757:                                RETURN_FALSE;
        !          1758:                        }
        !          1759:                        break;
        !          1760:                default:
        !          1761:                        convert_to_string_ex(arg1);
        !          1762:                        if (!php_mb_parse_encoding_list(Z_STRVAL_PP(arg1), Z_STRLEN_PP(arg1), &list, &size, 0 TSRMLS_CC)) {
        !          1763:                                if (list) {
        !          1764:                                        efree(list);
        !          1765:                                }
        !          1766:                                RETURN_FALSE;
        !          1767:                        }
        !          1768:                        break;
        !          1769:                }
        !          1770: 
        !          1771:                if (list == NULL) {
        !          1772:                        RETURN_FALSE;
        !          1773:                }
        !          1774: 
        !          1775:                if (MBSTRG(current_detect_order_list)) {
        !          1776:                        efree(MBSTRG(current_detect_order_list));
        !          1777:                }
        !          1778:                MBSTRG(current_detect_order_list) = list;
        !          1779:                MBSTRG(current_detect_order_list_size) = size;
        !          1780:                RETURN_TRUE;
        !          1781:        }
        !          1782: }
        !          1783: /* }}} */
        !          1784: 
        !          1785: /* {{{ proto mixed mb_substitute_character([mixed substchar])
        !          1786:    Sets the current substitute_character or returns the current substitute_character */
        !          1787: PHP_FUNCTION(mb_substitute_character)
        !          1788: {
        !          1789:        zval **arg1 = NULL;
        !          1790: 
        !          1791:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|Z", &arg1) == FAILURE) {
        !          1792:                return;
        !          1793:        }
        !          1794: 
        !          1795:        if (!arg1) {
        !          1796:                if (MBSTRG(current_filter_illegal_mode) == MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
        !          1797:                        RETURN_STRING("none", 1);
        !          1798:                } else if (MBSTRG(current_filter_illegal_mode) == MBFL_OUTPUTFILTER_ILLEGAL_MODE_LONG) {
        !          1799:                        RETURN_STRING("long", 1);
        !          1800:                } else if (MBSTRG(current_filter_illegal_mode) == MBFL_OUTPUTFILTER_ILLEGAL_MODE_ENTITY) {
        !          1801:                        RETURN_STRING("entity", 1);
        !          1802:                } else {
        !          1803:                        RETURN_LONG(MBSTRG(current_filter_illegal_substchar));
        !          1804:                }
        !          1805:        } else {
        !          1806:                RETVAL_TRUE;
        !          1807: 
        !          1808:                switch (Z_TYPE_PP(arg1)) {
        !          1809:                case IS_STRING:
        !          1810:                        if (strncasecmp("none", Z_STRVAL_PP(arg1), Z_STRLEN_PP(arg1)) == 0) {
        !          1811:                                MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE;
        !          1812:                        } else if (strncasecmp("long", Z_STRVAL_PP(arg1), Z_STRLEN_PP(arg1)) == 0) {
        !          1813:                                MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_LONG;
        !          1814:                        } else if (strncasecmp("entity", Z_STRVAL_PP(arg1), Z_STRLEN_PP(arg1)) == 0) {
        !          1815:                                MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_ENTITY;
        !          1816:                        } else {
        !          1817:                                convert_to_long_ex(arg1);
        !          1818: 
        !          1819:                                if (Z_LVAL_PP(arg1) < 0xffff && Z_LVAL_PP(arg1) > 0x0) {
        !          1820:                                        MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR;
        !          1821:                                        MBSTRG(current_filter_illegal_substchar) = Z_LVAL_PP(arg1);
        !          1822:                                } else {
        !          1823:                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown character.");
        !          1824:                                        RETURN_FALSE;
        !          1825:                                }
        !          1826:                        }
        !          1827:                        break;
        !          1828:                default:
        !          1829:                        convert_to_long_ex(arg1);
        !          1830:                        if (Z_LVAL_PP(arg1) < 0xffff && Z_LVAL_PP(arg1) > 0x0) {
        !          1831:                                MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR;
        !          1832:                                MBSTRG(current_filter_illegal_substchar) = Z_LVAL_PP(arg1);
        !          1833:                        } else {
        !          1834:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown character.");
        !          1835:                                RETURN_FALSE;
        !          1836:                        }
        !          1837:                        break;
        !          1838:                }
        !          1839:        }
        !          1840: }
        !          1841: /* }}} */
        !          1842: 
        !          1843: /* {{{ proto string mb_preferred_mime_name(string encoding)
        !          1844:    Return the preferred MIME name (charset) as a string */
        !          1845: PHP_FUNCTION(mb_preferred_mime_name)
        !          1846: {
        !          1847:        enum mbfl_no_encoding no_encoding;
        !          1848:        char *name = NULL;
        !          1849:        int name_len;
        !          1850: 
        !          1851:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
        !          1852:                return;
        !          1853:        } else {
        !          1854:                no_encoding = mbfl_name2no_encoding(name);
        !          1855:                if (no_encoding == mbfl_no_encoding_invalid) {
        !          1856:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", name);
        !          1857:                        RETVAL_FALSE;
        !          1858:                } else {
        !          1859:                        const char *preferred_name = mbfl_no2preferred_mime_name(no_encoding);
        !          1860:                        if (preferred_name == NULL || *preferred_name == '\0') {
        !          1861:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "No MIME preferred name corresponding to \"%s\"", name);
        !          1862:                                RETVAL_FALSE;
        !          1863:                        } else {
        !          1864:                                RETVAL_STRING((char *)preferred_name, 1);
        !          1865:                        }
        !          1866:                }
        !          1867:        }
        !          1868: }
        !          1869: /* }}} */
        !          1870: 
        !          1871: #define IS_SJIS1(c) ((((c)>=0x81 && (c)<=0x9f) || ((c)>=0xe0 && (c)<=0xf5)) ? 1 : 0)
        !          1872: #define IS_SJIS2(c) ((((c)>=0x40 && (c)<=0x7e) || ((c)>=0x80 && (c)<=0xfc)) ? 1 : 0)
        !          1873: 
        !          1874: /* {{{ proto bool mb_parse_str(string encoded_string [, array result])
        !          1875:    Parses GET/POST/COOKIE data and sets global variables */
        !          1876: PHP_FUNCTION(mb_parse_str)
        !          1877: {
        !          1878:        zval *track_vars_array = NULL;
        !          1879:        char *encstr = NULL;
        !          1880:        int encstr_len;
        !          1881:        php_mb_encoding_handler_info_t info;
        !          1882:        enum mbfl_no_encoding detected;
        !          1883: 
        !          1884:        track_vars_array = NULL;
        !          1885:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &encstr, &encstr_len, &track_vars_array) == FAILURE) {
        !          1886:                return;
        !          1887:        }
        !          1888: 
        !          1889:        /* Clear out the array */
        !          1890:        if (track_vars_array != NULL) {
        !          1891:                zval_dtor(track_vars_array);
        !          1892:                array_init(track_vars_array);
        !          1893:        }
        !          1894: 
        !          1895:        encstr = estrndup(encstr, encstr_len);
        !          1896: 
        !          1897:        info.data_type              = PARSE_STRING;
        !          1898:        info.separator              = PG(arg_separator).input; 
        !          1899:        info.force_register_globals = (track_vars_array == NULL);
        !          1900:        info.report_errors          = 1;
        !          1901:        info.to_encoding            = MBSTRG(current_internal_encoding);
        !          1902:        info.to_language            = MBSTRG(language);
        !          1903:        info.from_encodings         = MBSTRG(http_input_list);
        !          1904:        info.num_from_encodings     = MBSTRG(http_input_list_size); 
        !          1905:        info.from_language          = MBSTRG(language);
        !          1906: 
        !          1907:        detected = _php_mb_encoding_handler_ex(&info, track_vars_array, encstr TSRMLS_CC);
        !          1908: 
        !          1909:        MBSTRG(http_input_identify) = detected;
        !          1910: 
        !          1911:        RETVAL_BOOL(detected != mbfl_no_encoding_invalid);
        !          1912: 
        !          1913:        if (encstr != NULL) efree(encstr);
        !          1914: }
        !          1915: /* }}} */
        !          1916: 
        !          1917: /* {{{ proto string mb_output_handler(string contents, int status)
        !          1918:    Returns string in output buffer converted to the http_output encoding */
        !          1919: PHP_FUNCTION(mb_output_handler)
        !          1920: {
        !          1921:        char *arg_string;
        !          1922:        int arg_string_len;
        !          1923:        long arg_status;
        !          1924:        mbfl_string string, result;
        !          1925:        const char *charset;
        !          1926:        char *p;
        !          1927:        enum mbfl_no_encoding encoding;
        !          1928:        int last_feed, len;
        !          1929:        unsigned char send_text_mimetype = 0;
        !          1930:        char *s, *mimetype = NULL;
        !          1931: 
        !          1932:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &arg_string, &arg_string_len, &arg_status) == FAILURE) {
        !          1933:                return;
        !          1934:        }
        !          1935: 
        !          1936:        encoding = MBSTRG(current_http_output_encoding);
        !          1937: 
        !          1938:        /* start phase only */
        !          1939:        if ((arg_status & PHP_OUTPUT_HANDLER_START) != 0) {
        !          1940:                /* delete the converter just in case. */
        !          1941:                if (MBSTRG(outconv)) {
        !          1942:                        MBSTRG(illegalchars) += mbfl_buffer_illegalchars(MBSTRG(outconv));
        !          1943:                        mbfl_buffer_converter_delete(MBSTRG(outconv));
        !          1944:                        MBSTRG(outconv) = NULL;
        !          1945:                }
        !          1946:                if (encoding == mbfl_no_encoding_pass) {
        !          1947:                        RETURN_STRINGL(arg_string, arg_string_len, 1);
        !          1948:                }
        !          1949: 
        !          1950:                /* analyze mime type */
        !          1951:                if (SG(sapi_headers).mimetype &&
        !          1952:                        _php_mb_match_regex(
        !          1953:                                MBSTRG(http_output_conv_mimetypes),
        !          1954:                                SG(sapi_headers).mimetype,
        !          1955:                                strlen(SG(sapi_headers).mimetype))) {
        !          1956:                        if ((s = strchr(SG(sapi_headers).mimetype,';')) == NULL){
        !          1957:                                mimetype = estrdup(SG(sapi_headers).mimetype);
        !          1958:                        } else {
        !          1959:                                mimetype = estrndup(SG(sapi_headers).mimetype,s-SG(sapi_headers).mimetype);
        !          1960:                        }
        !          1961:                        send_text_mimetype = 1;
        !          1962:                } else if (SG(sapi_headers).send_default_content_type) {
        !          1963:                        mimetype = SG(default_mimetype) ? SG(default_mimetype) : SAPI_DEFAULT_MIMETYPE;
        !          1964:                }
        !          1965: 
        !          1966:                /* if content-type is not yet set, set it and activate the converter */
        !          1967:                if (SG(sapi_headers).send_default_content_type || send_text_mimetype) {
        !          1968:                        charset = mbfl_no2preferred_mime_name(encoding);
        !          1969:                        if (charset) {
        !          1970:                                len = spprintf( &p, 0, "Content-Type: %s; charset=%s",  mimetype, charset ); 
        !          1971:                                if (sapi_add_header(p, len, 0) != FAILURE) {
        !          1972:                                        SG(sapi_headers).send_default_content_type = 0;
        !          1973:                                }
        !          1974:                        }
        !          1975:                        /* activate the converter */
        !          1976:                        MBSTRG(outconv) = mbfl_buffer_converter_new(MBSTRG(current_internal_encoding), encoding, 0);
        !          1977:                        if (send_text_mimetype){
        !          1978:                                efree(mimetype);
        !          1979:                        }
        !          1980:                }
        !          1981:        }
        !          1982: 
        !          1983:        /* just return if the converter is not activated. */
        !          1984:        if (MBSTRG(outconv) == NULL) {
        !          1985:                RETURN_STRINGL(arg_string, arg_string_len, 1);
        !          1986:        }
        !          1987: 
        !          1988:        /* flag */
        !          1989:        last_feed = ((arg_status & PHP_OUTPUT_HANDLER_END) != 0);
        !          1990:        /* mode */
        !          1991:        mbfl_buffer_converter_illegal_mode(MBSTRG(outconv), MBSTRG(current_filter_illegal_mode));
        !          1992:        mbfl_buffer_converter_illegal_substchar(MBSTRG(outconv), MBSTRG(current_filter_illegal_substchar));
        !          1993:  
        !          1994:        /* feed the string */
        !          1995:        mbfl_string_init(&string);
        !          1996:        string.no_language = MBSTRG(language);
        !          1997:        string.no_encoding = MBSTRG(current_internal_encoding);
        !          1998:        string.val = (unsigned char *)arg_string;
        !          1999:        string.len = arg_string_len;
        !          2000:        mbfl_buffer_converter_feed(MBSTRG(outconv), &string);
        !          2001:        if (last_feed) {
        !          2002:                mbfl_buffer_converter_flush(MBSTRG(outconv));
        !          2003:        } 
        !          2004:        /* get the converter output, and return it */
        !          2005:        mbfl_buffer_converter_result(MBSTRG(outconv), &result);
        !          2006:        RETVAL_STRINGL((char *)result.val, result.len, 0);              /* the string is already strdup()'ed */
        !          2007:  
        !          2008:        /* delete the converter if it is the last feed. */
        !          2009:        if (last_feed) {
        !          2010:                MBSTRG(illegalchars) += mbfl_buffer_illegalchars(MBSTRG(outconv));
        !          2011:                mbfl_buffer_converter_delete(MBSTRG(outconv));
        !          2012:                MBSTRG(outconv) = NULL;
        !          2013:        }
        !          2014: }
        !          2015: /* }}} */
        !          2016: 
        !          2017: /* {{{ proto int mb_strlen(string str [, string encoding])
        !          2018:    Get character numbers of a string */
        !          2019: PHP_FUNCTION(mb_strlen)
        !          2020: {
        !          2021:        int n;
        !          2022:        mbfl_string string;
        !          2023:        char *enc_name = NULL;
        !          2024:        int enc_name_len;
        !          2025: 
        !          2026:        mbfl_string_init(&string);
        !          2027: 
        !          2028:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", (char **)&string.val, &string.len, &enc_name, &enc_name_len) == FAILURE) {
        !          2029:                RETURN_FALSE;
        !          2030:        }
        !          2031: 
        !          2032:        string.no_language = MBSTRG(language);
        !          2033:        if (enc_name == NULL) {
        !          2034:                string.no_encoding = MBSTRG(current_internal_encoding);
        !          2035:        } else {
        !          2036:                string.no_encoding = mbfl_name2no_encoding(enc_name);
        !          2037:                if (string.no_encoding == mbfl_no_encoding_invalid) {
        !          2038:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", enc_name);
        !          2039:                        RETURN_FALSE;
        !          2040:                }
        !          2041:        }
        !          2042: 
        !          2043:        n = mbfl_strlen(&string);
        !          2044:        if (n >= 0) {
        !          2045:                RETVAL_LONG(n);
        !          2046:        } else {
        !          2047:                RETVAL_FALSE;
        !          2048:        }
        !          2049: }
        !          2050: /* }}} */
        !          2051: 
        !          2052: /* {{{ proto int mb_strpos(string haystack, string needle [, int offset [, string encoding]])
        !          2053:    Find position of first occurrence of a string within another */
        !          2054: PHP_FUNCTION(mb_strpos)
        !          2055: {
        !          2056:        int n, reverse = 0;
        !          2057:        long offset;
        !          2058:        mbfl_string haystack, needle;
        !          2059:        char *enc_name = NULL;
        !          2060:        int enc_name_len;
        !          2061:        
        !          2062:        mbfl_string_init(&haystack);
        !          2063:        mbfl_string_init(&needle);
        !          2064:        haystack.no_language = MBSTRG(language);
        !          2065:        haystack.no_encoding = MBSTRG(current_internal_encoding);
        !          2066:        needle.no_language = MBSTRG(language);
        !          2067:        needle.no_encoding = MBSTRG(current_internal_encoding);
        !          2068:        offset = 0;
        !          2069: 
        !          2070:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ls", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &offset, &enc_name, &enc_name_len) == FAILURE) {
        !          2071:                RETURN_FALSE;
        !          2072:        }
        !          2073: 
        !          2074:        if (enc_name != NULL) {
        !          2075:                haystack.no_encoding = needle.no_encoding = mbfl_name2no_encoding(enc_name);
        !          2076:                if (haystack.no_encoding == mbfl_no_encoding_invalid) {
        !          2077:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", enc_name);
        !          2078:                        RETURN_FALSE;
        !          2079:                }
        !          2080:        }
        !          2081: 
        !          2082:        if (offset < 0 || offset > mbfl_strlen(&haystack)) {
        !          2083:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset not contained in string");
        !          2084:                RETURN_FALSE;
        !          2085:        }
        !          2086:        if (needle.len == 0) {
        !          2087:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter");
        !          2088:                RETURN_FALSE;
        !          2089:        }
        !          2090: 
        !          2091:        n = mbfl_strpos(&haystack, &needle, offset, reverse);
        !          2092:        if (n >= 0) {
        !          2093:                RETVAL_LONG(n);
        !          2094:        } else {
        !          2095:                switch (-n) {
        !          2096:                case 1:
        !          2097:                        break;
        !          2098:                case 2:
        !          2099:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Needle has not positive length");
        !          2100:                        break;
        !          2101:                case 4:
        !          2102:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding or conversion error");
        !          2103:                        break;
        !          2104:                case 8:
        !          2105:                        php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Argument is empty");
        !          2106:                        break;
        !          2107:                default:
        !          2108:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown error in mb_strpos");
        !          2109:                        break;
        !          2110:                }
        !          2111:                RETVAL_FALSE;
        !          2112:        }
        !          2113: }
        !          2114: /* }}} */
        !          2115: 
        !          2116: /* {{{ proto int mb_strrpos(string haystack, string needle [, int offset [, string encoding]])
        !          2117:    Find position of last occurrence of a string within another */
        !          2118: PHP_FUNCTION(mb_strrpos)
        !          2119: {
        !          2120:        int n;
        !          2121:        mbfl_string haystack, needle;
        !          2122:        char *enc_name = NULL;
        !          2123:        int enc_name_len;
        !          2124:        zval **zoffset = NULL;
        !          2125:        long offset = 0, str_flg;
        !          2126:        char *enc_name2 = NULL;
        !          2127:        int enc_name_len2;
        !          2128: 
        !          2129:        mbfl_string_init(&haystack);
        !          2130:        mbfl_string_init(&needle);
        !          2131:        haystack.no_language = MBSTRG(language);
        !          2132:        haystack.no_encoding = MBSTRG(current_internal_encoding);
        !          2133:        needle.no_language = MBSTRG(language);
        !          2134:        needle.no_encoding = MBSTRG(current_internal_encoding);
        !          2135: 
        !          2136:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|Zs", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &zoffset, &enc_name, &enc_name_len) == FAILURE) {
        !          2137:                RETURN_FALSE;
        !          2138:        }
        !          2139: 
        !          2140:        if (zoffset) {
        !          2141:                if (Z_TYPE_PP(zoffset) == IS_STRING) {
        !          2142:                        enc_name2     = Z_STRVAL_PP(zoffset);
        !          2143:                        enc_name_len2 = Z_STRLEN_PP(zoffset);
        !          2144:                        str_flg       = 1;
        !          2145: 
        !          2146:                        if (enc_name2 != NULL) {
        !          2147:                                switch (*enc_name2) {
        !          2148:                                case '0':
        !          2149:                                case '1':
        !          2150:                                case '2':
        !          2151:                                case '3':
        !          2152:                                case '4':
        !          2153:                                case '5':
        !          2154:                                case '6':
        !          2155:                                case '7':
        !          2156:                                case '8':
        !          2157:                                case '9':
        !          2158:                                case ' ':
        !          2159:                                case '-':
        !          2160:                                case '.':
        !          2161:                                        break;
        !          2162:                                default :
        !          2163:                                        str_flg = 0;
        !          2164:                                        break;
        !          2165:                                }
        !          2166:                        }
        !          2167: 
        !          2168:                        if (str_flg) {
        !          2169:                                convert_to_long_ex(zoffset);
        !          2170:                                offset   = Z_LVAL_PP(zoffset);
        !          2171:                        } else {
        !          2172:                                enc_name     = enc_name2;
        !          2173:                                enc_name_len = enc_name_len2;
        !          2174:                        }
        !          2175:                } else {
        !          2176:                        convert_to_long_ex(zoffset);
        !          2177:                        offset = Z_LVAL_PP(zoffset);
        !          2178:                }
        !          2179:        }
        !          2180: 
        !          2181:        if (enc_name != NULL) {
        !          2182:                haystack.no_encoding = needle.no_encoding = mbfl_name2no_encoding(enc_name);
        !          2183:                if (haystack.no_encoding == mbfl_no_encoding_invalid) {
        !          2184:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", enc_name);
        !          2185:                        RETURN_FALSE;
        !          2186:                }
        !          2187:        }
        !          2188: 
        !          2189:        if (haystack.len <= 0) {
        !          2190:                RETURN_FALSE;
        !          2191:        }
        !          2192:        if (needle.len <= 0) {
        !          2193:                RETURN_FALSE;
        !          2194:        }
        !          2195: 
        !          2196:        {
        !          2197:                int haystack_char_len = mbfl_strlen(&haystack);
        !          2198:                if ((offset > 0 && offset > haystack_char_len) ||
        !          2199:                        (offset < 0 && -offset > haystack_char_len)) {
        !          2200:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset is greater than the length of haystack string");
        !          2201:                        RETURN_FALSE;
        !          2202:                }
        !          2203:        }
        !          2204: 
        !          2205:        n = mbfl_strpos(&haystack, &needle, offset, 1);
        !          2206:        if (n >= 0) {
        !          2207:                RETVAL_LONG(n);
        !          2208:        } else {
        !          2209:                RETVAL_FALSE;
        !          2210:        }
        !          2211: }
        !          2212: /* }}} */
        !          2213: 
        !          2214: /* {{{ proto int mb_stripos(string haystack, string needle [, int offset [, string encoding]])
        !          2215:    Finds position of first occurrence of a string within another, case insensitive */
        !          2216: PHP_FUNCTION(mb_stripos)
        !          2217: {
        !          2218:        int n;
        !          2219:        long offset;
        !          2220:        mbfl_string haystack, needle;
        !          2221:        char *from_encoding = (char*)mbfl_no2preferred_mime_name(MBSTRG(current_internal_encoding));
        !          2222:        int from_encoding_len;
        !          2223:        n = -1;
        !          2224:        offset = 0;
        !          2225: 
        !          2226:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ls", (char **)&haystack.val, (int *)&haystack.len, (char **)&needle.val, (int *)&needle.len, &offset, &from_encoding, &from_encoding_len) == FAILURE) {
        !          2227:                RETURN_FALSE;
        !          2228:        }
        !          2229:        if (needle.len == 0) {
        !          2230:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter");
        !          2231:                RETURN_FALSE;
        !          2232:        }
        !          2233:        n = php_mb_stripos(0, (char *)haystack.val, haystack.len, (char *)needle.val, needle.len, offset, from_encoding TSRMLS_CC);
        !          2234: 
        !          2235:        if (n >= 0) {
        !          2236:                RETVAL_LONG(n);
        !          2237:        } else {
        !          2238:                RETVAL_FALSE;
        !          2239:        }
        !          2240: }
        !          2241: /* }}} */
        !          2242: 
        !          2243: /* {{{ proto int mb_strripos(string haystack, string needle [, int offset [, string encoding]])
        !          2244:    Finds position of last occurrence of a string within another, case insensitive */
        !          2245: PHP_FUNCTION(mb_strripos)
        !          2246: {
        !          2247:        int n;
        !          2248:        long offset;
        !          2249:        mbfl_string haystack, needle;
        !          2250:        const char *from_encoding = mbfl_no2preferred_mime_name(MBSTRG(current_internal_encoding));
        !          2251:        int from_encoding_len;
        !          2252:        n = -1;
        !          2253:        offset = 0;
        !          2254: 
        !          2255:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ls", (char **)&haystack.val, (int *)&haystack.len, (char **)&needle.val, (int *)&needle.len, &offset, &from_encoding, &from_encoding_len) == FAILURE) {
        !          2256:                RETURN_FALSE;
        !          2257:        }
        !          2258: 
        !          2259:        n = php_mb_stripos(1, (char *)haystack.val, haystack.len, (char *)needle.val, needle.len, offset, from_encoding TSRMLS_CC);
        !          2260: 
        !          2261:        if (n >= 0) {
        !          2262:                RETVAL_LONG(n);
        !          2263:        } else {
        !          2264:                RETVAL_FALSE;
        !          2265:        }
        !          2266: }
        !          2267: /* }}} */
        !          2268: 
        !          2269: /* {{{ proto string mb_strstr(string haystack, string needle[, bool part[, string encoding]])
        !          2270:    Finds first occurrence of a string within another */
        !          2271: PHP_FUNCTION(mb_strstr)
        !          2272: {
        !          2273:        int n, len, mblen;
        !          2274:        mbfl_string haystack, needle, result, *ret = NULL;
        !          2275:        char *enc_name = NULL;
        !          2276:        int enc_name_len;
        !          2277:        zend_bool part = 0;
        !          2278: 
        !          2279:        mbfl_string_init(&haystack);
        !          2280:        mbfl_string_init(&needle);
        !          2281:        haystack.no_language = MBSTRG(language);
        !          2282:        haystack.no_encoding = MBSTRG(current_internal_encoding);
        !          2283:        needle.no_language = MBSTRG(language);
        !          2284:        needle.no_encoding = MBSTRG(current_internal_encoding);
        !          2285: 
        !          2286:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|bs", (char **)&haystack.val, (int *)&haystack.len, (char **)&needle.val, (int *)&needle.len, &part, &enc_name, &enc_name_len) == FAILURE) {
        !          2287:                RETURN_FALSE;
        !          2288:        }
        !          2289: 
        !          2290:        if (enc_name != NULL) {
        !          2291:                haystack.no_encoding = needle.no_encoding = mbfl_name2no_encoding(enc_name);
        !          2292:                if (haystack.no_encoding == mbfl_no_encoding_invalid) {
        !          2293:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", enc_name);
        !          2294:                        RETURN_FALSE;
        !          2295:                }
        !          2296:        }
        !          2297: 
        !          2298:        if (needle.len <= 0) {
        !          2299:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter");
        !          2300:                RETURN_FALSE;
        !          2301:        }
        !          2302:        n = mbfl_strpos(&haystack, &needle, 0, 0);
        !          2303:        if (n >= 0) {
        !          2304:                mblen = mbfl_strlen(&haystack);
        !          2305:                if (part) {
        !          2306:                        ret = mbfl_substr(&haystack, &result, 0, n);
        !          2307:                        if (ret != NULL) {
        !          2308:                                RETVAL_STRINGL((char *)ret->val, ret->len, 0);
        !          2309:                        } else {
        !          2310:                                RETVAL_FALSE;
        !          2311:                        }
        !          2312:                } else {
        !          2313:                        len = (mblen - n);
        !          2314:                        ret = mbfl_substr(&haystack, &result, n, len);
        !          2315:                        if (ret != NULL) {
        !          2316:                                RETVAL_STRINGL((char *)ret->val, ret->len, 0);
        !          2317:                        } else {
        !          2318:                                RETVAL_FALSE;
        !          2319:                        }
        !          2320:                }
        !          2321:        } else {
        !          2322:                RETVAL_FALSE;
        !          2323:        }
        !          2324: }
        !          2325: /* }}} */
        !          2326: 
        !          2327: /* {{{ proto string mb_strrchr(string haystack, string needle[, bool part[, string encoding]])
        !          2328:    Finds the last occurrence of a character in a string within another */
        !          2329: PHP_FUNCTION(mb_strrchr)
        !          2330: {
        !          2331:        int n, len, mblen;
        !          2332:        mbfl_string haystack, needle, result, *ret = NULL;
        !          2333:        char *enc_name = NULL;
        !          2334:        int enc_name_len;
        !          2335:        zend_bool part = 0;
        !          2336: 
        !          2337:        mbfl_string_init(&haystack);
        !          2338:        mbfl_string_init(&needle);
        !          2339:        haystack.no_language = MBSTRG(language);
        !          2340:        haystack.no_encoding = MBSTRG(current_internal_encoding);
        !          2341:        needle.no_language = MBSTRG(language);
        !          2342:        needle.no_encoding = MBSTRG(current_internal_encoding);
        !          2343: 
        !          2344:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|bs", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &part, &enc_name, &enc_name_len) == FAILURE) {
        !          2345:                RETURN_FALSE;
        !          2346:        }
        !          2347: 
        !          2348:        if (enc_name != NULL) {
        !          2349:                haystack.no_encoding = needle.no_encoding = mbfl_name2no_encoding(enc_name);
        !          2350:                if (haystack.no_encoding == mbfl_no_encoding_invalid) {
        !          2351:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", enc_name);
        !          2352:                        RETURN_FALSE;
        !          2353:                }
        !          2354:        }
        !          2355: 
        !          2356:        if (haystack.len <= 0) {
        !          2357:                RETURN_FALSE;
        !          2358:        }
        !          2359:        if (needle.len <= 0) {
        !          2360:                RETURN_FALSE;
        !          2361:        }
        !          2362:        n = mbfl_strpos(&haystack, &needle, 0, 1);
        !          2363:        if (n >= 0) {
        !          2364:                mblen = mbfl_strlen(&haystack);
        !          2365:                if (part) {
        !          2366:                        ret = mbfl_substr(&haystack, &result, 0, n);
        !          2367:                        if (ret != NULL) {
        !          2368:                                RETVAL_STRINGL((char *)ret->val, ret->len, 0);
        !          2369:                        } else {
        !          2370:                                RETVAL_FALSE;
        !          2371:                        }
        !          2372:                } else {
        !          2373:                        len = (mblen - n);
        !          2374:                        ret = mbfl_substr(&haystack, &result, n, len);
        !          2375:                        if (ret != NULL) {
        !          2376:                                RETVAL_STRINGL((char *)ret->val, ret->len, 0);
        !          2377:                        } else {
        !          2378:                                RETVAL_FALSE;
        !          2379:                        }
        !          2380:                }
        !          2381:        } else {
        !          2382:                RETVAL_FALSE;
        !          2383:        }
        !          2384: }
        !          2385: /* }}} */
        !          2386: 
        !          2387: /* {{{ proto string mb_stristr(string haystack, string needle[, bool part[, string encoding]])
        !          2388:    Finds first occurrence of a string within another, case insensitive */
        !          2389: PHP_FUNCTION(mb_stristr)
        !          2390: {
        !          2391:        zend_bool part = 0;
        !          2392:        unsigned int from_encoding_len, len, mblen;
        !          2393:        int n;
        !          2394:        mbfl_string haystack, needle, result, *ret = NULL;
        !          2395:        const char *from_encoding = mbfl_no2preferred_mime_name(MBSTRG(current_internal_encoding));
        !          2396:        mbfl_string_init(&haystack);
        !          2397:        mbfl_string_init(&needle);
        !          2398:        haystack.no_language = MBSTRG(language);
        !          2399:        haystack.no_encoding = MBSTRG(current_internal_encoding);
        !          2400:        needle.no_language = MBSTRG(language);
        !          2401:        needle.no_encoding = MBSTRG(current_internal_encoding);
        !          2402: 
        !          2403: 
        !          2404:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|bs", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &part, &from_encoding, &from_encoding_len) == FAILURE) {
        !          2405:                RETURN_FALSE;
        !          2406:        }
        !          2407: 
        !          2408:        if (!needle.len) {
        !          2409:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter");
        !          2410:                RETURN_FALSE;
        !          2411:        }
        !          2412: 
        !          2413:        haystack.no_encoding = needle.no_encoding = mbfl_name2no_encoding(from_encoding);
        !          2414:        if (haystack.no_encoding == mbfl_no_encoding_invalid) {
        !          2415:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", from_encoding);
        !          2416:                RETURN_FALSE;
        !          2417:        }
        !          2418: 
        !          2419:        n = php_mb_stripos(0, (char *)haystack.val, haystack.len, (char *)needle.val, needle.len, 0, from_encoding TSRMLS_CC);
        !          2420: 
        !          2421:        if (n <0) {
        !          2422:                RETURN_FALSE;
        !          2423:        }
        !          2424: 
        !          2425:        mblen = mbfl_strlen(&haystack);
        !          2426: 
        !          2427:        if (part) {
        !          2428:                ret = mbfl_substr(&haystack, &result, 0, n);
        !          2429:                if (ret != NULL) {
        !          2430:                        RETVAL_STRINGL((char *)ret->val, ret->len, 0);
        !          2431:                } else {
        !          2432:                        RETVAL_FALSE;
        !          2433:                }
        !          2434:        } else {
        !          2435:                len = (mblen - n);
        !          2436:                ret = mbfl_substr(&haystack, &result, n, len);
        !          2437:                if (ret != NULL) {
        !          2438:                        RETVAL_STRINGL((char *)ret->val, ret->len, 0);
        !          2439:                } else {
        !          2440:                        RETVAL_FALSE;
        !          2441:                }
        !          2442:        }
        !          2443: }
        !          2444: /* }}} */
        !          2445: 
        !          2446: /* {{{ proto string mb_strrichr(string haystack, string needle[, bool part[, string encoding]])
        !          2447:    Finds the last occurrence of a character in a string within another, case insensitive */
        !          2448: PHP_FUNCTION(mb_strrichr)
        !          2449: {
        !          2450:        zend_bool part = 0;
        !          2451:        int n, from_encoding_len, len, mblen;
        !          2452:        mbfl_string haystack, needle, result, *ret = NULL;
        !          2453:        char *from_encoding = (char*)mbfl_no2preferred_mime_name(MBSTRG(current_internal_encoding));
        !          2454:        mbfl_string_init(&haystack);
        !          2455:        mbfl_string_init(&needle);
        !          2456:        haystack.no_language = MBSTRG(language);
        !          2457:        haystack.no_encoding = MBSTRG(current_internal_encoding);
        !          2458:        needle.no_language = MBSTRG(language);
        !          2459:        needle.no_encoding = MBSTRG(current_internal_encoding);
        !          2460: 
        !          2461: 
        !          2462:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|bs", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &part, &from_encoding, &from_encoding_len) == FAILURE) {
        !          2463:                RETURN_FALSE;
        !          2464:        }
        !          2465: 
        !          2466:        haystack.no_encoding = needle.no_encoding = mbfl_name2no_encoding(from_encoding);
        !          2467:        if (haystack.no_encoding == mbfl_no_encoding_invalid) {
        !          2468:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", from_encoding);
        !          2469:                RETURN_FALSE;
        !          2470:        }
        !          2471: 
        !          2472:        n = php_mb_stripos(1, (char *)haystack.val, haystack.len, (char *)needle.val, needle.len, 0, from_encoding TSRMLS_CC);
        !          2473: 
        !          2474:        if (n <0) {
        !          2475:                RETURN_FALSE;
        !          2476:        }
        !          2477: 
        !          2478:        mblen = mbfl_strlen(&haystack);
        !          2479: 
        !          2480:        if (part) {
        !          2481:                ret = mbfl_substr(&haystack, &result, 0, n);
        !          2482:                if (ret != NULL) {
        !          2483:                        RETVAL_STRINGL((char *)ret->val, ret->len, 0);
        !          2484:                } else {
        !          2485:                        RETVAL_FALSE;
        !          2486:                }
        !          2487:        } else {
        !          2488:                len = (mblen - n);
        !          2489:                ret = mbfl_substr(&haystack, &result, n, len);
        !          2490:                if (ret != NULL) {
        !          2491:                        RETVAL_STRINGL((char *)ret->val, ret->len, 0);
        !          2492:                } else {
        !          2493:                        RETVAL_FALSE;
        !          2494:                }
        !          2495:        }
        !          2496: }
        !          2497: /* }}} */
        !          2498: 
        !          2499: /* {{{ proto int mb_substr_count(string haystack, string needle [, string encoding])
        !          2500:    Count the number of substring occurrences */
        !          2501: PHP_FUNCTION(mb_substr_count)
        !          2502: {
        !          2503:        int n;
        !          2504:        mbfl_string haystack, needle;
        !          2505:        char *enc_name = NULL;
        !          2506:        int enc_name_len;
        !          2507: 
        !          2508:        mbfl_string_init(&haystack);
        !          2509:        mbfl_string_init(&needle);
        !          2510:        haystack.no_language = MBSTRG(language);
        !          2511:        haystack.no_encoding = MBSTRG(current_internal_encoding);
        !          2512:        needle.no_language = MBSTRG(language);
        !          2513:        needle.no_encoding = MBSTRG(current_internal_encoding);
        !          2514: 
        !          2515:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &enc_name, &enc_name_len) == FAILURE) {
        !          2516:                return;
        !          2517:        }
        !          2518: 
        !          2519:        if (enc_name != NULL) {
        !          2520:                haystack.no_encoding = needle.no_encoding = mbfl_name2no_encoding(enc_name);
        !          2521:                if (haystack.no_encoding == mbfl_no_encoding_invalid) {
        !          2522:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", enc_name);
        !          2523:                        RETURN_FALSE;
        !          2524:                }
        !          2525:        }
        !          2526: 
        !          2527:        if (needle.len <= 0) {
        !          2528:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty substring");
        !          2529:                RETURN_FALSE;
        !          2530:        }
        !          2531: 
        !          2532:        n = mbfl_substr_count(&haystack, &needle);
        !          2533:        if (n >= 0) {
        !          2534:                RETVAL_LONG(n);
        !          2535:        } else {
        !          2536:                RETVAL_FALSE;
        !          2537:        }
        !          2538: }
        !          2539: /* }}} */
        !          2540: 
        !          2541: /* {{{ proto string mb_substr(string str, int start [, int length [, string encoding]])
        !          2542:    Returns part of a string */
        !          2543: PHP_FUNCTION(mb_substr)
        !          2544: {
        !          2545:        size_t argc = ZEND_NUM_ARGS();
        !          2546:        char *str, *encoding;
        !          2547:        long from, len;
        !          2548:        int mblen, str_len, encoding_len;
        !          2549:        mbfl_string string, result, *ret;
        !          2550: 
        !          2551:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|ls", &str, &str_len, &from, &len, &encoding, &encoding_len) == FAILURE) {
        !          2552:                return;
        !          2553:        }
        !          2554: 
        !          2555:        mbfl_string_init(&string);
        !          2556:        string.no_language = MBSTRG(language);
        !          2557:        string.no_encoding = MBSTRG(current_internal_encoding);
        !          2558: 
        !          2559:        if (argc == 4) {
        !          2560:                string.no_encoding = mbfl_name2no_encoding(encoding);
        !          2561:                if (string.no_encoding == mbfl_no_encoding_invalid) {
        !          2562:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", encoding);
        !          2563:                        RETURN_FALSE;
        !          2564:                }
        !          2565:        }
        !          2566: 
        !          2567:        string.val = (unsigned char *)str;
        !          2568:        string.len = str_len;
        !          2569: 
        !          2570:        if (argc < 3) {
        !          2571:                len = str_len;
        !          2572:        }
        !          2573: 
        !          2574:        /* measures length */
        !          2575:        mblen = 0;
        !          2576:        if (from < 0 || len < 0) {
        !          2577:                mblen = mbfl_strlen(&string);
        !          2578:        }
        !          2579: 
        !          2580:        /* if "from" position is negative, count start position from the end
        !          2581:         * of the string
        !          2582:         */
        !          2583:        if (from < 0) {
        !          2584:                from = mblen + from;
        !          2585:                if (from < 0) {
        !          2586:                        from = 0;
        !          2587:                }
        !          2588:        }
        !          2589: 
        !          2590:        /* if "length" position is negative, set it to the length
        !          2591:         * needed to stop that many chars from the end of the string
        !          2592:         */
        !          2593:        if (len < 0) {
        !          2594:                len = (mblen - from) + len;
        !          2595:                if (len < 0) {
        !          2596:                        len = 0;
        !          2597:                }
        !          2598:        }
        !          2599: 
        !          2600:        if (((MBSTRG(func_overload) & MB_OVERLOAD_STRING) == MB_OVERLOAD_STRING)
        !          2601:                && (from >= mbfl_strlen(&string))) {
        !          2602:                RETURN_FALSE;
        !          2603:        }
        !          2604: 
        !          2605:        ret = mbfl_substr(&string, &result, from, len);
        !          2606:        if (NULL == ret) {
        !          2607:                RETURN_FALSE;
        !          2608:        }
        !          2609: 
        !          2610:        RETURN_STRINGL((char *)ret->val, ret->len, 0); /* the string is already strdup()'ed */
        !          2611: }
        !          2612: /* }}} */
        !          2613: 
        !          2614: /* {{{ proto string mb_strcut(string str, int start [, int length [, string encoding]])
        !          2615:    Returns part of a string */
        !          2616: PHP_FUNCTION(mb_strcut)
        !          2617: {
        !          2618:        size_t argc = ZEND_NUM_ARGS();
        !          2619:        char *encoding;
        !          2620:        long from, len;
        !          2621:        int encoding_len;
        !          2622:        mbfl_string string, result, *ret;
        !          2623: 
        !          2624:        mbfl_string_init(&string);
        !          2625:        string.no_language = MBSTRG(language);
        !          2626:        string.no_encoding = MBSTRG(current_internal_encoding);
        !          2627: 
        !          2628:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|ls", (char **)&string.val, (int **)&string.len, &from, &len, &encoding, &encoding_len) == FAILURE) {
        !          2629:                return;
        !          2630:        }
        !          2631: 
        !          2632:        if (argc == 4) {
        !          2633:                string.no_encoding = mbfl_name2no_encoding(encoding);
        !          2634:                if (string.no_encoding == mbfl_no_encoding_invalid) {
        !          2635:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", encoding);
        !          2636:                        RETURN_FALSE;
        !          2637:                }
        !          2638:        }
        !          2639: 
        !          2640:        if (argc < 3) {
        !          2641:                len = string.len;
        !          2642:        }
        !          2643: 
        !          2644:        /* if "from" position is negative, count start position from the end
        !          2645:         * of the string
        !          2646:         */
        !          2647:        if (from < 0) {
        !          2648:                from = string.len + from;
        !          2649:                if (from < 0) {
        !          2650:                        from = 0;
        !          2651:                }
        !          2652:        }
        !          2653: 
        !          2654:        /* if "length" position is negative, set it to the length
        !          2655:         * needed to stop that many chars from the end of the string
        !          2656:         */
        !          2657:        if (len < 0) {
        !          2658:                len = (string.len - from) + len;
        !          2659:                if (len < 0) {
        !          2660:                        len = 0;
        !          2661:                }
        !          2662:        }
        !          2663: 
        !          2664:        if ((unsigned int)from > string.len) {
        !          2665:                RETURN_FALSE;
        !          2666:        }
        !          2667: 
        !          2668:        ret = mbfl_strcut(&string, &result, from, len);
        !          2669:        if (ret == NULL) {
        !          2670:                RETURN_FALSE;
        !          2671:        }
        !          2672: 
        !          2673:        RETURN_STRINGL((char *)ret->val, ret->len, 0); /* the string is already strdup()'ed */
        !          2674: }
        !          2675: /* }}} */
        !          2676: 
        !          2677: /* {{{ proto int mb_strwidth(string str [, string encoding])
        !          2678:    Gets terminal width of a string */
        !          2679: PHP_FUNCTION(mb_strwidth)
        !          2680: {
        !          2681:        int n;
        !          2682:        mbfl_string string;
        !          2683:        char *enc_name = NULL;
        !          2684:        int enc_name_len;
        !          2685: 
        !          2686:        mbfl_string_init(&string);
        !          2687: 
        !          2688:        string.no_language = MBSTRG(language);
        !          2689:        string.no_encoding = MBSTRG(current_internal_encoding);
        !          2690: 
        !          2691:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", (char **)&string.val, &string.len, &enc_name, &enc_name_len) == FAILURE) {
        !          2692:                return;
        !          2693:        }
        !          2694: 
        !          2695:        if (enc_name != NULL) {
        !          2696:                string.no_encoding = mbfl_name2no_encoding(enc_name);
        !          2697:                if (string.no_encoding == mbfl_no_encoding_invalid) {
        !          2698:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", enc_name);
        !          2699:                        RETURN_FALSE;
        !          2700:                }
        !          2701:        }
        !          2702: 
        !          2703:        n = mbfl_strwidth(&string);
        !          2704:        if (n >= 0) {
        !          2705:                RETVAL_LONG(n);
        !          2706:        } else {
        !          2707:                RETVAL_FALSE;
        !          2708:        }
        !          2709: }
        !          2710: /* }}} */
        !          2711: 
        !          2712: /* {{{ proto string mb_strimwidth(string str, int start, int width [, string trimmarker [, string encoding]])
        !          2713:    Trim the string in terminal width */
        !          2714: PHP_FUNCTION(mb_strimwidth)
        !          2715: {
        !          2716:        char *str, *trimmarker, *encoding;
        !          2717:        long from, width;
        !          2718:        int str_len, trimmarker_len, encoding_len;
        !          2719:        mbfl_string string, result, marker, *ret;
        !          2720: 
        !          2721:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll|ss", &str, &str_len, &from, &width, &trimmarker, &trimmarker_len, &encoding, &encoding_len) == FAILURE) {
        !          2722:                return;
        !          2723:        }
        !          2724: 
        !          2725:        mbfl_string_init(&string);
        !          2726:        mbfl_string_init(&marker);
        !          2727:        string.no_language = MBSTRG(language);
        !          2728:        string.no_encoding = MBSTRG(current_internal_encoding);
        !          2729:        marker.no_language = MBSTRG(language);
        !          2730:        marker.no_encoding = MBSTRG(current_internal_encoding);
        !          2731:        marker.val = NULL;
        !          2732:        marker.len = 0;
        !          2733: 
        !          2734:        if (ZEND_NUM_ARGS() == 5) {
        !          2735:                string.no_encoding = marker.no_encoding = mbfl_name2no_encoding(encoding);
        !          2736:                if (string.no_encoding == mbfl_no_encoding_invalid) {
        !          2737:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", encoding);
        !          2738:                        RETURN_FALSE;
        !          2739:                }
        !          2740:        }
        !          2741: 
        !          2742:        string.val = (unsigned char *)str;
        !          2743:        string.len = str_len;
        !          2744: 
        !          2745:        if (from < 0 || from > str_len) {
        !          2746:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Start position is out of range");
        !          2747:                RETURN_FALSE;
        !          2748:        }
        !          2749: 
        !          2750:        if (width < 0) {
        !          2751:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Width is negative value");
        !          2752:                RETURN_FALSE;
        !          2753:        }
        !          2754: 
        !          2755:        if (ZEND_NUM_ARGS() >= 4) {
        !          2756:                marker.val = (unsigned char *)trimmarker;
        !          2757:                marker.len = trimmarker_len;
        !          2758:        }
        !          2759: 
        !          2760:        ret = mbfl_strimwidth(&string, &marker, &result, from, width);
        !          2761: 
        !          2762:        if (ret == NULL) {
        !          2763:                RETURN_FALSE;
        !          2764:        }
        !          2765: 
        !          2766:        RETVAL_STRINGL((char *)ret->val, ret->len, 0); /* the string is already strdup()'ed */
        !          2767: }
        !          2768: /* }}} */
        !          2769: 
        !          2770: /* {{{ MBSTRING_API char *php_mb_convert_encoding() */
        !          2771: MBSTRING_API char * php_mb_convert_encoding(const char *input, size_t length, const char *_to_encoding, const char *_from_encodings, size_t *output_len TSRMLS_DC)
        !          2772: {
        !          2773:        mbfl_string string, result, *ret;
        !          2774:        enum mbfl_no_encoding from_encoding, to_encoding;
        !          2775:        mbfl_buffer_converter *convd;
        !          2776:        int size, *list;
        !          2777:        char *output=NULL;
        !          2778: 
        !          2779:        if (output_len) {
        !          2780:                *output_len = 0;
        !          2781:        }
        !          2782:        if (!input) {
        !          2783:                return NULL;
        !          2784:        }
        !          2785:        /* new encoding */
        !          2786:        if (_to_encoding && strlen(_to_encoding)) {
        !          2787:                to_encoding = mbfl_name2no_encoding(_to_encoding);
        !          2788:                if (to_encoding == mbfl_no_encoding_invalid) {
        !          2789:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", _to_encoding);
        !          2790:                        return NULL;
        !          2791:                }
        !          2792:        } else {
        !          2793:                to_encoding = MBSTRG(current_internal_encoding);
        !          2794:        }
        !          2795: 
        !          2796:        /* initialize string */
        !          2797:        mbfl_string_init(&string);
        !          2798:        mbfl_string_init(&result);
        !          2799:        from_encoding = MBSTRG(current_internal_encoding);
        !          2800:        string.no_encoding = from_encoding;
        !          2801:        string.no_language = MBSTRG(language);
        !          2802:        string.val = (unsigned char *)input;
        !          2803:        string.len = length;
        !          2804: 
        !          2805:        /* pre-conversion encoding */
        !          2806:        if (_from_encodings) {
        !          2807:                list = NULL;
        !          2808:                size = 0;
        !          2809:            php_mb_parse_encoding_list(_from_encodings, strlen(_from_encodings), &list, &size, 0 TSRMLS_CC);
        !          2810:                if (size == 1) {
        !          2811:                        from_encoding = *list;
        !          2812:                        string.no_encoding = from_encoding;
        !          2813:                } else if (size > 1) {
        !          2814:                        /* auto detect */
        !          2815:                        from_encoding = mbfl_identify_encoding_no(&string, list, size, MBSTRG(strict_detection));
        !          2816:                        if (from_encoding != mbfl_no_encoding_invalid) {
        !          2817:                                string.no_encoding = from_encoding;
        !          2818:                        } else {
        !          2819:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to detect character encoding");
        !          2820:                                from_encoding = mbfl_no_encoding_pass;
        !          2821:                                to_encoding = from_encoding;
        !          2822:                                string.no_encoding = from_encoding;
        !          2823:                        }
        !          2824:                } else {
        !          2825:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal character encoding specified");
        !          2826:                }
        !          2827:                if (list != NULL) {
        !          2828:                        efree((void *)list);
        !          2829:                }
        !          2830:        }
        !          2831: 
        !          2832:        /* initialize converter */
        !          2833:        convd = mbfl_buffer_converter_new(from_encoding, to_encoding, string.len);
        !          2834:        if (convd == NULL) {
        !          2835:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create character encoding converter");
        !          2836:                return NULL;
        !          2837:        }
        !          2838:        mbfl_buffer_converter_illegal_mode(convd, MBSTRG(current_filter_illegal_mode));
        !          2839:        mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar));
        !          2840: 
        !          2841:        /* do it */
        !          2842:        ret = mbfl_buffer_converter_feed_result(convd, &string, &result);
        !          2843:        if (ret) {
        !          2844:                if (output_len) {
        !          2845:                        *output_len = ret->len;
        !          2846:                }
        !          2847:                output = (char *)ret->val;
        !          2848:        }
        !          2849: 
        !          2850:        MBSTRG(illegalchars) += mbfl_buffer_illegalchars(convd);
        !          2851:        mbfl_buffer_converter_delete(convd);
        !          2852:        return output;
        !          2853: }
        !          2854: /* }}} */
        !          2855: 
        !          2856: /* {{{ proto string mb_convert_encoding(string str, string to-encoding [, mixed from-encoding])
        !          2857:    Returns converted string in desired encoding */
        !          2858: PHP_FUNCTION(mb_convert_encoding)
        !          2859: {
        !          2860:        char *arg_str, *arg_new;
        !          2861:        int str_len, new_len;
        !          2862:        zval *arg_old;
        !          2863:        int i;
        !          2864:        size_t size, l, n;
        !          2865:        char *_from_encodings = NULL, *ret, *s_free = NULL;
        !          2866: 
        !          2867:        zval **hash_entry;
        !          2868:        HashTable *target_hash;
        !          2869: 
        !          2870:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|z", &arg_str, &str_len, &arg_new, &new_len, &arg_old) == FAILURE) {
        !          2871:                return;
        !          2872:        }
        !          2873: 
        !          2874:        if (ZEND_NUM_ARGS() == 3) {
        !          2875:                switch (Z_TYPE_P(arg_old)) {
        !          2876:                case IS_ARRAY:
        !          2877:                        target_hash = Z_ARRVAL_P(arg_old);
        !          2878:                        zend_hash_internal_pointer_reset(target_hash);
        !          2879:                        i = zend_hash_num_elements(target_hash);
        !          2880:                        _from_encodings = NULL;
        !          2881: 
        !          2882:                        while (i > 0) {
        !          2883:                                if (zend_hash_get_current_data(target_hash, (void **) &hash_entry) == FAILURE) {
        !          2884:                                        break;
        !          2885:                                }
        !          2886: 
        !          2887:                                convert_to_string_ex(hash_entry);
        !          2888: 
        !          2889:                                if ( _from_encodings) {
        !          2890:                                        l = strlen(_from_encodings);
        !          2891:                                        n = strlen(Z_STRVAL_PP(hash_entry));
        !          2892:                                        _from_encodings = erealloc(_from_encodings, l+n+2);
        !          2893:                                        strcpy(_from_encodings+l, ",");
        !          2894:                                        strcpy(_from_encodings+l+1, Z_STRVAL_PP(hash_entry));
        !          2895:                                } else {
        !          2896:                                        _from_encodings = estrdup(Z_STRVAL_PP(hash_entry));
        !          2897:                                }
        !          2898: 
        !          2899:                                zend_hash_move_forward(target_hash);
        !          2900:                                i--;
        !          2901:                        }
        !          2902: 
        !          2903:                        if (_from_encodings != NULL && !strlen(_from_encodings)) {
        !          2904:                                efree(_from_encodings);
        !          2905:                                _from_encodings = NULL;
        !          2906:                        }
        !          2907:                        s_free = _from_encodings;
        !          2908:                        break;
        !          2909:                default:
        !          2910:                        convert_to_string(arg_old);
        !          2911:                        _from_encodings = Z_STRVAL_P(arg_old);
        !          2912:                        break;
        !          2913:                }
        !          2914:        }
        !          2915: 
        !          2916:        /* new encoding */
        !          2917:        ret = php_mb_convert_encoding(arg_str, str_len, arg_new, _from_encodings, &size TSRMLS_CC);
        !          2918:        if (ret != NULL) {
        !          2919:                RETVAL_STRINGL(ret, size, 0);           /* the string is already strdup()'ed */
        !          2920:        } else {
        !          2921:                RETVAL_FALSE;
        !          2922:        }
        !          2923: 
        !          2924:        if ( s_free) {
        !          2925:                efree(s_free);
        !          2926:        }
        !          2927: }
        !          2928: /* }}} */
        !          2929: 
        !          2930: /* {{{ proto string mb_convert_case(string sourcestring, int mode [, string encoding])
        !          2931:    Returns a case-folded version of sourcestring */
        !          2932: PHP_FUNCTION(mb_convert_case)
        !          2933: {
        !          2934:        char *str, *from_encoding = (char*)mbfl_no2preferred_mime_name(MBSTRG(current_internal_encoding));
        !          2935:        int str_len, from_encoding_len;
        !          2936:        long case_mode = 0;
        !          2937:        char *newstr;
        !          2938:        size_t ret_len;
        !          2939: 
        !          2940:        RETVAL_FALSE;
        !          2941:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|s!", &str, &str_len,
        !          2942:                                &case_mode, &from_encoding, &from_encoding_len) == FAILURE)
        !          2943:                RETURN_FALSE;
        !          2944: 
        !          2945:        newstr = php_unicode_convert_case(case_mode, str, (size_t) str_len, &ret_len, from_encoding TSRMLS_CC);
        !          2946: 
        !          2947:        if (newstr) {
        !          2948:                RETVAL_STRINGL(newstr, ret_len, 0);
        !          2949:        }       
        !          2950: }
        !          2951: /* }}} */
        !          2952: 
        !          2953: /* {{{ proto string mb_strtoupper(string sourcestring [, string encoding])
        !          2954:  *  Returns a uppercased version of sourcestring
        !          2955:  */
        !          2956: PHP_FUNCTION(mb_strtoupper)
        !          2957: {
        !          2958:        char *str, *from_encoding = (char*)mbfl_no2preferred_mime_name(MBSTRG(current_internal_encoding));
        !          2959:        int str_len, from_encoding_len;
        !          2960:        char *newstr;
        !          2961:        size_t ret_len;
        !          2962: 
        !          2963:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!", &str, &str_len,
        !          2964:                                &from_encoding, &from_encoding_len) == FAILURE) {
        !          2965:                return;
        !          2966:        }
        !          2967:        newstr = php_unicode_convert_case(PHP_UNICODE_CASE_UPPER, str, (size_t) str_len, &ret_len, from_encoding TSRMLS_CC);
        !          2968: 
        !          2969:        if (newstr) {
        !          2970:                RETURN_STRINGL(newstr, ret_len, 0);
        !          2971:        }
        !          2972:        RETURN_FALSE;
        !          2973: }
        !          2974: /* }}} */
        !          2975: 
        !          2976: /* {{{ proto string mb_strtolower(string sourcestring [, string encoding])
        !          2977:  *  Returns a lowercased version of sourcestring
        !          2978:  */
        !          2979: PHP_FUNCTION(mb_strtolower)
        !          2980: {
        !          2981:        char *str, *from_encoding = (char*)mbfl_no2preferred_mime_name(MBSTRG(current_internal_encoding));
        !          2982:        int str_len, from_encoding_len;
        !          2983:        char *newstr;
        !          2984:        size_t ret_len;
        !          2985: 
        !          2986:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!", &str, &str_len,
        !          2987:                                &from_encoding, &from_encoding_len) == FAILURE) {
        !          2988:                return;
        !          2989:        }
        !          2990:        newstr = php_unicode_convert_case(PHP_UNICODE_CASE_LOWER, str, (size_t) str_len, &ret_len, from_encoding TSRMLS_CC);
        !          2991: 
        !          2992:        if (newstr) {
        !          2993:                RETURN_STRINGL(newstr, ret_len, 0);
        !          2994:        }
        !          2995:        RETURN_FALSE;
        !          2996: }
        !          2997: /* }}} */
        !          2998: 
        !          2999: /* {{{ proto string mb_detect_encoding(string str [, mixed encoding_list [, bool strict]])
        !          3000:    Encodings of the given string is returned (as a string) */
        !          3001: PHP_FUNCTION(mb_detect_encoding)
        !          3002: {
        !          3003:        char *str;
        !          3004:        int str_len;
        !          3005:        zend_bool strict=0;
        !          3006:        zval *encoding_list;
        !          3007: 
        !          3008:        mbfl_string string;
        !          3009:        const char *ret;
        !          3010:        enum mbfl_no_encoding *elist;
        !          3011:        int size, *list;
        !          3012: 
        !          3013:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|zb", &str, &str_len, &encoding_list, &strict) == FAILURE) {
        !          3014:                return;
        !          3015:        }
        !          3016: 
        !          3017:        /* make encoding list */
        !          3018:        list = NULL;
        !          3019:        size = 0;
        !          3020:        if (ZEND_NUM_ARGS() >= 2 && !ZVAL_IS_NULL(encoding_list)) {
        !          3021:                switch (Z_TYPE_P(encoding_list)) {
        !          3022:                case IS_ARRAY:
        !          3023:                        if (!php_mb_parse_encoding_array(encoding_list, &list, &size, 0 TSRMLS_CC)) {
        !          3024:                                if (list) {
        !          3025:                                        efree(list);
        !          3026:                                        list = NULL;
        !          3027:                                        size = 0;
        !          3028:                                }
        !          3029:                        }
        !          3030:                        break;
        !          3031:                default:
        !          3032:                        convert_to_string(encoding_list);
        !          3033:                        if (!php_mb_parse_encoding_list(Z_STRVAL_P(encoding_list), Z_STRLEN_P(encoding_list), &list, &size, 0 TSRMLS_CC)) {
        !          3034:                                if (list) {
        !          3035:                                        efree(list);
        !          3036:                                        list = NULL;
        !          3037:                                        size = 0;
        !          3038:                                }
        !          3039:                        }
        !          3040:                        break;
        !          3041:                }
        !          3042:                if (size <= 0) {
        !          3043:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal argument");
        !          3044:                }
        !          3045:        }
        !          3046: 
        !          3047:        if (ZEND_NUM_ARGS() < 3) {
        !          3048:                strict = (zend_bool)MBSTRG(strict_detection);
        !          3049:        }
        !          3050: 
        !          3051:        if (size > 0 && list != NULL) {
        !          3052:                elist = list;
        !          3053:        } else {
        !          3054:                elist = MBSTRG(current_detect_order_list);
        !          3055:                size = MBSTRG(current_detect_order_list_size);
        !          3056:        }
        !          3057: 
        !          3058:        mbfl_string_init(&string);
        !          3059:        string.no_language = MBSTRG(language);
        !          3060:        string.val = (unsigned char *)str;
        !          3061:        string.len = str_len;
        !          3062:        ret = mbfl_identify_encoding_name(&string, elist, size, strict);
        !          3063: 
        !          3064:        if (list != NULL) {
        !          3065:                efree((void *)list);
        !          3066:        }
        !          3067: 
        !          3068:        if (ret == NULL) {
        !          3069:                RETURN_FALSE;
        !          3070:        }
        !          3071: 
        !          3072:        RETVAL_STRING((char *)ret, 1);
        !          3073: }
        !          3074: /* }}} */
        !          3075: 
        !          3076: /* {{{ proto mixed mb_list_encodings()
        !          3077:    Returns an array of all supported entity encodings */
        !          3078: PHP_FUNCTION(mb_list_encodings)
        !          3079: {
        !          3080:        const mbfl_encoding **encodings;
        !          3081:        const mbfl_encoding *encoding;
        !          3082:        int i;
        !          3083: 
        !          3084:        array_init(return_value);
        !          3085:        i = 0;
        !          3086:        encodings = mbfl_get_supported_encodings();
        !          3087:        while ((encoding = encodings[i++]) != NULL) {
        !          3088:                add_next_index_string(return_value, (char *) encoding->name, 1);
        !          3089:        }
        !          3090: }
        !          3091: /* }}} */
        !          3092: 
        !          3093: /* {{{ proto array mb_encoding_aliases(string encoding)
        !          3094:    Returns an array of the aliases of a given encoding name */
        !          3095: PHP_FUNCTION(mb_encoding_aliases)
        !          3096: {
        !          3097:        const mbfl_encoding *encoding;
        !          3098:        char *name = NULL;
        !          3099:        int name_len;
        !          3100: 
        !          3101:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
        !          3102:                RETURN_FALSE;
        !          3103:        }
        !          3104: 
        !          3105:        encoding = mbfl_name2encoding(name);
        !          3106:        if (!encoding) {
        !          3107:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", name);
        !          3108:                RETURN_FALSE;
        !          3109:        }
        !          3110: 
        !          3111:        array_init(return_value);
        !          3112:        if (encoding->aliases != NULL) {
        !          3113:                const char **alias;
        !          3114:                for (alias = *encoding->aliases; *alias; ++alias) {
        !          3115:                        add_next_index_string(return_value, (char *)*alias, 1);
        !          3116:                }
        !          3117:        }
        !          3118: }
        !          3119: /* }}} */
        !          3120: 
        !          3121: /* {{{ proto string mb_encode_mimeheader(string str [, string charset [, string transfer-encoding [, string linefeed [, int indent]]]])
        !          3122:    Converts the string to MIME "encoded-word" in the format of =?charset?(B|Q)?encoded_string?= */
        !          3123: PHP_FUNCTION(mb_encode_mimeheader)
        !          3124: {
        !          3125:        enum mbfl_no_encoding charset, transenc;
        !          3126:        mbfl_string  string, result, *ret;
        !          3127:        char *charset_name = NULL;
        !          3128:        int charset_name_len;
        !          3129:        char *trans_enc_name = NULL;
        !          3130:        int trans_enc_name_len;
        !          3131:        char *linefeed = "\r\n";
        !          3132:        int linefeed_len;
        !          3133:        long indent = 0;
        !          3134: 
        !          3135:        mbfl_string_init(&string);
        !          3136:        string.no_language = MBSTRG(language);
        !          3137:        string.no_encoding = MBSTRG(current_internal_encoding);
        !          3138: 
        !          3139:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sssl", (char **)&string.val, &string.len, &charset_name, &charset_name_len, &trans_enc_name, &trans_enc_name_len, &linefeed, &linefeed_len, &indent) == FAILURE) {
        !          3140:                return;
        !          3141:        }
        !          3142: 
        !          3143:        charset = mbfl_no_encoding_pass;
        !          3144:        transenc = mbfl_no_encoding_base64;
        !          3145: 
        !          3146:        if (charset_name != NULL) {
        !          3147:                charset = mbfl_name2no_encoding(charset_name);
        !          3148:                if (charset == mbfl_no_encoding_invalid) {
        !          3149:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", charset_name);
        !          3150:                        RETURN_FALSE;
        !          3151:                }
        !          3152:        } else {
        !          3153:                const mbfl_language *lang = mbfl_no2language(MBSTRG(language));
        !          3154:                if (lang != NULL) {
        !          3155:                        charset = lang->mail_charset;
        !          3156:                        transenc = lang->mail_header_encoding;
        !          3157:                }
        !          3158:        }
        !          3159: 
        !          3160:        if (trans_enc_name != NULL) {
        !          3161:                if (*trans_enc_name == 'B' || *trans_enc_name == 'b') {
        !          3162:                        transenc = mbfl_no_encoding_base64;
        !          3163:                } else if (*trans_enc_name == 'Q' || *trans_enc_name == 'q') {
        !          3164:                        transenc = mbfl_no_encoding_qprint;
        !          3165:                }
        !          3166:        }
        !          3167: 
        !          3168:        mbfl_string_init(&result);
        !          3169:        ret = mbfl_mime_header_encode(&string, &result, charset, transenc, linefeed, indent);
        !          3170:        if (ret != NULL) {
        !          3171:                RETVAL_STRINGL((char *)ret->val, ret->len, 0)   /* the string is already strdup()'ed */
        !          3172:        } else {
        !          3173:                RETVAL_FALSE;
        !          3174:        }
        !          3175: }
        !          3176: /* }}} */
        !          3177: 
        !          3178: /* {{{ proto string mb_decode_mimeheader(string string)
        !          3179:    Decodes the MIME "encoded-word" in the string */
        !          3180: PHP_FUNCTION(mb_decode_mimeheader)
        !          3181: {
        !          3182:        mbfl_string string, result, *ret;
        !          3183: 
        !          3184:        mbfl_string_init(&string);
        !          3185:        string.no_language = MBSTRG(language);
        !          3186:        string.no_encoding = MBSTRG(current_internal_encoding);
        !          3187: 
        !          3188:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", (char **)&string.val, &string.len) == FAILURE) {
        !          3189:                return;
        !          3190:        }
        !          3191: 
        !          3192:        mbfl_string_init(&result);
        !          3193:        ret = mbfl_mime_header_decode(&string, &result, MBSTRG(current_internal_encoding));
        !          3194:        if (ret != NULL) {
        !          3195:                RETVAL_STRINGL((char *)ret->val, ret->len, 0)   /* the string is already strdup()'ed */
        !          3196:        } else {
        !          3197:                RETVAL_FALSE;
        !          3198:        }
        !          3199: }
        !          3200: /* }}} */
        !          3201: 
        !          3202: /* {{{ proto string mb_convert_kana(string str [, string option] [, string encoding])
        !          3203:    Conversion between full-width character and half-width character (Japanese) */
        !          3204: PHP_FUNCTION(mb_convert_kana)
        !          3205: {
        !          3206:        int opt, i;
        !          3207:        mbfl_string string, result, *ret;
        !          3208:        char *optstr = NULL;
        !          3209:        int optstr_len;
        !          3210:        char *encname = NULL;
        !          3211:        int encname_len;
        !          3212: 
        !          3213:        mbfl_string_init(&string);
        !          3214:        string.no_language = MBSTRG(language);
        !          3215:        string.no_encoding = MBSTRG(current_internal_encoding);
        !          3216: 
        !          3217:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ss", (char **)&string.val, &string.len, &optstr, &optstr_len, &encname, &encname_len) == FAILURE) {
        !          3218:                return;
        !          3219:        }
        !          3220: 
        !          3221:        /* option */
        !          3222:        if (optstr != NULL) {
        !          3223:                char *p = optstr;
        !          3224:                int n = optstr_len;
        !          3225:                i = 0;
        !          3226:                opt = 0;
        !          3227:                while (i < n) {
        !          3228:                        i++;
        !          3229:                        switch (*p++) {
        !          3230:                        case 'A':
        !          3231:                                opt |= 0x1;
        !          3232:                                break;
        !          3233:                        case 'a':
        !          3234:                                opt |= 0x10;
        !          3235:                                break;
        !          3236:                        case 'R':
        !          3237:                                opt |= 0x2;
        !          3238:                                break;
        !          3239:                        case 'r':
        !          3240:                                opt |= 0x20;
        !          3241:                                break;
        !          3242:                        case 'N':
        !          3243:                                opt |= 0x4;
        !          3244:                                break;
        !          3245:                        case 'n':
        !          3246:                                opt |= 0x40;
        !          3247:                                break;
        !          3248:                        case 'S':
        !          3249:                                opt |= 0x8;
        !          3250:                                break;
        !          3251:                        case 's':
        !          3252:                                opt |= 0x80;
        !          3253:                                break;
        !          3254:                        case 'K':
        !          3255:                                opt |= 0x100;
        !          3256:                                break;
        !          3257:                        case 'k':
        !          3258:                                opt |= 0x1000;
        !          3259:                                break;
        !          3260:                        case 'H':
        !          3261:                                opt |= 0x200;
        !          3262:                                break;
        !          3263:                        case 'h':
        !          3264:                                opt |= 0x2000;
        !          3265:                                break;
        !          3266:                        case 'V':
        !          3267:                                opt |= 0x800;
        !          3268:                                break;
        !          3269:                        case 'C':
        !          3270:                                opt |= 0x10000;
        !          3271:                                break;
        !          3272:                        case 'c':
        !          3273:                                opt |= 0x20000;
        !          3274:                                break;
        !          3275:                        case 'M':
        !          3276:                                opt |= 0x100000;
        !          3277:                                break;
        !          3278:                        case 'm':
        !          3279:                                opt |= 0x200000;
        !          3280:                                break;
        !          3281:                        }
        !          3282:                }
        !          3283:        } else {
        !          3284:                opt = 0x900;
        !          3285:        }
        !          3286: 
        !          3287:        /* encoding */
        !          3288:        if (encname != NULL) {
        !          3289:                string.no_encoding = mbfl_name2no_encoding(encname);
        !          3290:                if (string.no_encoding == mbfl_no_encoding_invalid) {
        !          3291:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", encname);
        !          3292:                        RETURN_FALSE;
        !          3293:                }
        !          3294:        }
        !          3295: 
        !          3296:        ret = mbfl_ja_jp_hantozen(&string, &result, opt);
        !          3297:        if (ret != NULL) {
        !          3298:                RETVAL_STRINGL((char *)ret->val, ret->len, 0);          /* the string is already strdup()'ed */
        !          3299:        } else {
        !          3300:                RETVAL_FALSE;
        !          3301:        }
        !          3302: }
        !          3303: /* }}} */
        !          3304: 
        !          3305: #define PHP_MBSTR_STACK_BLOCK_SIZE 32
        !          3306: 
        !          3307: /* {{{ proto string mb_convert_variables(string to-encoding, mixed from-encoding, mixed vars [, ...])
        !          3308:    Converts the string resource in variables to desired encoding */
        !          3309: PHP_FUNCTION(mb_convert_variables)
        !          3310: {
        !          3311:        zval ***args, ***stack, **var, **hash_entry, **zfrom_enc;
        !          3312:        HashTable *target_hash;
        !          3313:        mbfl_string string, result, *ret;
        !          3314:        enum mbfl_no_encoding from_encoding, to_encoding;
        !          3315:        mbfl_encoding_detector *identd;
        !          3316:        mbfl_buffer_converter *convd;
        !          3317:        int n, to_enc_len, argc, stack_level, stack_max, elistsz;
        !          3318:        enum mbfl_no_encoding *elist;
        !          3319:        char *name, *to_enc;
        !          3320:        void *ptmp;     
        !          3321:        
        !          3322:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sZ+", &to_enc, &to_enc_len, &zfrom_enc, &args, &argc) == FAILURE) {
        !          3323:                return;
        !          3324:        }
        !          3325: 
        !          3326:        /* new encoding */
        !          3327:        to_encoding = mbfl_name2no_encoding(to_enc);
        !          3328:        if (to_encoding == mbfl_no_encoding_invalid) {
        !          3329:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", to_enc);
        !          3330:                efree(args);
        !          3331:                RETURN_FALSE;
        !          3332:        }
        !          3333: 
        !          3334:        /* initialize string */
        !          3335:        mbfl_string_init(&string);
        !          3336:        mbfl_string_init(&result);
        !          3337:        from_encoding = MBSTRG(current_internal_encoding);
        !          3338:        string.no_encoding = from_encoding;
        !          3339:        string.no_language = MBSTRG(language);
        !          3340: 
        !          3341:        /* pre-conversion encoding */
        !          3342:        elist = NULL;
        !          3343:        elistsz = 0;
        !          3344:        switch (Z_TYPE_PP(zfrom_enc)) {
        !          3345:        case IS_ARRAY:
        !          3346:                php_mb_parse_encoding_array(*zfrom_enc, &elist, &elistsz, 0 TSRMLS_CC);
        !          3347:                break;
        !          3348:        default:
        !          3349:                convert_to_string_ex(zfrom_enc);
        !          3350:                php_mb_parse_encoding_list(Z_STRVAL_PP(zfrom_enc), Z_STRLEN_PP(zfrom_enc), &elist, &elistsz, 0 TSRMLS_CC);
        !          3351:                break;
        !          3352:        }
        !          3353:        if (elistsz <= 0) {
        !          3354:                from_encoding = mbfl_no_encoding_pass;
        !          3355:        } else if (elistsz == 1) {
        !          3356:                from_encoding = *elist;
        !          3357:        } else {
        !          3358:                /* auto detect */
        !          3359:                from_encoding = mbfl_no_encoding_invalid;
        !          3360:                stack_max = PHP_MBSTR_STACK_BLOCK_SIZE;
        !          3361:                stack = (zval ***)safe_emalloc(stack_max, sizeof(zval **), 0);
        !          3362:                stack_level = 0;
        !          3363:                identd = mbfl_encoding_detector_new(elist, elistsz, MBSTRG(strict_detection));
        !          3364:                if (identd != NULL) {
        !          3365:                        n = 0;
        !          3366:                        while (n < argc || stack_level > 0) {
        !          3367:                                if (stack_level <= 0) {
        !          3368:                                        var = args[n++];
        !          3369:                                        if (Z_TYPE_PP(var) == IS_ARRAY || Z_TYPE_PP(var) == IS_OBJECT) {
        !          3370:                                                target_hash = HASH_OF(*var);
        !          3371:                                                if (target_hash != NULL) {
        !          3372:                                                        zend_hash_internal_pointer_reset(target_hash);
        !          3373:                                                }
        !          3374:                                        }
        !          3375:                                } else {
        !          3376:                                        stack_level--;
        !          3377:                                        var = stack[stack_level];
        !          3378:                                }
        !          3379:                                if (Z_TYPE_PP(var) == IS_ARRAY || Z_TYPE_PP(var) == IS_OBJECT) {
        !          3380:                                        target_hash = HASH_OF(*var);
        !          3381:                                        if (target_hash != NULL) {
        !          3382:                                                while (zend_hash_get_current_data(target_hash, (void **) &hash_entry) != FAILURE) {
        !          3383:                                                        zend_hash_move_forward(target_hash);
        !          3384:                                                        if (Z_TYPE_PP(hash_entry) == IS_ARRAY || Z_TYPE_PP(hash_entry) == IS_OBJECT) {
        !          3385:                                                                if (stack_level >= stack_max) {
        !          3386:                                                                        stack_max += PHP_MBSTR_STACK_BLOCK_SIZE;
        !          3387:                                                                        ptmp = erealloc(stack, sizeof(zval **)*stack_max);
        !          3388:                                                                        stack = (zval ***)ptmp;
        !          3389:                                                                }
        !          3390:                                                                stack[stack_level] = var;
        !          3391:                                                                stack_level++;
        !          3392:                                                                var = hash_entry;
        !          3393:                                                                target_hash = HASH_OF(*var);
        !          3394:                                                                if (target_hash != NULL) {
        !          3395:                                                                        zend_hash_internal_pointer_reset(target_hash);
        !          3396:                                                                        continue;
        !          3397:                                                                }
        !          3398:                                                        } else if (Z_TYPE_PP(hash_entry) == IS_STRING) {
        !          3399:                                                                string.val = (unsigned char *)Z_STRVAL_PP(hash_entry);
        !          3400:                                                                string.len = Z_STRLEN_PP(hash_entry);
        !          3401:                                                                if (mbfl_encoding_detector_feed(identd, &string)) {
        !          3402:                                                                        goto detect_end;                /* complete detecting */
        !          3403:                                                                }
        !          3404:                                                        }
        !          3405:                                                }
        !          3406:                                        }
        !          3407:                                } else if (Z_TYPE_PP(var) == IS_STRING) {
        !          3408:                                        string.val = (unsigned char *)Z_STRVAL_PP(var);
        !          3409:                                        string.len = Z_STRLEN_PP(var);
        !          3410:                                        if (mbfl_encoding_detector_feed(identd, &string)) {
        !          3411:                                                goto detect_end;                /* complete detecting */
        !          3412:                                        }
        !          3413:                                }
        !          3414:                        }
        !          3415: detect_end:
        !          3416:                        from_encoding = mbfl_encoding_detector_judge(identd);
        !          3417:                        mbfl_encoding_detector_delete(identd);
        !          3418:                }
        !          3419:                efree(stack);
        !          3420: 
        !          3421:                if (from_encoding == mbfl_no_encoding_invalid) {
        !          3422:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to detect encoding");
        !          3423:                        from_encoding = mbfl_no_encoding_pass;
        !          3424:                }
        !          3425:        }
        !          3426:        if (elist != NULL) {
        !          3427:                efree((void *)elist);
        !          3428:        }
        !          3429:        /* create converter */
        !          3430:        convd = NULL;
        !          3431:        if (from_encoding != mbfl_no_encoding_pass) {
        !          3432:                convd = mbfl_buffer_converter_new(from_encoding, to_encoding, 0);
        !          3433:                if (convd == NULL) {
        !          3434:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create converter");
        !          3435:                        RETURN_FALSE;
        !          3436:                }
        !          3437:                mbfl_buffer_converter_illegal_mode(convd, MBSTRG(current_filter_illegal_mode));
        !          3438:                mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar));
        !          3439:        }
        !          3440: 
        !          3441:        /* convert */
        !          3442:        if (convd != NULL) {
        !          3443:                stack_max = PHP_MBSTR_STACK_BLOCK_SIZE;
        !          3444:                stack = (zval ***)safe_emalloc(stack_max, sizeof(zval **), 0);
        !          3445:                stack_level = 0;
        !          3446:                n = 0;
        !          3447:                while (n < argc || stack_level > 0) {
        !          3448:                        if (stack_level <= 0) {
        !          3449:                                var = args[n++];
        !          3450:                                if (Z_TYPE_PP(var) == IS_ARRAY || Z_TYPE_PP(var) == IS_OBJECT) {
        !          3451:                                        target_hash = HASH_OF(*var);
        !          3452:                                        if (target_hash != NULL) {
        !          3453:                                                zend_hash_internal_pointer_reset(target_hash);
        !          3454:                                        }
        !          3455:                                }
        !          3456:                        } else {
        !          3457:                                stack_level--;
        !          3458:                                var = stack[stack_level];
        !          3459:                        }
        !          3460:                        if (Z_TYPE_PP(var) == IS_ARRAY || Z_TYPE_PP(var) == IS_OBJECT) {
        !          3461:                                target_hash = HASH_OF(*var);
        !          3462:                                if (target_hash != NULL) {
        !          3463:                                        while (zend_hash_get_current_data(target_hash, (void **) &hash_entry) != FAILURE) {
        !          3464:                                                zend_hash_move_forward(target_hash);
        !          3465:                                                if (Z_TYPE_PP(hash_entry) == IS_ARRAY || Z_TYPE_PP(hash_entry) == IS_OBJECT) {
        !          3466:                                                        if (stack_level >= stack_max) {
        !          3467:                                                                stack_max += PHP_MBSTR_STACK_BLOCK_SIZE;
        !          3468:                                                                ptmp = erealloc(stack, sizeof(zval **)*stack_max);
        !          3469:                                                                stack = (zval ***)ptmp;
        !          3470:                                                        }
        !          3471:                                                        stack[stack_level] = var;
        !          3472:                                                        stack_level++;
        !          3473:                                                        var = hash_entry;
        !          3474:                                                        SEPARATE_ZVAL(hash_entry);
        !          3475:                                                        target_hash = HASH_OF(*var);
        !          3476:                                                        if (target_hash != NULL) {
        !          3477:                                                                zend_hash_internal_pointer_reset(target_hash);
        !          3478:                                                                continue;
        !          3479:                                                        }
        !          3480:                                                } else if (Z_TYPE_PP(hash_entry) == IS_STRING) {
        !          3481:                                                        string.val = (unsigned char *)Z_STRVAL_PP(hash_entry);
        !          3482:                                                        string.len = Z_STRLEN_PP(hash_entry);
        !          3483:                                                        ret = mbfl_buffer_converter_feed_result(convd, &string, &result);
        !          3484:                                                        if (ret != NULL) {
        !          3485:                                                                if (Z_REFCOUNT_PP(hash_entry) > 1) {
        !          3486:                                                                        Z_DELREF_PP(hash_entry);
        !          3487:                                                                        MAKE_STD_ZVAL(*hash_entry);
        !          3488:                                                                } else {
        !          3489:                                                                        zval_dtor(*hash_entry);
        !          3490:                                                                }
        !          3491:                                                        ZVAL_STRINGL(*hash_entry, (char *)ret->val, ret->len, 0);
        !          3492:                                                }
        !          3493:                                        }
        !          3494:                                }
        !          3495:                        }
        !          3496:                } else if (Z_TYPE_PP(var) == IS_STRING) {
        !          3497:                        string.val = (unsigned char *)Z_STRVAL_PP(var);
        !          3498:                        string.len = Z_STRLEN_PP(var);
        !          3499:                        ret = mbfl_buffer_converter_feed_result(convd, &string, &result);
        !          3500:                        if (ret != NULL) {
        !          3501:                                zval_dtor(*var);
        !          3502:                                ZVAL_STRINGL(*var, (char *)ret->val, ret->len, 0);
        !          3503:                                }
        !          3504:                        }
        !          3505:                }
        !          3506:                efree(stack);
        !          3507: 
        !          3508:                MBSTRG(illegalchars) += mbfl_buffer_illegalchars(convd);
        !          3509:                mbfl_buffer_converter_delete(convd);
        !          3510:        }
        !          3511: 
        !          3512:        efree(args);
        !          3513: 
        !          3514:        name = (char *)mbfl_no_encoding2name(from_encoding);
        !          3515:        if (name != NULL) {
        !          3516:                RETURN_STRING(name, 1);
        !          3517:        } else {
        !          3518:                RETURN_FALSE;
        !          3519:        }
        !          3520: }
        !          3521: /* }}} */
        !          3522: 
        !          3523: /* {{{ HTML numeric entity */
        !          3524: /* {{{ static void php_mb_numericentity_exec() */
        !          3525: static void
        !          3526: php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAMETERS, int type)
        !          3527: {
        !          3528:        char *str, *encoding;
        !          3529:        int str_len, encoding_len;
        !          3530:        zval *zconvmap, **hash_entry;
        !          3531:        HashTable *target_hash;
        !          3532:        size_t argc = ZEND_NUM_ARGS();
        !          3533:        int i, *convmap, *mapelm, mapsize=0;
        !          3534:        mbfl_string string, result, *ret;
        !          3535:        enum mbfl_no_encoding no_encoding;
        !          3536: 
        !          3537:        if (zend_parse_parameters(argc TSRMLS_CC, "szs", &str, &str_len, &zconvmap, &encoding, &encoding_len) == FAILURE) {
        !          3538:                return;
        !          3539:        }
        !          3540: 
        !          3541:        mbfl_string_init(&string);
        !          3542:        string.no_language = MBSTRG(language);
        !          3543:        string.no_encoding = MBSTRG(current_internal_encoding);
        !          3544:        string.val = (unsigned char *)str;
        !          3545:        string.len = str_len;
        !          3546: 
        !          3547:        /* encoding */
        !          3548:        if (argc == 3) {
        !          3549:                no_encoding = mbfl_name2no_encoding(encoding);
        !          3550:                if (no_encoding == mbfl_no_encoding_invalid) {
        !          3551:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", encoding);
        !          3552:                        RETURN_FALSE;
        !          3553:                } else {
        !          3554:                        string.no_encoding = no_encoding;
        !          3555:                }
        !          3556:        }
        !          3557: 
        !          3558:        /* conversion map */
        !          3559:        convmap = NULL;
        !          3560:        if (Z_TYPE_P(zconvmap) == IS_ARRAY) {
        !          3561:                target_hash = Z_ARRVAL_P(zconvmap);
        !          3562:                zend_hash_internal_pointer_reset(target_hash);
        !          3563:                i = zend_hash_num_elements(target_hash);
        !          3564:                if (i > 0) {
        !          3565:                        convmap = (int *)safe_emalloc(i, sizeof(int), 0);
        !          3566:                        mapelm = convmap;
        !          3567:                        mapsize = 0;
        !          3568:                        while (i > 0) {
        !          3569:                                if (zend_hash_get_current_data(target_hash, (void **) &hash_entry) == FAILURE) {
        !          3570:                                        break;
        !          3571:                                }
        !          3572:                                convert_to_long_ex(hash_entry);
        !          3573:                                *mapelm++ = Z_LVAL_PP(hash_entry);
        !          3574:                                mapsize++;
        !          3575:                                i--;
        !          3576:                                zend_hash_move_forward(target_hash);
        !          3577:                        }
        !          3578:                }
        !          3579:        }
        !          3580:        if (convmap == NULL) {
        !          3581:                RETURN_FALSE;
        !          3582:        }
        !          3583:        mapsize /= 4;
        !          3584: 
        !          3585:        ret = mbfl_html_numeric_entity(&string, &result, convmap, mapsize, type);
        !          3586:        if (ret != NULL) {
        !          3587:                RETVAL_STRINGL((char *)ret->val, ret->len, 0);
        !          3588:        } else {
        !          3589:                RETVAL_FALSE;
        !          3590:        }
        !          3591:        efree((void *)convmap);
        !          3592: }
        !          3593: /* }}} */
        !          3594: 
        !          3595: /* {{{ proto string mb_encode_numericentity(string string, array convmap [, string encoding])
        !          3596:    Converts specified characters to HTML numeric entities */
        !          3597: PHP_FUNCTION(mb_encode_numericentity)
        !          3598: {
        !          3599:        php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
        !          3600: }
        !          3601: /* }}} */
        !          3602: 
        !          3603: /* {{{ proto string mb_decode_numericentity(string string, array convmap [, string encoding])
        !          3604:    Converts HTML numeric entities to character code */
        !          3605: PHP_FUNCTION(mb_decode_numericentity)
        !          3606: {
        !          3607:        php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
        !          3608: }
        !          3609: /* }}} */
        !          3610: /* }}} */
        !          3611: 
        !          3612: /* {{{ proto int mb_send_mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]])
        !          3613:  *  Sends an email message with MIME scheme
        !          3614:  */
        !          3615: 
        !          3616: #define SKIP_LONG_HEADER_SEP_MBSTRING(str, pos)                                                                                \
        !          3617:        if (str[pos] == '\r' && str[pos + 1] == '\n' && (str[pos + 2] == ' ' || str[pos + 2] == '\t')) {        \
        !          3618:                pos += 2;                                                                                       \
        !          3619:                while (str[pos + 1] == ' ' || str[pos + 1] == '\t') {                                                   \
        !          3620:                        pos++;                                                                                  \
        !          3621:                }                                                                                               \
        !          3622:                continue;                                                                                       \
        !          3623:        }
        !          3624: 
        !          3625: #define MAIL_ASCIIZ_CHECK_MBSTRING(str, len)                   \
        !          3626:        pp = str;                                       \
        !          3627:        ee = pp + len;                                  \
        !          3628:        while ((pp = memchr(pp, '\0', (ee - pp)))) {    \
        !          3629:                *pp = ' ';                              \
        !          3630:        }                                               \
        !          3631: 
        !          3632: #define APPEND_ONE_CHAR(ch) do { \
        !          3633:        if (token.a > 0) { \
        !          3634:                smart_str_appendc(&token, ch); \
        !          3635:        } else {\
        !          3636:                token.len++; \
        !          3637:        } \
        !          3638: } while (0)
        !          3639: 
        !          3640: #define SEPARATE_SMART_STR(str) do {\
        !          3641:        if ((str)->a == 0) { \
        !          3642:                char *tmp_ptr; \
        !          3643:                (str)->a = 1; \
        !          3644:                while ((str)->a < (str)->len) { \
        !          3645:                        (str)->a <<= 1; \
        !          3646:                } \
        !          3647:                tmp_ptr = emalloc((str)->a + 1); \
        !          3648:                memcpy(tmp_ptr, (str)->c, (str)->len); \
        !          3649:                (str)->c = tmp_ptr; \
        !          3650:        } \
        !          3651: } while (0)
        !          3652: 
        !          3653: static void my_smart_str_dtor(smart_str *s)
        !          3654: {
        !          3655:        if (s->a > 0) {
        !          3656:                smart_str_free(s);
        !          3657:        }
        !          3658: }
        !          3659: 
        !          3660: static int _php_mbstr_parse_mail_headers(HashTable *ht, const char *str, size_t str_len)
        !          3661: {
        !          3662:        const char *ps;
        !          3663:        size_t icnt;
        !          3664:        int state = 0;
        !          3665:        int crlf_state = -1;
        !          3666: 
        !          3667:        smart_str token = { 0, 0, 0 };
        !          3668:        smart_str fld_name = { 0, 0, 0 }, fld_val = { 0, 0, 0 };
        !          3669: 
        !          3670:        ps = str;
        !          3671:        icnt = str_len;
        !          3672: 
        !          3673:        /*
        !          3674:         *             C o n t e n t - T y p e :   t e x t / h t m l \r\n
        !          3675:         *             ^ ^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^ ^^^^ 
        !          3676:         *      state  0            1           2          3          
        !          3677:         *
        !          3678:         *             C o n t e n t - T y p e :   t e x t / h t m l \r\n
        !          3679:         *             ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ 
        !          3680:         * crlf_state -1                       0                     1 -1  
        !          3681:         *
        !          3682:         */
        !          3683: 
        !          3684:        while (icnt > 0) {
        !          3685:                switch (*ps) {
        !          3686:                        case ':':
        !          3687:                                if (crlf_state == 1) {
        !          3688:                                        APPEND_ONE_CHAR('\r');
        !          3689:                                }
        !          3690: 
        !          3691:                                if (state == 0 || state == 1) {
        !          3692:                                        fld_name = token;
        !          3693: 
        !          3694:                                        state = 2;
        !          3695:                                } else {
        !          3696:                                        APPEND_ONE_CHAR(*ps);
        !          3697:                                }
        !          3698: 
        !          3699:                                crlf_state = 0;
        !          3700:                                break;
        !          3701: 
        !          3702:                        case '\n':
        !          3703:                                if (crlf_state == -1) {
        !          3704:                                        goto out;
        !          3705:                                }
        !          3706:                                crlf_state = -1;
        !          3707:                                break;
        !          3708: 
        !          3709:                        case '\r':
        !          3710:                                if (crlf_state == 1) {
        !          3711:                                        APPEND_ONE_CHAR('\r');
        !          3712:                                } else {
        !          3713:                                        crlf_state = 1;
        !          3714:                                }
        !          3715:                                break;
        !          3716: 
        !          3717:                        case ' ': case '\t':
        !          3718:                                if (crlf_state == -1) {
        !          3719:                                        if (state == 3) {
        !          3720:                                                /* continuing from the previous line */
        !          3721:                                                SEPARATE_SMART_STR(&token);
        !          3722:                                                state = 4;
        !          3723:                                        } else {
        !          3724:                                                /* simply skipping this new line */
        !          3725:                                                state = 5;
        !          3726:                                        }
        !          3727:                                } else {
        !          3728:                                        if (crlf_state == 1) {
        !          3729:                                                APPEND_ONE_CHAR('\r');
        !          3730:                                        }
        !          3731:                                        if (state == 1 || state == 3) {
        !          3732:                                                APPEND_ONE_CHAR(*ps);
        !          3733:                                        }
        !          3734:                                }
        !          3735:                                crlf_state = 0;
        !          3736:                                break;
        !          3737: 
        !          3738:                        default:
        !          3739:                                switch (state) {
        !          3740:                                        case 0:
        !          3741:                                                token.c = (char *)ps;
        !          3742:                                                token.len = 0;
        !          3743:                                                token.a = 0;
        !          3744:                                                state = 1;
        !          3745:                                                break;
        !          3746:                                        
        !          3747:                                        case 2:
        !          3748:                                                if (crlf_state != -1) {
        !          3749:                                                        token.c = (char *)ps;
        !          3750:                                                        token.len = 0;
        !          3751:                                                        token.a = 0;
        !          3752: 
        !          3753:                                                        state = 3;
        !          3754:                                                        break;
        !          3755:                                                }
        !          3756:                                                /* break is missing intentionally */
        !          3757: 
        !          3758:                                        case 3:
        !          3759:                                                if (crlf_state == -1) {
        !          3760:                                                        fld_val = token;
        !          3761: 
        !          3762:                                                        if (fld_name.c != NULL && fld_val.c != NULL) {
        !          3763:                                                                char *dummy;
        !          3764: 
        !          3765:                                                                /* FIXME: some locale free implementation is
        !          3766:                                                                 * really required here,,, */
        !          3767:                                                                SEPARATE_SMART_STR(&fld_name);
        !          3768:                                                                php_strtoupper(fld_name.c, fld_name.len);
        !          3769: 
        !          3770:                                                                zend_hash_update(ht, (char *)fld_name.c, fld_name.len, &fld_val, sizeof(smart_str), (void **)&dummy);
        !          3771: 
        !          3772:                                                                my_smart_str_dtor(&fld_name);
        !          3773:                                                        }
        !          3774: 
        !          3775:                                                        memset(&fld_name, 0, sizeof(smart_str));
        !          3776:                                                        memset(&fld_val, 0, sizeof(smart_str));
        !          3777: 
        !          3778:                                                        token.c = (char *)ps;
        !          3779:                                                        token.len = 0;
        !          3780:                                                        token.a = 0;
        !          3781: 
        !          3782:                                                        state = 1;
        !          3783:                                                }
        !          3784:                                                break;
        !          3785: 
        !          3786:                                        case 4:
        !          3787:                                                APPEND_ONE_CHAR(' ');
        !          3788:                                                state = 3;
        !          3789:                                                break;
        !          3790:                                }
        !          3791: 
        !          3792:                                if (crlf_state == 1) {
        !          3793:                                        APPEND_ONE_CHAR('\r');
        !          3794:                                }
        !          3795: 
        !          3796:                                APPEND_ONE_CHAR(*ps);
        !          3797: 
        !          3798:                                crlf_state = 0;
        !          3799:                                break;
        !          3800:                }
        !          3801:                ps++, icnt--;
        !          3802:        }
        !          3803: out:
        !          3804:        if (state == 2) {
        !          3805:                token.c = "";
        !          3806:                token.len = 0;
        !          3807:                token.a = 0;
        !          3808: 
        !          3809:                state = 3;
        !          3810:        }
        !          3811:        if (state == 3) {
        !          3812:                fld_val = token;
        !          3813: 
        !          3814:                if (fld_name.c != NULL && fld_val.c != NULL) {
        !          3815:                        void *dummy;
        !          3816: 
        !          3817:                        /* FIXME: some locale free implementation is
        !          3818:                         * really required here,,, */
        !          3819:                        SEPARATE_SMART_STR(&fld_name);
        !          3820:                        php_strtoupper(fld_name.c, fld_name.len);
        !          3821: 
        !          3822:                        zend_hash_update(ht, (char *)fld_name.c, fld_name.len, &fld_val, sizeof(smart_str), (void **)&dummy);
        !          3823: 
        !          3824:                        my_smart_str_dtor(&fld_name);
        !          3825:                }
        !          3826:        }
        !          3827:        return state;
        !          3828: }
        !          3829: 
        !          3830: PHP_FUNCTION(mb_send_mail)
        !          3831: {
        !          3832:        int n;
        !          3833:        char *to = NULL;
        !          3834:        int to_len;
        !          3835:        char *message = NULL;
        !          3836:        int message_len;
        !          3837:        char *headers = NULL;
        !          3838:        int headers_len;
        !          3839:        char *subject = NULL;
        !          3840:        int subject_len;
        !          3841:        char *extra_cmd = NULL;
        !          3842:        int extra_cmd_len;
        !          3843:        int i;
        !          3844:        char *to_r = NULL;
        !          3845:        char *force_extra_parameters = INI_STR("mail.force_extra_parameters");
        !          3846:        struct {
        !          3847:                int cnt_type:1;
        !          3848:                int cnt_trans_enc:1;
        !          3849:        } suppressed_hdrs = { 0, 0 };
        !          3850: 
        !          3851:        char *message_buf = NULL, *subject_buf = NULL, *p;
        !          3852:        mbfl_string orig_str, conv_str;
        !          3853:        mbfl_string *pstr;      /* pointer to mbfl string for return value */
        !          3854:        enum mbfl_no_encoding
        !          3855:            tran_cs,    /* transfar text charset */
        !          3856:            head_enc,   /* header transfar encoding */
        !          3857:            body_enc;   /* body transfar encoding */
        !          3858:        mbfl_memory_device device;      /* automatic allocateable buffer for additional header */
        !          3859:        const mbfl_language *lang;
        !          3860:        int err = 0;
        !          3861:        HashTable ht_headers;
        !          3862:        smart_str *s;
        !          3863:        extern void mbfl_memory_device_unput(mbfl_memory_device *device);
        !          3864:        char *pp, *ee;
        !          3865:     
        !          3866:        if (PG(safe_mode) && (ZEND_NUM_ARGS() == 5)) {
        !          3867:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "SAFE MODE Restriction in effect.  The fifth parameter is disabled in SAFE MODE.");
        !          3868:                RETURN_FALSE;
        !          3869:        }
        !          3870:     
        !          3871:        /* initialize */
        !          3872:        mbfl_memory_device_init(&device, 0, 0);
        !          3873:        mbfl_string_init(&orig_str);
        !          3874:        mbfl_string_init(&conv_str);
        !          3875: 
        !          3876:        /* character-set, transfer-encoding */
        !          3877:        tran_cs = mbfl_no_encoding_utf8;
        !          3878:        head_enc = mbfl_no_encoding_base64;
        !          3879:        body_enc = mbfl_no_encoding_base64;
        !          3880:        lang = mbfl_no2language(MBSTRG(language));
        !          3881:        if (lang != NULL) {
        !          3882:                tran_cs = lang->mail_charset;
        !          3883:                head_enc = lang->mail_header_encoding;
        !          3884:                body_enc = lang->mail_body_encoding;
        !          3885:        }
        !          3886: 
        !          3887:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ss", &to, &to_len, &subject, &subject_len, &message, &message_len, &headers, &headers_len, &extra_cmd, &extra_cmd_len) == FAILURE) {
        !          3888:                return;
        !          3889:        }
        !          3890: 
        !          3891:        /* ASCIIZ check */
        !          3892:        MAIL_ASCIIZ_CHECK_MBSTRING(to, to_len);
        !          3893:        MAIL_ASCIIZ_CHECK_MBSTRING(subject, subject_len);
        !          3894:        MAIL_ASCIIZ_CHECK_MBSTRING(message, message_len);
        !          3895:        if (headers) {
        !          3896:                MAIL_ASCIIZ_CHECK_MBSTRING(headers, headers_len);
        !          3897:        }
        !          3898:        if (extra_cmd) {
        !          3899:                MAIL_ASCIIZ_CHECK_MBSTRING(extra_cmd, extra_cmd_len);
        !          3900:        }
        !          3901: 
        !          3902:        zend_hash_init(&ht_headers, 0, NULL, (dtor_func_t) my_smart_str_dtor, 0);
        !          3903: 
        !          3904:        if (headers != NULL) {
        !          3905:                _php_mbstr_parse_mail_headers(&ht_headers, headers, headers_len);
        !          3906:        }
        !          3907: 
        !          3908:        if (zend_hash_find(&ht_headers, "CONTENT-TYPE", sizeof("CONTENT-TYPE") - 1, (void **)&s) == SUCCESS) {
        !          3909:                char *tmp;
        !          3910:                char *param_name;
        !          3911:                char *charset = NULL;
        !          3912: 
        !          3913:                SEPARATE_SMART_STR(s);
        !          3914:                smart_str_0(s);
        !          3915: 
        !          3916:                p = strchr(s->c, ';');
        !          3917: 
        !          3918:                if (p != NULL) {
        !          3919:                        /* skipping the padded spaces */
        !          3920:                        do {
        !          3921:                                ++p;
        !          3922:                        } while (*p == ' ' || *p == '\t');
        !          3923: 
        !          3924:                        if (*p != '\0') {
        !          3925:                                if ((param_name = php_strtok_r(p, "= ", &tmp)) != NULL) {
        !          3926:                                        if (strcasecmp(param_name, "charset") == 0) {
        !          3927:                                                enum mbfl_no_encoding _tran_cs = tran_cs;
        !          3928:                                                
        !          3929:                                                charset = php_strtok_r(NULL, "= \"", &tmp);
        !          3930:                                                if (charset != NULL) {
        !          3931:                                                        _tran_cs = mbfl_name2no_encoding(charset);
        !          3932:                                                }
        !          3933: 
        !          3934:                                                if (_tran_cs == mbfl_no_encoding_invalid) {
        !          3935:                                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported charset \"%s\" - will be regarded as ascii", charset); 
        !          3936:                                                        _tran_cs = mbfl_no_encoding_ascii;
        !          3937:                                                }
        !          3938:                                                tran_cs = _tran_cs;
        !          3939:                                        }
        !          3940:                                }
        !          3941:                        }
        !          3942:                }
        !          3943:                suppressed_hdrs.cnt_type = 1;
        !          3944:        }
        !          3945: 
        !          3946:        if (zend_hash_find(&ht_headers, "CONTENT-TRANSFER-ENCODING", sizeof("CONTENT-TRANSFER-ENCODING") - 1, (void **)&s) == SUCCESS) {
        !          3947:                enum mbfl_no_encoding _body_enc;
        !          3948:                SEPARATE_SMART_STR(s);
        !          3949:                smart_str_0(s);
        !          3950: 
        !          3951:                _body_enc = mbfl_name2no_encoding(s->c);
        !          3952:                switch (_body_enc) {
        !          3953:                        case mbfl_no_encoding_base64:
        !          3954:                        case mbfl_no_encoding_7bit:
        !          3955:                        case mbfl_no_encoding_8bit:
        !          3956:                                body_enc = _body_enc;
        !          3957:                                break;
        !          3958: 
        !          3959:                        default:
        !          3960:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported transfer encoding \"%s\" - will be regarded as 8bit", s->c); 
        !          3961:                                body_enc =      mbfl_no_encoding_8bit;
        !          3962:                                break;
        !          3963:                }
        !          3964:                suppressed_hdrs.cnt_trans_enc = 1;
        !          3965:        }
        !          3966: 
        !          3967:        /* To: */
        !          3968:        if (to != NULL) {
        !          3969:         if (to_len > 0) {
        !          3970:             to_r = estrndup(to, to_len);
        !          3971:             for (; to_len; to_len--) {
        !          3972:                 if (!isspace((unsigned char) to_r[to_len - 1])) {
        !          3973:                     break;
        !          3974:                 }
        !          3975:                 to_r[to_len - 1] = '\0';
        !          3976:             }
        !          3977:             for (i = 0; to_r[i]; i++) {
        !          3978:                        if (iscntrl((unsigned char) to_r[i])) {
        !          3979:                                /* According to RFC 822, section 3.1.1 long headers may be separated into
        !          3980:                                 * parts using CRLF followed at least one linear-white-space character ('\t' or ' ').
        !          3981:                                 * To prevent these separators from being replaced with a space, we use the
        !          3982:                                 * SKIP_LONG_HEADER_SEP_MBSTRING to skip over them.
        !          3983:                                 */
        !          3984:                                SKIP_LONG_HEADER_SEP_MBSTRING(to_r, i);
        !          3985:                                to_r[i] = ' ';
        !          3986:                        }
        !          3987:             }
        !          3988:         } else {
        !          3989:             to_r = to;
        !          3990:         }
        !          3991:     } else {
        !          3992:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing To: field");
        !          3993:                err = 1;
        !          3994:        }
        !          3995: 
        !          3996:        /* Subject: */
        !          3997:        if (subject != NULL && subject_len >= 0) {
        !          3998:                orig_str.no_language = MBSTRG(language);
        !          3999:                orig_str.val = (unsigned char *)subject;
        !          4000:                orig_str.len = subject_len;
        !          4001:                orig_str.no_encoding = MBSTRG(current_internal_encoding);
        !          4002:                if (orig_str.no_encoding == mbfl_no_encoding_invalid
        !          4003:                    || orig_str.no_encoding == mbfl_no_encoding_pass) {
        !          4004:                        orig_str.no_encoding = mbfl_identify_encoding_no(&orig_str, MBSTRG(current_detect_order_list), MBSTRG(current_detect_order_list_size), MBSTRG(strict_detection));
        !          4005:                }
        !          4006:                pstr = mbfl_mime_header_encode(&orig_str, &conv_str, tran_cs, head_enc, "\n", sizeof("Subject: [PHP-jp nnnnnnnn]"));
        !          4007:                if (pstr != NULL) {
        !          4008:                        subject_buf = subject = (char *)pstr->val;
        !          4009:                }
        !          4010:        } else {
        !          4011:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing Subject: field");
        !          4012:                err = 1;
        !          4013:        }
        !          4014: 
        !          4015:        /* message body */
        !          4016:        if (message != NULL) {
        !          4017:                orig_str.no_language = MBSTRG(language);
        !          4018:                orig_str.val = (unsigned char *)message;
        !          4019:                orig_str.len = (unsigned int)message_len;
        !          4020:                orig_str.no_encoding = MBSTRG(current_internal_encoding);
        !          4021: 
        !          4022:                if (orig_str.no_encoding == mbfl_no_encoding_invalid
        !          4023:                    || orig_str.no_encoding == mbfl_no_encoding_pass) {
        !          4024:                        orig_str.no_encoding = mbfl_identify_encoding_no(&orig_str, MBSTRG(current_detect_order_list), MBSTRG(current_detect_order_list_size), MBSTRG(strict_detection));
        !          4025:                }
        !          4026: 
        !          4027:                pstr = NULL;
        !          4028:                {
        !          4029:                        mbfl_string tmpstr;
        !          4030: 
        !          4031:                        if (mbfl_convert_encoding(&orig_str, &tmpstr, tran_cs) != NULL) {
        !          4032:                                tmpstr.no_encoding=mbfl_no_encoding_8bit;
        !          4033:                                pstr = mbfl_convert_encoding(&tmpstr, &conv_str, body_enc);
        !          4034:                                efree(tmpstr.val);
        !          4035:                        }
        !          4036:                }
        !          4037:                if (pstr != NULL) {
        !          4038:                        message_buf = message = (char *)pstr->val;
        !          4039:                }
        !          4040:        } else {
        !          4041:                /* this is not really an error, so it is allowed. */
        !          4042:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty message body");
        !          4043:                message = NULL;
        !          4044:        }
        !          4045: 
        !          4046:        /* other headers */
        !          4047: #define PHP_MBSTR_MAIL_MIME_HEADER1 "MIME-Version: 1.0"
        !          4048: #define PHP_MBSTR_MAIL_MIME_HEADER2 "Content-Type: text/plain"
        !          4049: #define PHP_MBSTR_MAIL_MIME_HEADER3 "; charset="
        !          4050: #define PHP_MBSTR_MAIL_MIME_HEADER4 "Content-Transfer-Encoding: "
        !          4051:        if (headers != NULL) {
        !          4052:                p = headers;
        !          4053:                n = headers_len;
        !          4054:                mbfl_memory_device_strncat(&device, p, n);
        !          4055:                if (n > 0 && p[n - 1] != '\n') {
        !          4056:                        mbfl_memory_device_strncat(&device, "\n", 1);
        !          4057:                }
        !          4058:        }
        !          4059: 
        !          4060:        if (!zend_hash_exists(&ht_headers, "MIME-VERSION", sizeof("MIME-VERSION") - 1)) {
        !          4061:                mbfl_memory_device_strncat(&device, PHP_MBSTR_MAIL_MIME_HEADER1, sizeof(PHP_MBSTR_MAIL_MIME_HEADER1) - 1);
        !          4062:                mbfl_memory_device_strncat(&device, "\n", 1);
        !          4063:        }
        !          4064: 
        !          4065:        if (!suppressed_hdrs.cnt_type) {
        !          4066:                mbfl_memory_device_strncat(&device, PHP_MBSTR_MAIL_MIME_HEADER2, sizeof(PHP_MBSTR_MAIL_MIME_HEADER2) - 1);
        !          4067: 
        !          4068:                p = (char *)mbfl_no2preferred_mime_name(tran_cs);
        !          4069:                if (p != NULL) {
        !          4070:                        mbfl_memory_device_strncat(&device, PHP_MBSTR_MAIL_MIME_HEADER3, sizeof(PHP_MBSTR_MAIL_MIME_HEADER3) - 1);
        !          4071:                        mbfl_memory_device_strcat(&device, p);
        !          4072:                }
        !          4073:                mbfl_memory_device_strncat(&device, "\n", 1);
        !          4074:        }
        !          4075:        if (!suppressed_hdrs.cnt_trans_enc) {
        !          4076:                mbfl_memory_device_strncat(&device, PHP_MBSTR_MAIL_MIME_HEADER4, sizeof(PHP_MBSTR_MAIL_MIME_HEADER4) - 1);
        !          4077:                p = (char *)mbfl_no2preferred_mime_name(body_enc);
        !          4078:                if (p == NULL) {
        !          4079:                        p = "7bit";
        !          4080:                }
        !          4081:                mbfl_memory_device_strcat(&device, p);
        !          4082:                mbfl_memory_device_strncat(&device, "\n", 1);
        !          4083:        }
        !          4084: 
        !          4085:        mbfl_memory_device_unput(&device);
        !          4086:        mbfl_memory_device_output('\0', &device);
        !          4087:        headers = (char *)device.buffer;
        !          4088: 
        !          4089:        if (force_extra_parameters) {
        !          4090:                extra_cmd = php_escape_shell_cmd(force_extra_parameters);
        !          4091:        } else if (extra_cmd) {
        !          4092:                extra_cmd = php_escape_shell_cmd(extra_cmd);
        !          4093:        } 
        !          4094: 
        !          4095:        if (!err && php_mail(to_r, subject, message, headers, extra_cmd TSRMLS_CC)) {
        !          4096:                RETVAL_TRUE;
        !          4097:        } else {
        !          4098:                RETVAL_FALSE;
        !          4099:        }
        !          4100: 
        !          4101:        if (extra_cmd) {
        !          4102:                efree(extra_cmd);
        !          4103:        }
        !          4104:        if (to_r != to) {
        !          4105:                efree(to_r);
        !          4106:        }
        !          4107:        if (subject_buf) {
        !          4108:                efree((void *)subject_buf);
        !          4109:        }
        !          4110:        if (message_buf) {
        !          4111:                efree((void *)message_buf);
        !          4112:        }
        !          4113:        mbfl_memory_device_clear(&device);
        !          4114:        zend_hash_destroy(&ht_headers);
        !          4115: }
        !          4116: 
        !          4117: #undef SKIP_LONG_HEADER_SEP_MBSTRING
        !          4118: #undef MAIL_ASCIIZ_CHECK_MBSTRING
        !          4119: #undef APPEND_ONE_CHAR
        !          4120: #undef SEPARATE_SMART_STR
        !          4121: #undef PHP_MBSTR_MAIL_MIME_HEADER1
        !          4122: #undef PHP_MBSTR_MAIL_MIME_HEADER2
        !          4123: #undef PHP_MBSTR_MAIL_MIME_HEADER3
        !          4124: #undef PHP_MBSTR_MAIL_MIME_HEADER4
        !          4125: /* }}} */
        !          4126: 
        !          4127: /* {{{ proto mixed mb_get_info([string type])
        !          4128:    Returns the current settings of mbstring */
        !          4129: PHP_FUNCTION(mb_get_info)
        !          4130: {
        !          4131:        char *typ = NULL;
        !          4132:        int typ_len, n;
        !          4133:        char *name;
        !          4134:        const struct mb_overload_def *over_func;
        !          4135:        zval *row1, *row2;
        !          4136:        const mbfl_language *lang = mbfl_no2language(MBSTRG(language));
        !          4137:        enum mbfl_no_encoding *entry;
        !          4138: #ifdef ZEND_MULTIBYTE
        !          4139:        zval *row3;
        !          4140: #endif /* ZEND_MULTIBYTE */
        !          4141: 
        !          4142:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &typ, &typ_len) == FAILURE) {
        !          4143:                RETURN_FALSE;
        !          4144:        }
        !          4145: 
        !          4146:        if (!typ || !strcasecmp("all", typ)) {
        !          4147:                array_init(return_value);
        !          4148:                if ((name = (char *)mbfl_no_encoding2name(MBSTRG(current_internal_encoding))) != NULL) {
        !          4149:                        add_assoc_string(return_value, "internal_encoding", name, 1);
        !          4150:                }
        !          4151:                if ((name = (char *)mbfl_no_encoding2name(MBSTRG(http_input_identify))) != NULL) {
        !          4152:                        add_assoc_string(return_value, "http_input", name, 1);
        !          4153:                }
        !          4154:                if ((name = (char *)mbfl_no_encoding2name(MBSTRG(current_http_output_encoding))) != NULL) {
        !          4155:                        add_assoc_string(return_value, "http_output", name, 1);
        !          4156:                }
        !          4157:                if ((name = (char *)zend_ini_string("mbstring.http_output_conv_mimetypes", sizeof("mbstring.http_output_conv_mimetypes"), 0)) != NULL) {
        !          4158:                        add_assoc_string(return_value, "http_output_conv_mimetypes", name, 1);
        !          4159:                }
        !          4160:                add_assoc_long(return_value, "func_overload", MBSTRG(func_overload));
        !          4161:                if (MBSTRG(func_overload)){
        !          4162:                        over_func = &(mb_ovld[0]);
        !          4163:                        MAKE_STD_ZVAL(row1);
        !          4164:                        array_init(row1);
        !          4165:                        while (over_func->type > 0) {
        !          4166:                                if ((MBSTRG(func_overload) & over_func->type) == over_func->type ) {
        !          4167:                                        add_assoc_string(row1, over_func->orig_func, over_func->ovld_func, 1);
        !          4168:                                }
        !          4169:                                over_func++;
        !          4170:                        }
        !          4171:                        add_assoc_zval(return_value, "func_overload_list", row1);
        !          4172:                } else {
        !          4173:                        add_assoc_string(return_value, "func_overload_list", "no overload", 1);
        !          4174:                }
        !          4175:                if (lang != NULL) {
        !          4176:                        if ((name = (char *)mbfl_no_encoding2name(lang->mail_charset)) != NULL) {
        !          4177:                                add_assoc_string(return_value, "mail_charset", name, 1);
        !          4178:                        }
        !          4179:                        if ((name = (char *)mbfl_no_encoding2name(lang->mail_header_encoding)) != NULL) {
        !          4180:                                add_assoc_string(return_value, "mail_header_encoding", name, 1);
        !          4181:                        }
        !          4182:                        if ((name = (char *)mbfl_no_encoding2name(lang->mail_body_encoding)) != NULL) {
        !          4183:                                add_assoc_string(return_value, "mail_body_encoding", name, 1);
        !          4184:                        }
        !          4185:                }
        !          4186:                add_assoc_long(return_value, "illegal_chars", MBSTRG(illegalchars));
        !          4187:                if (MBSTRG(encoding_translation)) {
        !          4188:                        add_assoc_string(return_value, "encoding_translation", "On", 1);
        !          4189:                } else {
        !          4190:                        add_assoc_string(return_value, "encoding_translation", "Off", 1);
        !          4191:                }
        !          4192:                if ((name = (char *)mbfl_no_language2name(MBSTRG(language))) != NULL) {
        !          4193:                        add_assoc_string(return_value, "language", name, 1);
        !          4194:                }               
        !          4195:                n = MBSTRG(current_detect_order_list_size);
        !          4196:                entry = MBSTRG(current_detect_order_list);
        !          4197:                if(n > 0) {
        !          4198:                        MAKE_STD_ZVAL(row2);
        !          4199:                        array_init(row2);
        !          4200:                        while (n > 0) {
        !          4201:                                if ((name = (char *)mbfl_no_encoding2name(*entry)) != NULL) {
        !          4202:                                        add_next_index_string(row2, name, 1);
        !          4203:                                }
        !          4204:                                entry++;
        !          4205:                                n--;
        !          4206:                        }
        !          4207:                        add_assoc_zval(return_value, "detect_order", row2);
        !          4208:                }
        !          4209:                if (MBSTRG(current_filter_illegal_mode) == MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
        !          4210:                        add_assoc_string(return_value, "substitute_character", "none", 1);
        !          4211:                } else if (MBSTRG(current_filter_illegal_mode) == MBFL_OUTPUTFILTER_ILLEGAL_MODE_LONG) {
        !          4212:                        add_assoc_string(return_value, "substitute_character", "long", 1);
        !          4213:                } else if (MBSTRG(current_filter_illegal_mode) == MBFL_OUTPUTFILTER_ILLEGAL_MODE_ENTITY) {
        !          4214:                        add_assoc_string(return_value, "substitute_character", "entity", 1);
        !          4215:                } else {
        !          4216:                        add_assoc_long(return_value, "substitute_character", MBSTRG(current_filter_illegal_substchar));
        !          4217:                }
        !          4218:                if (MBSTRG(strict_detection)) {
        !          4219:                        add_assoc_string(return_value, "strict_detection", "On", 1);
        !          4220:                } else {
        !          4221:                        add_assoc_string(return_value, "strict_detection", "Off", 1);
        !          4222:                }
        !          4223: #ifdef ZEND_MULTIBYTE
        !          4224:                entry = MBSTRG(script_encoding_list);
        !          4225:                n = MBSTRG(script_encoding_list_size);
        !          4226:                if(n > 0) {
        !          4227:                        MAKE_STD_ZVAL(row3);
        !          4228:                        array_init(row3);
        !          4229:                        while (n > 0) {
        !          4230:                                if ((name = (char *)mbfl_no_encoding2name(*entry)) != NULL) {
        !          4231:                                        add_next_index_string(row3, name, 1);
        !          4232:                                }
        !          4233:                                entry++;
        !          4234:                                n--;
        !          4235:                        }
        !          4236:                        add_assoc_zval(return_value, "script_encoding", row3);
        !          4237:                }
        !          4238: #endif /* ZEND_MULTIBYTE */
        !          4239:        } else if (!strcasecmp("internal_encoding", typ)) {
        !          4240:                if ((name = (char *)mbfl_no_encoding2name(MBSTRG(current_internal_encoding))) != NULL) {
        !          4241:                        RETVAL_STRING(name, 1);
        !          4242:                }               
        !          4243:        } else if (!strcasecmp("http_input", typ)) {
        !          4244:                if ((name = (char *)mbfl_no_encoding2name(MBSTRG(http_input_identify))) != NULL) {
        !          4245:                        RETVAL_STRING(name, 1);
        !          4246:                }               
        !          4247:        } else if (!strcasecmp("http_output", typ)) {
        !          4248:                if ((name = (char *)mbfl_no_encoding2name(MBSTRG(current_http_output_encoding))) != NULL) {
        !          4249:                        RETVAL_STRING(name, 1);
        !          4250:                }               
        !          4251:        } else if (!strcasecmp("http_output_conv_mimetypes", typ)) {
        !          4252:                if ((name = (char *)zend_ini_string("mbstring.http_output_conv_mimetypes", sizeof("mbstring.http_output_conv_mimetypes"), 0)) != NULL) {
        !          4253:                        RETVAL_STRING(name, 1);
        !          4254:                }
        !          4255:        } else if (!strcasecmp("func_overload", typ)) {
        !          4256:                RETVAL_LONG(MBSTRG(func_overload));
        !          4257:        } else if (!strcasecmp("func_overload_list", typ)) {
        !          4258:                if (MBSTRG(func_overload)){
        !          4259:                                over_func = &(mb_ovld[0]);
        !          4260:                                array_init(return_value);
        !          4261:                                while (over_func->type > 0) {
        !          4262:                                        if ((MBSTRG(func_overload) & over_func->type) == over_func->type ) {
        !          4263:                                                add_assoc_string(return_value, over_func->orig_func, over_func->ovld_func, 1);
        !          4264:                                        }
        !          4265:                                        over_func++;
        !          4266:                                }
        !          4267:                } else {
        !          4268:                        RETVAL_STRING("no overload", 1);
        !          4269:                }
        !          4270:        } else if (!strcasecmp("mail_charset", typ)) {
        !          4271:                if (lang != NULL && (name = (char *)mbfl_no_encoding2name(lang->mail_charset)) != NULL) {
        !          4272:                        RETVAL_STRING(name, 1);
        !          4273:                }
        !          4274:        } else if (!strcasecmp("mail_header_encoding", typ)) {
        !          4275:                if (lang != NULL && (name = (char *)mbfl_no_encoding2name(lang->mail_header_encoding)) != NULL) {
        !          4276:                        RETVAL_STRING(name, 1);
        !          4277:                }
        !          4278:        } else if (!strcasecmp("mail_body_encoding", typ)) {
        !          4279:                if (lang != NULL && (name = (char *)mbfl_no_encoding2name(lang->mail_body_encoding)) != NULL) {
        !          4280:                        RETVAL_STRING(name, 1);
        !          4281:                }
        !          4282:        } else if (!strcasecmp("illegal_chars", typ)) {
        !          4283:                RETVAL_LONG(MBSTRG(illegalchars));
        !          4284:        } else if (!strcasecmp("encoding_translation", typ)) {
        !          4285:                if (MBSTRG(encoding_translation)) {
        !          4286:                        RETVAL_STRING("On", 1);
        !          4287:                } else {
        !          4288:                        RETVAL_STRING("Off", 1);
        !          4289:                }
        !          4290:        } else if (!strcasecmp("language", typ)) {
        !          4291:                if ((name = (char *)mbfl_no_language2name(MBSTRG(language))) != NULL) {
        !          4292:                        RETVAL_STRING(name, 1);
        !          4293:                }               
        !          4294:        } else if (!strcasecmp("detect_order", typ)) {
        !          4295:                n = MBSTRG(current_detect_order_list_size);
        !          4296:                entry = MBSTRG(current_detect_order_list);
        !          4297:                if(n > 0) {
        !          4298:                        array_init(return_value);
        !          4299:                        while (n > 0) {
        !          4300:                                name = (char *)mbfl_no_encoding2name(*entry);
        !          4301:                                if (name) {
        !          4302:                                        add_next_index_string(return_value, name, 1);
        !          4303:                                }
        !          4304:                                entry++;
        !          4305:                                n--;
        !          4306:                        }
        !          4307:                }
        !          4308:        } else if (!strcasecmp("substitute_character", typ)) {
        !          4309:                if (MBSTRG(current_filter_illegal_mode) == MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE) {
        !          4310:                        RETVAL_STRING("none", 1);
        !          4311:                } else if (MBSTRG(current_filter_illegal_mode) == MBFL_OUTPUTFILTER_ILLEGAL_MODE_LONG) {
        !          4312:                        RETVAL_STRING("long", 1);
        !          4313:                } else if (MBSTRG(current_filter_illegal_mode) == MBFL_OUTPUTFILTER_ILLEGAL_MODE_ENTITY) {
        !          4314:                        RETVAL_STRING("entity", 1);
        !          4315:                } else {
        !          4316:                        RETVAL_LONG(MBSTRG(current_filter_illegal_substchar));
        !          4317:                }
        !          4318:        } else if (!strcasecmp("strict_detection", typ)) {
        !          4319:                if (MBSTRG(strict_detection)) {
        !          4320:                        RETVAL_STRING("On", 1);
        !          4321:                } else {
        !          4322:                        RETVAL_STRING("Off", 1);
        !          4323:                }
        !          4324:        } else {
        !          4325: #ifdef ZEND_MULTIBYTE
        !          4326:        if (!strcasecmp("script_encoding", typ)) {
        !          4327:                entry = MBSTRG(script_encoding_list);
        !          4328:                n = MBSTRG(script_encoding_list_size);
        !          4329:                if(n > 0) {
        !          4330:                        array_init(return_value);
        !          4331:                        while (n > 0) {
        !          4332:                                name = (char *)mbfl_no_encoding2name(*entry);
        !          4333:                                if (name) {
        !          4334:                                        add_next_index_string(return_value, name, 1);
        !          4335:                                }
        !          4336:                                entry++;
        !          4337:                                n--;
        !          4338:                        }
        !          4339:                }
        !          4340:                return;
        !          4341:        }
        !          4342: #endif /* ZEND_MULTIBYTE */
        !          4343:                RETURN_FALSE;
        !          4344:        }
        !          4345: }
        !          4346: /* }}} */
        !          4347: 
        !          4348: /* {{{ proto bool mb_check_encoding([string var[, string encoding]])
        !          4349:    Check if the string is valid for the specified encoding */
        !          4350: PHP_FUNCTION(mb_check_encoding)
        !          4351: {
        !          4352:        char *var = NULL;
        !          4353:        int var_len;
        !          4354:        char *enc = NULL;
        !          4355:        int enc_len;
        !          4356:        mbfl_buffer_converter *convd;
        !          4357:        enum mbfl_no_encoding no_encoding = MBSTRG(current_internal_encoding);
        !          4358:        mbfl_string string, result, *ret = NULL;
        !          4359:        long illegalchars = 0;
        !          4360: 
        !          4361:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &var, &var_len, &enc, &enc_len) == FAILURE) {
        !          4362:                RETURN_FALSE;
        !          4363:        }
        !          4364: 
        !          4365:        if (var == NULL) {
        !          4366:                RETURN_BOOL(MBSTRG(illegalchars) == 0);
        !          4367:        }
        !          4368: 
        !          4369:        if (enc != NULL) {
        !          4370:                no_encoding = mbfl_name2no_encoding(enc);
        !          4371:                if (no_encoding == mbfl_no_encoding_invalid || no_encoding == mbfl_no_encoding_pass) {
        !          4372:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid encoding \"%s\"", enc);
        !          4373:                        RETURN_FALSE;
        !          4374:                }
        !          4375:        }
        !          4376:        
        !          4377:        convd = mbfl_buffer_converter_new(no_encoding, no_encoding, 0);
        !          4378:        if (convd == NULL) {
        !          4379:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create converter");
        !          4380:                RETURN_FALSE;
        !          4381:        }       
        !          4382:        mbfl_buffer_converter_illegal_mode(convd, MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE);
        !          4383:        mbfl_buffer_converter_illegal_substchar(convd, 0);      
        !          4384:        
        !          4385:        /* initialize string */
        !          4386:        mbfl_string_init_set(&string, mbfl_no_language_neutral, no_encoding);
        !          4387:        mbfl_string_init(&result);
        !          4388: 
        !          4389:        string.val = (unsigned char *)var;
        !          4390:        string.len = var_len;
        !          4391:        ret = mbfl_buffer_converter_feed_result(convd, &string, &result);
        !          4392:        illegalchars = mbfl_buffer_illegalchars(convd);
        !          4393:        mbfl_buffer_converter_delete(convd);
        !          4394: 
        !          4395:        RETVAL_FALSE;
        !          4396:        if (ret != NULL) {
        !          4397:                if (illegalchars == 0 && string.len == result.len && memcmp(string.val, result.val, string.len) == 0) {
        !          4398:                        RETVAL_TRUE;
        !          4399:                }
        !          4400:                mbfl_string_clear(&result);
        !          4401:        }
        !          4402: }
        !          4403: /* }}} */
        !          4404: 
        !          4405: /* {{{ MBSTRING_API int php_mb_encoding_translation() */
        !          4406: MBSTRING_API int php_mb_encoding_translation(TSRMLS_D) 
        !          4407: {
        !          4408:        return MBSTRG(encoding_translation);
        !          4409: }
        !          4410: /* }}} */
        !          4411: 
        !          4412: /* {{{ MBSTRING_API size_t php_mb_mbchar_bytes_ex() */
        !          4413: MBSTRING_API size_t php_mb_mbchar_bytes_ex(const char *s, const mbfl_encoding *enc)
        !          4414: {
        !          4415:        if (enc != NULL) {
        !          4416:                if (enc->flag & MBFL_ENCTYPE_MBCS) {
        !          4417:                        if (enc->mblen_table != NULL) {
        !          4418:                                if (s != NULL) return enc->mblen_table[*(unsigned char *)s];
        !          4419:                        }
        !          4420:                } else if (enc->flag & (MBFL_ENCTYPE_WCS2BE | MBFL_ENCTYPE_WCS2LE)) {
        !          4421:                        return 2;
        !          4422:                } else if (enc->flag & (MBFL_ENCTYPE_WCS4BE | MBFL_ENCTYPE_WCS4LE)) {
        !          4423:                        return 4;
        !          4424:                }
        !          4425:        }
        !          4426:        return 1;
        !          4427: }
        !          4428: /* }}} */
        !          4429: 
        !          4430: /* {{{ MBSTRING_API size_t php_mb_mbchar_bytes() */
        !          4431: MBSTRING_API size_t php_mb_mbchar_bytes(const char *s TSRMLS_DC)
        !          4432: {
        !          4433:        return php_mb_mbchar_bytes_ex(s,
        !          4434:                mbfl_no2encoding(MBSTRG(internal_encoding)));
        !          4435: }
        !          4436: /* }}} */
        !          4437: 
        !          4438: /* {{{ MBSTRING_API char *php_mb_safe_strrchr_ex() */
        !          4439: MBSTRING_API char *php_mb_safe_strrchr_ex(const char *s, unsigned int c, size_t nbytes, const mbfl_encoding *enc)
        !          4440: {
        !          4441:        register const char *p = s;
        !          4442:        char *last=NULL;
        !          4443: 
        !          4444:        if (nbytes == (size_t)-1) {
        !          4445:                size_t nb = 0;
        !          4446: 
        !          4447:                while (*p != '\0') {
        !          4448:                        if (nb == 0) {
        !          4449:                                if ((unsigned char)*p == (unsigned char)c) {
        !          4450:                                        last = (char *)p;
        !          4451:                                }
        !          4452:                                nb = php_mb_mbchar_bytes_ex(p, enc);
        !          4453:                                if (nb == 0) {
        !          4454:                                        return NULL; /* something is going wrong! */
        !          4455:                                }
        !          4456:                        }
        !          4457:                        --nb;
        !          4458:                        ++p;
        !          4459:                }
        !          4460:        } else {
        !          4461:                register size_t bcnt = nbytes;
        !          4462:                register size_t nbytes_char;
        !          4463:                while (bcnt > 0) {
        !          4464:                        if ((unsigned char)*p == (unsigned char)c) {
        !          4465:                                last = (char *)p;
        !          4466:                        }
        !          4467:                        nbytes_char = php_mb_mbchar_bytes_ex(p, enc);
        !          4468:                        if (bcnt < nbytes_char) {
        !          4469:                                return NULL;
        !          4470:                        }
        !          4471:                        p += nbytes_char;
        !          4472:                        bcnt -= nbytes_char;
        !          4473:                }
        !          4474:        }
        !          4475:        return last;
        !          4476: }
        !          4477: /* }}} */
        !          4478: 
        !          4479: /* {{{ MBSTRING_API char *php_mb_safe_strrchr() */
        !          4480: MBSTRING_API char *php_mb_safe_strrchr(const char *s, unsigned int c, size_t nbytes TSRMLS_DC)
        !          4481: {
        !          4482:        return php_mb_safe_strrchr_ex(s, c, nbytes,
        !          4483:                mbfl_no2encoding(MBSTRG(internal_encoding)));
        !          4484: }
        !          4485: /* }}} */
        !          4486: 
        !          4487: /* {{{ MBSTRING_API char *php_mb_strrchr() */
        !          4488: MBSTRING_API char *php_mb_strrchr(const char *s, char c TSRMLS_DC)
        !          4489: {
        !          4490:        return php_mb_safe_strrchr(s, c, -1 TSRMLS_CC);
        !          4491: }
        !          4492: /* }}} */
        !          4493: 
        !          4494: /* {{{ MBSTRING_API size_t php_mb_gpc_mbchar_bytes() */
        !          4495: MBSTRING_API size_t php_mb_gpc_mbchar_bytes(const char *s TSRMLS_DC)
        !          4496: {
        !          4497: 
        !          4498:        if (MBSTRG(http_input_identify) != mbfl_no_encoding_invalid){
        !          4499:                return php_mb_mbchar_bytes_ex(s,
        !          4500:                mbfl_no2encoding(MBSTRG(http_input_identify)));
        !          4501:        } else {
        !          4502:                return php_mb_mbchar_bytes_ex(s,
        !          4503:                mbfl_no2encoding(MBSTRG(internal_encoding)));
        !          4504:        }
        !          4505: }
        !          4506: /* }}} */
        !          4507: 
        !          4508: /*     {{{ MBSTRING_API int php_mb_gpc_encoding_converter() */
        !          4509: MBSTRING_API int php_mb_gpc_encoding_converter(char **str, int *len, int num, const char *encoding_to, const char *encoding_from TSRMLS_DC)
        !          4510: {
        !          4511:        int i;
        !          4512:        mbfl_string string, result, *ret = NULL;
        !          4513:        enum mbfl_no_encoding from_encoding, to_encoding;
        !          4514:        mbfl_buffer_converter *convd;
        !          4515: 
        !          4516:        if (encoding_to) {
        !          4517:                /* new encoding */
        !          4518:                to_encoding = mbfl_name2no_encoding(encoding_to);
        !          4519:                if (to_encoding == mbfl_no_encoding_invalid) {
        !          4520:                        return -1;
        !          4521:                }
        !          4522:        } else {
        !          4523:                to_encoding = MBSTRG(current_internal_encoding);
        !          4524:        }       
        !          4525:        if (encoding_from) {
        !          4526:                /* old encoding */
        !          4527:                from_encoding = mbfl_name2no_encoding(encoding_from);
        !          4528:                if (from_encoding == mbfl_no_encoding_invalid) {
        !          4529:                        return -1;
        !          4530:                }
        !          4531:        } else {
        !          4532:                from_encoding = MBSTRG(http_input_identify);
        !          4533:        }
        !          4534: 
        !          4535:        if (from_encoding == mbfl_no_encoding_pass) {
        !          4536:                return 0;
        !          4537:        }
        !          4538: 
        !          4539:        /* initialize string */
        !          4540:        mbfl_string_init(&string);
        !          4541:        mbfl_string_init(&result);
        !          4542:        string.no_encoding = from_encoding;
        !          4543:        string.no_language = MBSTRG(language);
        !          4544: 
        !          4545:        for (i=0; i<num; i++){
        !          4546:                string.val = (unsigned char *)str[i];
        !          4547:                string.len = len[i];
        !          4548: 
        !          4549:                /* initialize converter */
        !          4550:                convd = mbfl_buffer_converter_new(from_encoding, to_encoding, string.len);
        !          4551:                if (convd == NULL) {
        !          4552:                        return -1;
        !          4553:                }
        !          4554:                mbfl_buffer_converter_illegal_mode(convd, MBSTRG(current_filter_illegal_mode));
        !          4555:                mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar));
        !          4556:                
        !          4557:                /* do it */
        !          4558:                ret = mbfl_buffer_converter_feed_result(convd, &string, &result);
        !          4559:                if (ret != NULL) {
        !          4560:                        efree(str[i]);
        !          4561:                        str[i] = (char *)ret->val;
        !          4562:                        len[i] = (int)ret->len;
        !          4563:                }
        !          4564:                
        !          4565:                MBSTRG(illegalchars) += mbfl_buffer_illegalchars(convd);
        !          4566:                mbfl_buffer_converter_delete(convd);
        !          4567:        }
        !          4568: 
        !          4569:        return ret ? 0 : -1;
        !          4570: }
        !          4571: /* }}} */
        !          4572: 
        !          4573: /* {{{ MBSTRING_API int php_mb_gpc_encoding_detector()
        !          4574:  */
        !          4575: MBSTRING_API int php_mb_gpc_encoding_detector(char **arg_string, int *arg_length, int num, char *arg_list TSRMLS_DC)
        !          4576: {
        !          4577:        mbfl_string string;
        !          4578:        enum mbfl_no_encoding *elist;
        !          4579:        enum mbfl_no_encoding encoding = mbfl_no_encoding_invalid;
        !          4580:        mbfl_encoding_detector *identd = NULL; 
        !          4581: 
        !          4582:        int size;
        !          4583:        enum mbfl_no_encoding *list;
        !          4584: 
        !          4585:        if (MBSTRG(http_input_list_size) == 1 && 
        !          4586:                MBSTRG(http_input_list)[0] == mbfl_no_encoding_pass) {
        !          4587:                MBSTRG(http_input_identify) = mbfl_no_encoding_pass;
        !          4588:                return SUCCESS;
        !          4589:        }
        !          4590: 
        !          4591:        if (MBSTRG(http_input_list_size) == 1 && 
        !          4592:                MBSTRG(http_input_list)[0] != mbfl_no_encoding_auto &&
        !          4593:                mbfl_no_encoding2name(MBSTRG(http_input_list)[0]) != NULL) {
        !          4594:                MBSTRG(http_input_identify) = MBSTRG(http_input_list)[0];
        !          4595:                return SUCCESS;
        !          4596:        }
        !          4597: 
        !          4598:        if (arg_list && strlen(arg_list)>0) {
        !          4599:                /* make encoding list */
        !          4600:                list = NULL;
        !          4601:                size = 0;
        !          4602:                php_mb_parse_encoding_list(arg_list, strlen(arg_list), &list, &size, 0 TSRMLS_CC);
        !          4603:                
        !          4604:                if (size > 0 && list != NULL) {
        !          4605:                        elist = list;
        !          4606:                } else {
        !          4607:                        elist = MBSTRG(current_detect_order_list);
        !          4608:                        size = MBSTRG(current_detect_order_list_size);
        !          4609:                        if (size <= 0){
        !          4610:                                elist = MBSTRG(default_detect_order_list);
        !          4611:                                size = MBSTRG(default_detect_order_list_size);
        !          4612:                        }
        !          4613:                }
        !          4614:        } else {
        !          4615:                elist = MBSTRG(current_detect_order_list);
        !          4616:                size = MBSTRG(current_detect_order_list_size);
        !          4617:                if (size <= 0){
        !          4618:                        elist = MBSTRG(default_detect_order_list);
        !          4619:                        size = MBSTRG(default_detect_order_list_size);
        !          4620:                }
        !          4621:        }
        !          4622: 
        !          4623:        mbfl_string_init(&string);
        !          4624:        string.no_language = MBSTRG(language);
        !          4625: 
        !          4626:        identd = mbfl_encoding_detector_new(elist, size, MBSTRG(strict_detection));
        !          4627: 
        !          4628:        if (identd) {
        !          4629:                int n = 0;
        !          4630:                while(n < num){
        !          4631:                        string.val = (unsigned char *)arg_string[n];
        !          4632:                        string.len = arg_length[n];
        !          4633:                        if (mbfl_encoding_detector_feed(identd, &string)) {
        !          4634:                                break;
        !          4635:                        }
        !          4636:                        n++;
        !          4637:                }
        !          4638:                encoding = mbfl_encoding_detector_judge(identd);
        !          4639:                mbfl_encoding_detector_delete(identd);
        !          4640:        }
        !          4641: 
        !          4642:        if (encoding != mbfl_no_encoding_invalid) {
        !          4643:                MBSTRG(http_input_identify) = encoding;
        !          4644:                return SUCCESS;
        !          4645:        } else {
        !          4646:                return FAILURE;
        !          4647:        }
        !          4648: }
        !          4649: /* }}} */
        !          4650: 
        !          4651: /* {{{ MBSTRING_API int php_mb_stripos()
        !          4652:  */
        !          4653: MBSTRING_API int php_mb_stripos(int mode, const char *old_haystack, unsigned int old_haystack_len, const char *old_needle, unsigned int old_needle_len, long offset, const char *from_encoding TSRMLS_DC)
        !          4654: {
        !          4655:        int n;
        !          4656:        mbfl_string haystack, needle;
        !          4657:        n = -1;
        !          4658: 
        !          4659:        mbfl_string_init(&haystack);
        !          4660:        mbfl_string_init(&needle);
        !          4661:        haystack.no_language = MBSTRG(language);
        !          4662:        haystack.no_encoding = MBSTRG(current_internal_encoding);
        !          4663:        needle.no_language = MBSTRG(language);
        !          4664:        needle.no_encoding = MBSTRG(current_internal_encoding);
        !          4665: 
        !          4666:        do {
        !          4667:                size_t len = 0;
        !          4668:                haystack.val = (unsigned char *)php_unicode_convert_case(PHP_UNICODE_CASE_UPPER, (char *)old_haystack, old_haystack_len, &len, from_encoding TSRMLS_CC);
        !          4669:                haystack.len = len;
        !          4670: 
        !          4671:                if (!haystack.val) {
        !          4672:                        break;
        !          4673:                }
        !          4674: 
        !          4675:                if (haystack.len <= 0) {
        !          4676:                        break;
        !          4677:                }
        !          4678: 
        !          4679:                needle.val = (unsigned char *)php_unicode_convert_case(PHP_UNICODE_CASE_UPPER, (char *)old_needle, old_needle_len, &len, from_encoding TSRMLS_CC);
        !          4680:                needle.len = len;
        !          4681: 
        !          4682:                if (!needle.val) {
        !          4683:                        break;
        !          4684:                }
        !          4685: 
        !          4686:                if (needle.len <= 0) {
        !          4687:                        break;
        !          4688:                }
        !          4689: 
        !          4690:                haystack.no_encoding = needle.no_encoding = mbfl_name2no_encoding(from_encoding);
        !          4691:                if (haystack.no_encoding == mbfl_no_encoding_invalid) {
        !          4692:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", from_encoding);
        !          4693:                        break;
        !          4694:                }
        !          4695: 
        !          4696:                {
        !          4697:                        int haystack_char_len = mbfl_strlen(&haystack);
        !          4698:  
        !          4699:                        if (mode) {
        !          4700:                                if ((offset > 0 && offset > haystack_char_len) ||
        !          4701:                                        (offset < 0 && -offset > haystack_char_len)) {
        !          4702:                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset is greater than the length of haystack string");
        !          4703:                                        break;
        !          4704:                                }
        !          4705:                        } else {
        !          4706:                                if (offset < 0 || offset > haystack_char_len) {
        !          4707:                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset not contained in string");
        !          4708:                                        break;
        !          4709:                                }
        !          4710:                        }
        !          4711:                }
        !          4712: 
        !          4713:                n = mbfl_strpos(&haystack, &needle, offset, mode);
        !          4714:        } while(0);
        !          4715: 
        !          4716:        if (haystack.val) {
        !          4717:                efree(haystack.val);
        !          4718:        }
        !          4719: 
        !          4720:        if (needle.val) {
        !          4721:                efree(needle.val);
        !          4722:        }
        !          4723: 
        !          4724:        return n;
        !          4725: }
        !          4726: /* }}} */
        !          4727: 
        !          4728: #ifdef ZEND_MULTIBYTE
        !          4729: /* {{{ php_mb_set_zend_encoding() */
        !          4730: static int php_mb_set_zend_encoding(TSRMLS_D)
        !          4731: {
        !          4732:        /* 'd better use mbfl_memory_device? */
        !          4733:        char *name, *list = NULL;
        !          4734:        int n, *entry, list_size = 0;
        !          4735:        zend_encoding_detector encoding_detector;
        !          4736:        zend_encoding_converter encoding_converter;
        !          4737:        zend_encoding_oddlen encoding_oddlen;
        !          4738: 
        !          4739:        /* notify script encoding to Zend Engine */
        !          4740:        entry = MBSTRG(script_encoding_list);
        !          4741:        n = MBSTRG(script_encoding_list_size);
        !          4742:        while (n > 0) {
        !          4743:                name = (char *)mbfl_no_encoding2name(*entry);
        !          4744:                if (name) {
        !          4745:                        list_size += strlen(name) + 1;
        !          4746:                        if (!list) {
        !          4747:                                list = (char*)emalloc(list_size);
        !          4748:                                *list = '\0';
        !          4749:                        } else {
        !          4750:                                list = (char*)erealloc(list, list_size);
        !          4751:                                strcat(list, ",");
        !          4752:                        }
        !          4753:                        strcat(list, name);
        !          4754:                }
        !          4755:                entry++;
        !          4756:                n--;
        !          4757:        }
        !          4758:        zend_multibyte_set_script_encoding(list, (list ? strlen(list) : 0) TSRMLS_CC);
        !          4759:        if (list) {
        !          4760:                efree(list);
        !          4761:        }
        !          4762:        encoding_detector = php_mb_encoding_detector;
        !          4763:        encoding_converter = php_mb_encoding_converter;
        !          4764:        encoding_oddlen = php_mb_oddlen;
        !          4765: 
        !          4766:        /* TODO: make independent from mbstring.encoding_translation? */
        !          4767:        if (MBSTRG(encoding_translation)) {
        !          4768:                /* notify internal encoding to Zend Engine */
        !          4769:                name = (char*)mbfl_no_encoding2name(MBSTRG(current_internal_encoding));
        !          4770:                zend_multibyte_set_internal_encoding(name TSRMLS_CC);
        !          4771:        }
        !          4772: 
        !          4773:        zend_multibyte_set_functions(encoding_detector, encoding_converter, encoding_oddlen TSRMLS_CC);
        !          4774: 
        !          4775:        return 0;
        !          4776: }
        !          4777: /* }}} */
        !          4778: 
        !          4779: /* {{{ char *php_mb_encoding_detector()
        !          4780:  * Interface for Zend Engine
        !          4781:  */
        !          4782: static char* php_mb_encoding_detector(const unsigned char *arg_string, size_t arg_length, char *arg_list TSRMLS_DC)
        !          4783: {
        !          4784:        mbfl_string string;
        !          4785:        const char *ret;
        !          4786:        enum mbfl_no_encoding *elist;
        !          4787:        int size, *list;
        !          4788: 
        !          4789:        /* make encoding list */
        !          4790:        list = NULL;
        !          4791:        size = 0;
        !          4792:        php_mb_parse_encoding_list(arg_list, strlen(arg_list), &list, &size, 0 TSRMLS_CC);
        !          4793:        if (size <= 0) {
        !          4794:                return NULL;
        !          4795:        }
        !          4796:        if (size > 0 && list != NULL) {
        !          4797:                elist = list;
        !          4798:        } else {
        !          4799:                elist = MBSTRG(current_detect_order_list);
        !          4800:                size = MBSTRG(current_detect_order_list_size);
        !          4801:        }
        !          4802: 
        !          4803:        mbfl_string_init(&string);
        !          4804:        string.no_language = MBSTRG(language);
        !          4805:        string.val = (unsigned char *)arg_string;
        !          4806:        string.len = arg_length;
        !          4807:        ret = mbfl_identify_encoding_name(&string, elist, size, 0);
        !          4808:        if (list != NULL) {
        !          4809:                efree((void *)list);
        !          4810:        }
        !          4811:        if (ret != NULL) {
        !          4812:                return estrdup(ret);
        !          4813:        } else {
        !          4814:                return NULL;
        !          4815:        }
        !          4816: }
        !          4817: /* }}} */
        !          4818: 
        !          4819: /*     {{{ int php_mb_encoding_converter() */
        !          4820: static int php_mb_encoding_converter(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length, const char *encoding_to, const char *encoding_from TSRMLS_DC)
        !          4821: {
        !          4822:        mbfl_string string, result, *ret;
        !          4823:        enum mbfl_no_encoding from_encoding, to_encoding;
        !          4824:        mbfl_buffer_converter *convd;
        !          4825: 
        !          4826:        /* new encoding */
        !          4827:        to_encoding = mbfl_name2no_encoding(encoding_to);
        !          4828:        if (to_encoding == mbfl_no_encoding_invalid) {
        !          4829:                return -1;
        !          4830:        }       
        !          4831:        /* old encoding */
        !          4832:        from_encoding = mbfl_name2no_encoding(encoding_from);
        !          4833:        if (from_encoding == mbfl_no_encoding_invalid) {
        !          4834:                return -1;
        !          4835:        }
        !          4836:        /* initialize string */
        !          4837:        mbfl_string_init(&string);
        !          4838:        mbfl_string_init(&result);
        !          4839:        string.no_encoding = from_encoding;
        !          4840:        string.no_language = MBSTRG(language);
        !          4841:        string.val = (unsigned char*)from;
        !          4842:        string.len = from_length;
        !          4843: 
        !          4844:        /* initialize converter */
        !          4845:        convd = mbfl_buffer_converter_new(from_encoding, to_encoding, string.len);
        !          4846:        if (convd == NULL) {
        !          4847:                return -1;
        !          4848:        }
        !          4849:        mbfl_buffer_converter_illegal_mode(convd, MBSTRG(current_filter_illegal_mode));
        !          4850:        mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar));
        !          4851: 
        !          4852:        /* do it */
        !          4853:        ret = mbfl_buffer_converter_feed_result(convd, &string, &result);
        !          4854:        if (ret != NULL) {
        !          4855:                *to = ret->val;
        !          4856:                *to_length = ret->len;
        !          4857:        }
        !          4858: 
        !          4859:        MBSTRG(illegalchars) += mbfl_buffer_illegalchars(convd);
        !          4860:        mbfl_buffer_converter_delete(convd);
        !          4861: 
        !          4862:        return ret ? 0 : -1;
        !          4863: }
        !          4864: /* }}} */
        !          4865: 
        !          4866: /* {{{ int php_mb_oddlen()
        !          4867:  *     returns number of odd (e.g. appears only first byte of multibyte
        !          4868:  *     character) chars
        !          4869:  */
        !          4870: static size_t php_mb_oddlen(const unsigned char *string, size_t length, const char *encoding TSRMLS_DC)
        !          4871: {
        !          4872:        mbfl_string mb_string;
        !          4873: 
        !          4874:        mbfl_string_init(&mb_string);
        !          4875:        mb_string.no_language = MBSTRG(language);
        !          4876:        mb_string.no_encoding = mbfl_name2no_encoding(encoding);
        !          4877:        mb_string.val = (unsigned char *)string;
        !          4878:        mb_string.len = length;
        !          4879: 
        !          4880:        if (mb_string.no_encoding == mbfl_no_encoding_invalid) {
        !          4881:                return 0;
        !          4882:        }
        !          4883:        return mbfl_oddlen(&mb_string);
        !          4884: }
        !          4885: /* }}} */
        !          4886: #endif /* ZEND_MULTIBYTE */
        !          4887: 
        !          4888: #endif /* HAVE_MBSTRING */
        !          4889: 
        !          4890: /*
        !          4891:  * Local variables:
        !          4892:  * tab-width: 4
        !          4893:  * c-basic-offset: 4
        !          4894:  * End:
        !          4895:  * vim600: fdm=marker
        !          4896:  * vim: noet sw=4 ts=4
        !          4897:  */

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