1
      li~h
nbѿ0  +   lY>eJ}@?q1heǂ_I|+ ?     /*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2016 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Tsukada Takuya <tsukada@fminn.nagano.nagano.jp>              |
   +----------------------------------------------------------------------+
 */

/* $Id$ */


#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_ini.h"

#if HAVE_MBREGEX

#include "ext/standard/php_smart_str.h"
#include "ext/standard/info.h"
#include "php_mbregex.h"
#include "mbstring.h"

#include "php_onig_compat.h" /* must come prior to the oniguruma header */
#include <oniguruma.h>
#undef UChar

ZEND_EXTERN_MODULE_GLOBALS(mbstring)

struct _zend_mb_regex_globals {
	OnigEncoding default_mbctype;
	OnigEncoding current_mbctype;
	HashTable ht_rc;
	zval *search_str;
	zval *search_str_val;
	unsigned int search_pos;
	php_mb_regex_t *search_re;
	OnigRegion *search_regs;
	OnigOptionType regex_default_options;
	OnigSyntaxType *regex_default_syntax;
};

#define MBREX(g) (MBSTRG(mb_regex_globals)->g)

/* {{{ static void php_mb_regex_free_cache() */
static void php_mb_regex_free_cache(php_mb_regex_t **pre)
{
	onig_free(*pre);
}
/* }}} */

/* {{{ _php_mb_regex_globals_ctor */
static int _php_mb_regex_globals_ctor(zend_mb_regex_globals *pglobals TSRMLS_DC)
{
	pglobals->default_mbctype = ONIG_ENCODING_UTF8;
	pglobals->current_mbctype = ONIG_ENCODING_UTF8;
	zend_hash_init(&(pglobals->ht_rc), 0, NULL, (void (*)(void *)) php_mb_regex_free_cache, 1);
	pglobals->search_str = (zval*) NULL;
	pglobals->search_re = (php_mb_regex_t*)NULL;
	pglobals->search_pos = 0;
	pglobals->search_regs = (OnigRegion*)NULL;
	pglobals->regex_default_options = ONIG_OPTION_MULTILINE | ONIG_OPTION_SINGLELINE;
	pglobals->regex_default_syntax = ONIG_SYNTAX_RUBY;
	return SUCCESS;
}
/* }}} */

/* {{{ _php_mb_regex_globals_dtor */
static void _php_mb_regex_globals_dtor(zend_mb_regex_globals *pglobals TSRMLS_DC)
{
	zend_hash_destroy(&pglobals->ht_rc);
}
/* }}} */

/* {{{ php_mb_regex_globals_alloc */
zend_mb_regex_globals *php_mb_regex_globals_alloc(TSRMLS_D)
{
	zend_mb_regex_globals *pglobals = pemalloc(
			sizeof(zend_mb_regex_globals), 1);
	if (!pglobals) {
		return NULL;
	}
	if (SUCCESS != _php_mb_regex_globals_ctor(pglobals TSRMLS_CC)) {
		pefree(pglobals, 1);
		return NULL;
	}
	return pglobals;
}
/* }}} */

/* {{{ php_mb_regex_globals_free */
void php_mb_regex_globals_free(zend_mb_regex_globals *pglobals TSRMLS_DC)
{
	if (!pglobals) {
		return;
	}
	_php_mb_regex_globals_dtor(pglobals TSRMLS_CC);
	pefree(pglobals, 1);
}
/* }}} */

/* {{{ PHP_MINIT_FUNCTION(mb_regex) */
PHP_MINIT_FUNCTION(mb_regex)
{
	onig_init();
	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MSHUTDOWN_FUNCTION(mb_regex) */
PHP_MSHUTDOWN_FUNCTION(mb_regex)
{
	onig_end();
	return SUCCESS;
}
/* }}} */

/* {{{ PHP_RINIT_FUNCTION(mb_regex) */
PHP_RINIT_FUNCTION(mb_regex)
{
	return MBSTRG(mb_regex_globals) ? SUCCESS: FAILURE;
}
/* }}} */

/* {{{ PHP_RSHUTDOWN_FUNCTION(mb_regex) */
PHP_RSHUTDOWN_FUNCTION(mb_regex)
{
	MBREX(current_mbctype) = MBREX(default_mbctype);

	if (MBREX(search_str) != NULL) {
		zval_ptr_dtor(&MBREX(search_str