/*
   +----------------------------------------------------------------------+
   | All rights reserved                                                  |
   |                                                                      |
   | Redistribution and use in source and binary forms, with or without   |
   | modification, are permitted provided that the following conditions   |
   | are met:                                                             |
   |                                                                      |
   | 1. Redistributions of source code must retain the above copyright    |
   |    notice, this list of conditions and the following disclaimer.     |
   | 2. Redistributions in binary form must reproduce the above copyright |
   |    notice, this list of conditions and the following disclaimer in   |
   |    the documentation and/or other materials provided with the        |
   |    distribution.                                                     |
   | 3. The names of the authors may not be used to endorse or promote    |
   |    products derived from this software without specific prior        |
   |    written permission.                                               |
   |                                                                      |
   | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
   | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
   | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
   | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE       |
   | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,  |
   | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
   | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;     |
   | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER     |
   | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT   |
   | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN    | 
   | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE      |
   | POSSIBILITY OF SUCH DAMAGE.                                          |
   +----------------------------------------------------------------------+
   | Authors: rsk <rsky0711@gmail.com>                                    |
   +----------------------------------------------------------------------+
*/

/* $ Id: $ */ 

#ifndef PHP_MECAB_PRIVATE_H
#define PHP_MECAB_PRIVATE_H

/* {{{ structures */

typedef struct {
	mecab_t *ptr;
	char *str;
	size_t len;
} php_mecab_t;

typedef struct {
	mecab_node_t *ptr;
	zend_bool valid;
} php_mecab_node_t;

/* }}} structures */

/* {{{ function prototypes */

#ifdef ZEND_ENGINE_2
static void class_init_MeCab_Tagger(void);
static void class_init_MeCab_Node(void);
static void class_init_MeCab_Path(void);
#endif
static void php_mecab_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC);
static void php_mecab_real_dtor(php_mecab_t *mecab TSRMLS_DC);
static void php_mecab_node_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC);
static void php_mecab_node_real_dtor(php_mecab_node_t *node TSRMLS_DC);
static void php_mecab_path_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC);
static zval *php_mecab_node_instantiate(zval *obj, php_mecab_node_t *node TSRMLS_DC);
static zval *php_mecab_node_get_sibling(zval *zv, php_mecab_node_t *node, const char *rel, zend_bool is_obj TSRMLS_DC);
static zval *php_mecab_node_get_path(zval *zv, php_mecab_node_t *node, const char *rel, zend_bool is_obj TSRMLS_DC);
static zval *php_mecab_path_instantiate(zval *obj, mecab_path_t *path TSRMLS_DC);
static zval *php_mecab_path_get_sibling(zval *zv, mecab_path_t *path, const char *rel, zend_bool is_obj TSRMLS_DC);
static zval *php_mecab_path_get_node(zval *zv, mecab_path_t *path, const char *rel, zend_bool is_obj TSRMLS_DC);

/* }}} function prototypes */

/* {{{ macro for fetching resources */

/* fetch (php_mecab_t *) from "mecab" resource */
#define PHP_MECAB_TAGGER_FROM_ZVAL(mecab, zmecab) \
{ \
	ZEND_FETCH_RESOURCE((mecab), php_mecab_t *, &(zmecab), -1, "mecab", le_mecab); \
}

/* fetch (php_mecab_t *) from "mecab" property */
#ifdef ZEND_ENGINE_2
#define PHP_MECAB_TAGGER_FROM_OBJECT(mecab, zmecab, obj) \
{ \
	zmecab = zend_read_property(mecab_tagger_ce, (obj), "mecab", strlen("mecab"), 0 TSRMLS_CC); \
	PHP_MECAB_TAGGER_FROM_ZVAL((mecab), (zmecab)); \
}
#else
#define PHP_MECAB_TAGGER_FROM_OBJECT(mecab, zmecab, obj) {}
#endif

/* fetch (php_mecab_t *) from argument #1 */
#define PHP_MECAB_FETCH_TAGGER(mecab, zmecab, obj) \
{ \
	if (obj) { \
		if (ZEND_NUM_ARGS() != 0) { \
			WRONG_PARAM_COUNT; \
		} \
		PHP_MECAB_TAGGER_FROM_OBJECT((mecab), (zmecab), (obj)); \
	} else { \
		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &(zmecab)) == FAILURE) { \
			return; \
		} \
		PHP_MECAB_TAGGER_FROM_ZVAL((mecab), (zmecab)); \
	} \
}

/* fetch (php_mecab_node_t *) from "mecab_node" resource */
#define PHP_MECAB_NODE_FROM_ZVAL(node, znode) \
{ \
	ZEND_FETCH_RESOURCE((node), php_mecab_node_t *, &(znode), -1, "mecab_node", le_mecab_node); \
}

/* fetch (php_mecab_node_t *) from "node" property */
#ifdef ZEND_ENGINE_2
#define PHP_MECAB_NODE_FROM_OBJECT(node, znode, obj) \
{ \
	znode = zend_read_property(mecab_node_ce, (obj), "node", strlen("node"), 0 TSRMLS_CC); \
	PHP_MECAB_NODE_FROM_ZVAL((node), (znode)); \
}
#else
#define PHP_MECAB_NODE_FROM_OBJECT(node, znode, obj) {}
#endif

/* fetch (php_mecab_node_t *) from argument #1 */
#define PHP_MECAB_NODE_FROM_ARG1(node, znode, obj) \
{ \
	if (obj) { \
		if (ZEND_NUM_ARGS() != 0) { \
			WRONG_PARAM_COUNT; \
		} \
		PHP_MECAB_NODE_FROM_OBJECT((node), (znode), (obj)); \
		is_obj = 1; \
	} else { \
		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &(znode)) == FAILURE) { \
			return; \
		} \
		PHP_MECAB_NODE_FROM_ZVAL((node), (znode)); \
	} \
}

/* fetch (php_mecab_node_t *) from "mecab_node" resource */
#define PHP_MECAB_PATH_FROM_ZVAL(path, zpath) \
{ \
	ZEND_FETCH_RESOURCE((path), mecab_path_t *, &(zpath), -1, "mecab_path", le_mecab_path); \
}

/* fetch (mecab_path_t *) from "path" property */
#ifdef ZEND_ENGINE_2
#define PHP_MECAB_PATH_FROM_OBJECT(path, zpath, obj) \
{ \
	(zpath) = zend_read_property(mecab_path_ce, (obj), "path", strlen("path"), 0 TSRMLS_CC); \
	PHP_MECAB_PATH_FROM_ZVAL((path), (zpath)); \
}
#else
#define PHP_MECAB_PATH_FROM_OBJECT(path, zpath, obj) {}
#endif

/* fetch (mecab_path_t *) from argument #1 */
#define PHP_MECAB_PATH_FROM_ARG1(path, zpath, obj) \
{ \
	if (obj) { \
		if (ZEND_NUM_ARGS() != 0) { \
			WRONG_PARAM_COUNT; \
		} \
		PHP_MECAB_PATH_FROM_OBJECT((path), (zpath), (obj)); \
		is_obj = 1; \
	} else { \
		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &(zpath)) == FAILURE) { \
			return; \
		} \
		PHP_MECAB_PATH_FROM_ZVAL((path), (zpath)); \
	} \
}

/* }}} macro for fetching resources */

/* {{{ macro for declaration of variables */

#ifdef ZEND_ENGINE_2
#define PHP_MECAB_THIS_OBJ getThis()
#define PHP_MECAB_NODE_GETTER_VARS zval *obj = getThis(); zval *znode = NULL; php_mecab_node_t *node = NULL; zend_bool is_obj = 0;
#define PHP_MECAB_PATH_GETTER_VARS zval *obj = getThis(); zval *zpath = NULL; mecab_path_t *path = NULL; zend_bool is_obj = 0;
#else
#define PHP_MECAB_THIS_OBJ NULL
#define PHP_MECAB_NODE_GETTER_VARS zval *obj = NULL; zval *znode = NULL; php_mecab_node_t *node = NULL; zend_bool is_obj = 0;
#define PHP_MECAB_PATH_GETTER_VARS zval *obj = NULL; zval *zpath = NULL; mecab_path_t *path = NULL; zend_bool is_obj = 0;
#endif

/* }}} macro for declaration of variables */

/* {{{ macro for manage structures */

/* allocate for php_mecab */
#define PHP_MECAB_TAGGER_ALLOC(mecab) \
{ \
	mecab = (php_mecab_t *)emalloc(sizeof(php_mecab_t)); \
}

/* create empty php_mecab */
#define PHP_MECAB_TAGGER_INIT(mecab) \
{ \
	PHP_MECAB_TAGGER_ALLOC(mecab); \
	(mecab)->ptr = NULL; \
	(mecab)->str = NULL; \
	(mecab)->len = 0; \
}

/* create php_mecab and set inner string */
#define PHP_MECAB_TAGGER_SETUP(mecab, new_str, new_len) \
{ \
	PHP_MECAB_TAGGER_ALLOC(mecab); \
	(mecab)->ptr = NULL; \
	(mecab)->str = estrndup((new_str), (new_len)); \
	(mecab)->len = (new_len); \
}

/* update inner string of php_mecab */
#define PHP_MECAB_TAGGER_UPDATE(mecab, new_str, new_len) \
{ \
	if ((mecab)->str) { \
		efree((mecab)->str); \
	} \
	(mecab)->str = estrndup((new_str), (new_len)); \
	(mecab)->len = (new_len); \
}

/* free php_mecab */
#define PHP_MECAB_TAGGER_FREE(mecab) \
{ \
	php_mecab_real_dtor((mecab) TSRMLS_CC); \
}

/* allocate for php_mecab_node */
#define PHP_MECAB_NODE_ALLOC(node) \
{ \
	node = (php_mecab_node_t *)emalloc(sizeof(php_mecab_node_t)); \
}

/* create empty php_mecab_node */
#define PHP_MECAB_NODE_INIT(node) \
{ \
	PHP_MECAB_NODE_ALLOC(node); \
	(node)->ptr = NULL; \
	(node)->valid = 0; \
}

/* create php_mecab_node and set inner pointer */
#define PHP_MECAB_NODE_SETUP(node, new_ptr) \
{ \
	PHP_MECAB_NODE_ALLOC(node); \
	(node)->ptr = (new_ptr); \
	(node)->valid = 1; \
}

/* update inner pointer of php_mecab_node */
#define PHP_MECAB_NODE_UPDATE(node, new_ptr) \
{ \
	(node)->ptr = (new_ptr); \
	(node)->valid = 1; \
}

/* free php_mecab_node */
#define PHP_MECAB_NODE_FREE(node) \
{ \
	php_mecab_node_real_dtor((node) TSRMLS_CC); \
}

/* }}} macro for manage structures */

#endif /* PHP_MECAB_PRIVATE_H */


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */


syntax highlighted by Code2HTML, v. 0.9.1