1 /**
2 * The MeCab PHP extension
3 *
4 * Copyright (c) 2006-2015 Ryusuke SEKIYAMA. All rights reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * @package php-mecab
25 * @author Ryusuke SEKIYAMA <rsky0711@gmail.com>
26 * @copyright 2006-2015 Ryusuke SEKIYAMA
27 * @license http://www.opensource.org/licenses/mit-license.php MIT License
28 * @version $Id$
29 */
30
31 #include "php_mecab.h"
32 #include "php_mecab_compat5.h"
33
34 #define PATHBUFSIZE (MAXPATHLEN + 3)
35
36 /* {{{ globals */
37
38 static ZEND_DECLARE_MODULE_GLOBALS(mecab)
39
40 static int le_mecab;
41 static int le_mecab_node;
42 static int le_mecab_path;
43
44 /* }}} */
45
46 /* {{{ class entries */
47
48 static zend_class_entry *ext_ce_Iterator;
49 static zend_class_entry *ext_ce_IteratorAggregate;
50 static zend_class_entry *ext_ce_BadMethodCallException;
51 static zend_class_entry *ext_ce_InvalidArgumentException;
52 static zend_class_entry *ext_ce_OutOfRangeException;
53
54 static zend_class_entry *ce_MeCab_Tagger = NULL;
55 static zend_class_entry *ce_MeCab_Node = NULL;
56 static zend_class_entry *ce_MeCab_NodeIterator = NULL;
57 static zend_class_entry *ce_MeCab_Path = NULL;
58
59 static zend_class_entry *ce_MeCab_Deprecated = NULL;
60 static zend_class_entry *ce_MeCab_Tagger_Deprecated = NULL;
61 static zend_class_entry *ce_MeCab_Node_Deprecated = NULL;
62 static zend_class_entry *ce_MeCab_Path_Deprecated = NULL;
63
64 static zend_object_handlers php_mecab_object_handlers;
65 static zend_object_handlers php_mecab_node_object_handlers;
66 static zend_object_handlers php_mecab_path_object_handlers;
67
68 /* }}} */
69
70 /* {{{ module function prototypes */
71
72 static PHP_MINIT_FUNCTION(mecab);
73 static PHP_MSHUTDOWN_FUNCTION(mecab);
74 static PHP_MINFO_FUNCTION(mecab);
75 static PHP_GINIT_FUNCTION(mecab);
76
77 /* }}} */
78
79 /* {{{ PHP function prototypes */
80
81 /* Get MeCab library version */
82 static PHP_FUNCTION(mecab_version);
83 /* Wakati-Gaki function */
84 static PHP_FUNCTION(mecab_split);
85 /* MeCab API wrappers */
86 static PHP_FUNCTION(mecab_new);
87 static PHP_FUNCTION(mecab_destroy);
88 static PHP_FUNCTION(mecab_get_partial);
89 static PHP_FUNCTION(mecab_set_partial);
90 static PHP_FUNCTION(mecab_get_theta);
91 static PHP_FUNCTION(mecab_set_theta);
92 static PHP_FUNCTION(mecab_get_lattice_level);
93 static PHP_FUNCTION(mecab_set_lattice_level);
94 static PHP_FUNCTION(mecab_get_all_morphs);
95 static PHP_FUNCTION(mecab_set_all_morphs);
96 static PHP_FUNCTION(mecab_sparse_tostr);
97 static PHP_FUNCTION(mecab_sparse_tonode);
98 static PHP_FUNCTION(mecab_nbest_sparse_tostr);
99 static PHP_FUNCTION(mecab_nbest_init);
100 static PHP_FUNCTION(mecab_nbest_next_tostr);
101 static PHP_FUNCTION(mecab_nbest_next_tonode);
102 static PHP_FUNCTION(mecab_format_node);
103 static PHP_FUNCTION(mecab_dictionary_info);
104 /* Dumper for mecab_node */
105 static PHP_FUNCTION(mecab_node_toarray);
106 static PHP_FUNCTION(mecab_node_tostring);
107 /* Getters for mecab_node */
108 static PHP_FUNCTION(mecab_node_prev);
109 static PHP_FUNCTION(mecab_node_next);
110 static PHP_FUNCTION(mecab_node_enext);
111 static PHP_FUNCTION(mecab_node_bnext);
112 static PHP_FUNCTION(mecab_node_rpath);
113 static PHP_FUNCTION(mecab_node_lpath);
114 static PHP_FUNCTION(mecab_node_surface);
115 static PHP_FUNCTION(mecab_node_feature);
116 static PHP_FUNCTION(mecab_node_id);
117 static PHP_FUNCTION(mecab_node_length);
118 static PHP_FUNCTION(mecab_node_rlength);
119 static PHP_FUNCTION(mecab_node_rcattr);
120 static PHP_FUNCTION(mecab_node_lcattr);
121 static PHP_FUNCTION(mecab_node_posid);
122 static PHP_FUNCTION(mecab_node_char_type);
123 static PHP_FUNCTION(mecab_node_stat);
124 static PHP_FUNCTION(mecab_node_isbest);
125 static PHP_FUNCTION(mecab_node_alpha);
126 static PHP_FUNCTION(mecab_node_beta);
127 static PHP_FUNCTION(mecab_node_prob);
128 static PHP_FUNCTION(mecab_node_wcost);
129 static PHP_FUNCTION(mecab_node_cost);
130 /* Getters for mecab_path */
131 static PHP_FUNCTION(mecab_path_rnext);
132 static PHP_FUNCTION(mecab_path_lnext);
133 static PHP_FUNCTION(mecab_path_rnode);
134 static PHP_FUNCTION(mecab_path_lnode);
135 static PHP_FUNCTION(mecab_path_prob);
136 static PHP_FUNCTION(mecab_path_cost);
137
138 /* }}} */
139
140 /* {{{ PHP method prototypes */
141
142 static PHP_METHOD(MeCab_Node, __construct);
143 static PHP_METHOD(MeCab_Path, __construct);
144 /* Overloading implementations for mecab_node */
145 static PHP_METHOD(MeCab_Node, __get);
146 static PHP_METHOD(MeCab_Node, __isset);
147 /* IteratorAggregate implementations for mecab_node */
148 static PHP_METHOD(MeCab_Node, getIterator);
149 static PHP_METHOD(MeCab_Node, setTraverse);
150 /* Iterator implementations for mecab_node */
151 static PHP_METHOD(MeCab_NodeIterator, __construct);
152 static PHP_METHOD(MeCab_NodeIterator, current);
153 static PHP_METHOD(MeCab_NodeIterator, key);
154 static PHP_METHOD(MeCab_NodeIterator, valid);
155 static PHP_METHOD(MeCab_NodeIterator, rewind);
156 static PHP_METHOD(MeCab_NodeIterator, next);
157 /* Overloading implementations for mecab_path */
158 static PHP_METHOD(MeCab_Path, __get);
159 static PHP_METHOD(MeCab_Path, __isset);
160
161 /* }}} */
162
163 /* {{{ internal function prototypes */
164
165 /* allocate for mecab */
166 static php_mecab *
167 php_mecab_ctor(TSRMLS_D);
168
169 /* free the mecab */
170 static void
171 php_mecab_dtor(php_mecab *mecab TSRMLS_DC);
172
173 /* free the mecab resource */
174 static void
175 php_mecab_free_resource(zend_rsrc_list_entry *rsrc TSRMLS_DC);
176
177 /* set string to the mecab */
178 static void
179 php_mecab_set_string(php_mecab *mecab, const char *str, int len TSRMLS_DC);
180
181 /* allocate for mecab_node */
182 static php_mecab_node *
183 php_mecab_node_ctor(TSRMLS_D);
184
185 /* free the mecab_node */
186 static void
187 php_mecab_node_dtor(php_mecab_node *node TSRMLS_DC);
188
189 /* free the mecab_node resource */
190 static void
191 php_mecab_node_free_resource(zend_rsrc_list_entry *rsrc TSRMLS_DC);
192
193 /* set mecab to the mecab_node */
194 static void
195 php_mecab_node_set_tagger(php_mecab_node *node, php_mecab *mecab TSRMLS_DC);
196
197 /* allocate for mecab_path */
198 static php_mecab_path *
199 php_mecab_path_ctor(TSRMLS_D);
200
201 /* free the mecab_path */
202 static void
203 php_mecab_path_dtor(php_mecab_path *path TSRMLS_DC);
204
205 /* free the mecab_path resource */
206 static void
207 php_mecab_path_free_resource(zend_rsrc_list_entry *rsrc TSRMLS_DC);
208
209 /* set mecab_node to the mecab_path */
210 static void
211 php_mecab_path_set_tagger(php_mecab_path *path, php_mecab *mecab TSRMLS_DC);
212
213 /* get sibling node from mecab_node */
214 static zval *
215 php_mecab_node_get_sibling(zval *zv, zval *object, php_mecab_node *xnode, php_mecab_node_rel rel TSRMLS_DC);
216
217 /* get related path from mecab_node */
218 static zval *
219 php_mecab_node_get_path(zval *zv, zval *object, php_mecab_node *xnode, php_mecab_node_rel rel TSRMLS_DC);
220
221 /* get sibling path from mecab_path */
222 static zval *
223 php_mecab_path_get_sibling(zval *zv, zval *object, php_mecab_path *xpath, php_mecab_path_rel rel TSRMLS_DC);
224
225 /* get related node from mecab_path */
226 static zval *
227 php_mecab_path_get_node(zval *zv, zval *object, php_mecab_path *xpath, php_mecab_path_rel rel TSRMLS_DC);
228
229 /* wrappers */
230 static void
231 php_mecab_node_get_sibling_wrapper(INTERNAL_FUNCTION_PARAMETERS, php_mecab_node_rel rel),
232 php_mecab_node_get_path_wrapper(INTERNAL_FUNCTION_PARAMETERS, php_mecab_node_rel rel),
233 php_mecab_path_get_sibling_wrapper(INTERNAL_FUNCTION_PARAMETERS, php_mecab_path_rel rel),
234 php_mecab_path_get_node_wrapper(INTERNAL_FUNCTION_PARAMETERS, php_mecab_path_rel rel);
235
236 /* allocate for mecab object */
237 zend_object_value
238 php_mecab_object_new(zend_class_entry *ce TSRMLS_DC);
239
240 /* free the mecab object */
241 static void
242 php_mecab_free_object_storage(void *object TSRMLS_DC);
243
244 /* allocate for mecab_node object */
245 zend_object_value
246 php_mecab_node_object_new(zend_class_entry *ce TSRMLS_DC);
247
248 /* free the mecab_node object */
249 static void
250 php_mecab_node_free_object_storage(void *object TSRMLS_DC);
251
252 /* allocate for mecab_path object */
253 zend_object_value
254 php_mecab_path_object_new(zend_class_entry *ce TSRMLS_DC);
255
256 /* free the mecab_path object */
257 static void
258 php_mecab_path_free_object_storage(void *object TSRMLS_DC);
259
260 /* get the class entry */
261 static zend_class_entry *
262 php_mecab_get_class_entry(const char *lcname TSRMLS_DC);
263
264 /* }}} */
265
266 /* check file/dicectory accessibility */
267 static zend_bool
268 php_mecab_check_path(const char *path, size_t length, char *real_path TSRMLS_DC);
269
270 /* }}} */
271
272 /* {{{ argument informations */
273
274 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab__mecab, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
275 ZEND_ARG_INFO(0, mecab)
276 ZEND_END_ARG_INFO()
277
278 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_split, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
279 ZEND_ARG_INFO(0, str)
280 ZEND_ARG_INFO(0, dicdir)
281 ZEND_ARG_INFO(0, userdic)
282 ZEND_END_ARG_INFO()
283
284 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_new, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0)
285 ZEND_ARG_ARRAY_INFO(0, arg, 1)
286 ZEND_END_ARG_INFO()
287
288 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_set_partial, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
289 ZEND_ARG_INFO(0, mecab)
290 ZEND_ARG_INFO(0, partial)
291 ZEND_END_ARG_INFO()
292
293 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_set_partial_m, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0)
294 ZEND_ARG_INFO(0, partial)
295 ZEND_END_ARG_INFO()
296
297 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_set_theta, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
298 ZEND_ARG_INFO(0, mecab)
299 ZEND_ARG_INFO(0, theta)
300 ZEND_END_ARG_INFO()
301
302 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_set_theta_m, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0)
303 ZEND_ARG_INFO(0, theta)
304 ZEND_END_ARG_INFO()
305
306 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_set_lattice_level, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
307 ZEND_ARG_INFO(0, mecab)
308 ZEND_ARG_INFO(0, level)
309 ZEND_END_ARG_INFO()
310
311 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_set_lattice_level_m, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0)
312 ZEND_ARG_INFO(0, level)
313 ZEND_END_ARG_INFO()
314
315 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_set_all_morphs, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
316 ZEND_ARG_INFO(0, mecab)
317 ZEND_ARG_INFO(0, all_morphs)
318 ZEND_END_ARG_INFO()
319
320 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_set_all_morphs_m, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0)
321 ZEND_ARG_INFO(0, all_morphs)
322 ZEND_END_ARG_INFO()
323
324 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_sparse_tostr, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 2)
325 ZEND_ARG_INFO(0, mecab)
326 ZEND_ARG_INFO(0, str)
327 ZEND_ARG_INFO(0, len)
328 ZEND_ARG_INFO(0, olen)
329 ZEND_END_ARG_INFO()
330
331 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_sparse_tostr_m, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
332 ZEND_ARG_INFO(0, str)
333 ZEND_ARG_INFO(0, len)
334 ZEND_ARG_INFO(0, olen)
335 ZEND_END_ARG_INFO()
336
337 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_sparse_tonode, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 2)
338 ZEND_ARG_INFO(0, mecab)
339 ZEND_ARG_INFO(0, str)
340 ZEND_ARG_INFO(0, len)
341 ZEND_END_ARG_INFO()
342
343 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_sparse_tonode_m, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
344 ZEND_ARG_INFO(0, str)
345 ZEND_ARG_INFO(0, len)
346 ZEND_END_ARG_INFO()
347
348 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_nbest_sparse_tostr, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 3)
349 ZEND_ARG_INFO(0, mecab)
350 ZEND_ARG_INFO(0, n)
351 ZEND_ARG_INFO(0, str)
352 ZEND_ARG_INFO(0, len)
353 ZEND_ARG_INFO(0, olen)
354 ZEND_END_ARG_INFO()
355
356 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_nbest_sparse_tostr_m, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 2)
357 ZEND_ARG_INFO(0, n)
358 ZEND_ARG_INFO(0, str)
359 ZEND_ARG_INFO(0, len)
360 ZEND_ARG_INFO(0, olen)
361 ZEND_END_ARG_INFO()
362
363 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_nbest_init, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 2)
364 ZEND_ARG_INFO(0, mecab)
365 ZEND_ARG_INFO(0, str)
366 ZEND_ARG_INFO(0, len)
367 ZEND_END_ARG_INFO()
368
369 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_nbest_init_m, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
370 ZEND_ARG_INFO(0, str)
371 ZEND_ARG_INFO(0, len)
372 ZEND_END_ARG_INFO()
373
374 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_nbest_next_tostr, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
375 ZEND_ARG_INFO(0, mecab)
376 ZEND_ARG_INFO(0, olen)
377 ZEND_END_ARG_INFO()
378
379 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_nbest_next_tostr_m, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0)
380 ZEND_ARG_INFO(0, olen)
381 ZEND_END_ARG_INFO()
382
383 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_format_node, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
384 ZEND_ARG_INFO(0, mecab)
385 ZEND_ARG_INFO(0, node)
386 ZEND_END_ARG_INFO()
387
388 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_format_node_m, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
389 ZEND_ARG_OBJ_INFO(0, node, MeCab_Node, 0)
390 ZEND_END_ARG_INFO()
391
392 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_node__node, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
393 ZEND_ARG_INFO(0, node)
394 ZEND_END_ARG_INFO()
395
396 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_node_toarray, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
397 ZEND_ARG_INFO(0, node)
398 ZEND_ARG_INFO(0, dump_all)
399 ZEND_END_ARG_INFO()
400
401 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_node_toarray_m, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0)
402 ZEND_ARG_INFO(0, dump_all)
403 ZEND_END_ARG_INFO()
404
405 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_node_settraverse, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
406 ZEND_ARG_INFO(0, traverse)
407 ZEND_END_ARG_INFO()
408
409 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab_path__path, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
410 ZEND_ARG_INFO(0, path)
411 ZEND_END_ARG_INFO()
412
413 ZEND_BEGIN_ARG_INFO_EX(arginfo_mecab__magic_getter, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
414 ZEND_ARG_INFO(0, name)
415 ZEND_END_ARG_INFO()
416
417 /* }}} arginfo */
418
419 /* {{{ MeCab methods[] */
420 #define PM_TAGGER_ME_MAPPING(methname, funcname) \
421 PHP_ME_MAPPING(methname, mecab_ ## funcname, NULL, ZEND_ACC_PUBLIC)
422
423 #define PM_TAGGER_ME_MAPPING_EX(methname, funcname) \
424 PHP_ME_MAPPING(methname, mecab_ ## funcname, arginfo_mecab_ ## funcname ## _m, ZEND_ACC_PUBLIC)
425
426 static zend_function_entry mecab_methods[] = {
427 /* MeCab API wrappers */
428 PHP_ME_MAPPING(__construct, mecab_new, arginfo_mecab_new, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
429 PM_TAGGER_ME_MAPPING(getPartial, get_partial)
430 PM_TAGGER_ME_MAPPING_EX(setPartial, set_partial)
431 PM_TAGGER_ME_MAPPING(getTheta, get_theta)
432 PM_TAGGER_ME_MAPPING_EX(setTheta, set_theta)
433 PM_TAGGER_ME_MAPPING(getLatticeLevel, get_lattice_level)
434 PM_TAGGER_ME_MAPPING_EX(setLatticeLevel, set_lattice_level)
435 PM_TAGGER_ME_MAPPING(getAllMorphs, get_all_morphs)
436 PM_TAGGER_ME_MAPPING_EX(setAllMorphs, set_all_morphs)
437 PM_TAGGER_ME_MAPPING_EX(parse, sparse_tostr)
438 PM_TAGGER_ME_MAPPING_EX(parseToString, sparse_tostr)
439 PM_TAGGER_ME_MAPPING_EX(parseToNode, sparse_tonode)
440 PM_TAGGER_ME_MAPPING_EX(parseNBest, nbest_sparse_tostr)
441 PM_TAGGER_ME_MAPPING_EX(parseNBestInit, nbest_init)
442 PM_TAGGER_ME_MAPPING_EX(next, nbest_next_tostr)
443 PM_TAGGER_ME_MAPPING(nextNode, nbest_next_tonode)
444 PM_TAGGER_ME_MAPPING_EX(formatNode, format_node)
445 PM_TAGGER_ME_MAPPING(dictionaryInfo, dictionary_info)
446 PHP_FE_END
447 };
448
449 static zend_function_entry mecab_deprecated_methods[] = {
450 PHP_ME_MAPPING(version, mecab_version, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC | ZEND_ACC_DEPRECATED)
451 PHP_ME_MAPPING(split, mecab_split, arginfo_mecab_split, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC | ZEND_ACC_DEPRECATED)
452 PHP_ME_MAPPING(__construct, mecab_new, arginfo_mecab_new, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR | ZEND_ACC_DEPRECATED)
453 PHP_FE_END
454 };
455 /* }}} */
456
457 /* {{{ MeCab_Node methods[] */
458 #define PM_NODE_ME_MAPPING(methname, funcname) \
459 PHP_ME_MAPPING(methname, mecab_node_ ## funcname, NULL, ZEND_ACC_PUBLIC)
460
461 static zend_function_entry mecab_node_methods[] = {
462 /* Constructor */
463 PHP_ME(MeCab_Node, __construct, NULL, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR)
464 /* Overloading implementations */
465 PHP_ME(MeCab_Node, __get, arginfo_mecab__magic_getter, ZEND_ACC_PUBLIC)
466 PHP_ME(MeCab_Node, __isset, arginfo_mecab__magic_getter, ZEND_ACC_PUBLIC)
467 /* IteratorAggregate implementations */
468 PHP_ME(MeCab_Node, getIterator, NULL, ZEND_ACC_PUBLIC)
469 PHP_ME(MeCab_Node, setTraverse, arginfo_mecab_node_settraverse, ZEND_ACC_PUBLIC)
470 /* Dumper */
471 PHP_ME_MAPPING(toArray, mecab_node_toarray, arginfo_mecab_node_toarray_m, ZEND_ACC_PUBLIC)
472 PM_NODE_ME_MAPPING(toString, tostring)
473 PM_NODE_ME_MAPPING(__toString, tostring)
474 /* Getters */
475 PM_NODE_ME_MAPPING(getPrev, prev)
476 PM_NODE_ME_MAPPING(getNext, next)
477 PM_NODE_ME_MAPPING(getENext, enext)
478 PM_NODE_ME_MAPPING(getBNext, bnext)
479 PM_NODE_ME_MAPPING(getRPath, rpath)
480 PM_NODE_ME_MAPPING(getLPath, lpath)
481 PM_NODE_ME_MAPPING(getSurface, surface)
482 PM_NODE_ME_MAPPING(getFeature, feature)
483 PM_NODE_ME_MAPPING(getId, id)
484 PM_NODE_ME_MAPPING(getLength, length)
485 PM_NODE_ME_MAPPING(getRLength, rlength)
486 PM_NODE_ME_MAPPING(getRcAttr, rcattr)
487 PM_NODE_ME_MAPPING(getLcAttr, lcattr)
488 PM_NODE_ME_MAPPING(getPosId, posid)
489 PM_NODE_ME_MAPPING(getCharType, char_type)
490 PM_NODE_ME_MAPPING(getStat, stat)
491 PM_NODE_ME_MAPPING(isBest, isbest)
492 PM_NODE_ME_MAPPING(getAlpha, alpha)
493 PM_NODE_ME_MAPPING(getBeta, beta)
494 PM_NODE_ME_MAPPING(getProb, prob)
495 PM_NODE_ME_MAPPING(getWCost, wcost)
496 PM_NODE_ME_MAPPING(getCost, cost)
497 PHP_FE_END
498 };
499
500 static zend_function_entry mecab_node_deprecated_methods[] = {
501 PHP_ME(MeCab_Node, __construct, NULL, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR | ZEND_ACC_DEPRECATED)
502 PHP_FE_END
503 };
504 /* }}} */
505
506 /* {{{ MeCab_NodeIterator methods[] */
507 static zend_function_entry mecab_iterator_methods[] = {
508 /* Constructor */
509 PHP_ME(MeCab_NodeIterator, __construct, NULL, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR)
510 /* Iterator implementations */
511 PHP_ME(MeCab_NodeIterator, current, NULL, ZEND_ACC_PUBLIC)
512 PHP_ME(MeCab_NodeIterator, key, NULL, ZEND_ACC_PUBLIC)
513 PHP_ME(MeCab_NodeIterator, next, NULL, ZEND_ACC_PUBLIC)
514 PHP_ME(MeCab_NodeIterator, rewind, NULL, ZEND_ACC_PUBLIC)
515 PHP_ME(MeCab_NodeIterator, valid, NULL, ZEND_ACC_PUBLIC)
516 PHP_FE_END
517 };
518 /* }}} */
519
520 /* {{{ MeCab_Path methods[] */
521 #define PM_PATH_ME_MAPPING(methname, funcname) \
522 PHP_ME_MAPPING(methname, mecab_path_ ## funcname, NULL, ZEND_ACC_PUBLIC)
523
524 static zend_function_entry mecab_path_methods[] = {
525 /* Constructor */
526 PHP_ME(MeCab_Path, __construct, NULL, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR)
527 /* Overloading implementations */
528 PHP_ME(MeCab_Path, __get, arginfo_mecab__magic_getter, ZEND_ACC_PUBLIC)
529 PHP_ME(MeCab_Path, __isset, arginfo_mecab__magic_getter, ZEND_ACC_PUBLIC)
530 /* Getters */
531 PM_PATH_ME_MAPPING(getRNext, rnext)
532 PM_PATH_ME_MAPPING(getLNext, lnext)
533 PM_PATH_ME_MAPPING(getRNode, rnode)
534 PM_PATH_ME_MAPPING(getLNode, lnode)
535 PM_PATH_ME_MAPPING(getProb, prob)
536 PM_PATH_ME_MAPPING(getCost, cost)
537 PHP_FE_END
538 };
539
540 static zend_function_entry mecab_path_deprecated_methods[] = {
541 PHP_ME(MeCab_Path, __construct, NULL, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR | ZEND_ACC_DEPRECATED)
542 PHP_FE_END
543 };
544 /* }}} methods */
545
546 /* }}} class definitions */
547
548 /* {{{ mecab_functions[] */
549 #define PM_NODE_FE(name) PHP_FE(mecab_node_ ## name, arginfo_mecab_node__node)
550 #define PM_NODELIST_FE(name) PHP_FE(mecab_node_ ## name, arginfo_mecab_node__list)
551 #define PM_PATH_FE(name) PHP_FE(mecab_path_ ## name, arginfo_mecab_path__path)
552
553 static zend_function_entry mecab_functions[] = {
554 ZEND_NS_NAMED_FE("MeCab", version, ZEND_FN(mecab_version), NULL)
555 ZEND_NS_NAMED_FE("MeCab", split, ZEND_FN(mecab_split), arginfo_mecab_split)
556 /* Get MeCab library version */
557 PHP_FE(mecab_version, NULL)
558 /* Wakati-Gaki function */
559 PHP_FE(mecab_split, arginfo_mecab_split)
560 /* MeCab API wrappers */
561 PHP_FE(mecab_new, arginfo_mecab_new)
562 PHP_FE(mecab_destroy, arginfo_mecab__mecab)
563 PHP_FE(mecab_get_partial, arginfo_mecab__mecab)
564 PHP_FE(mecab_set_partial, arginfo_mecab_set_partial)
565 PHP_FE(mecab_get_theta, arginfo_mecab__mecab)
566 PHP_FE(mecab_set_theta, arginfo_mecab_set_theta)
567 PHP_FE(mecab_get_lattice_level, arginfo_mecab__mecab)
568 PHP_FE(mecab_set_lattice_level, arginfo_mecab_set_lattice_level)
569 PHP_FE(mecab_get_all_morphs, arginfo_mecab__mecab)
570 PHP_FE(mecab_set_all_morphs, arginfo_mecab_set_all_morphs)
571 PHP_FE(mecab_sparse_tostr, arginfo_mecab_sparse_tostr)
572 PHP_FE(mecab_sparse_tonode, arginfo_mecab_sparse_tonode)
573 PHP_FE(mecab_nbest_sparse_tostr, arginfo_mecab_nbest_sparse_tostr)
574 PHP_FE(mecab_nbest_init, arginfo_mecab_nbest_init)
575 PHP_FE(mecab_nbest_next_tostr, arginfo_mecab_nbest_next_tostr)
576 PHP_FE(mecab_nbest_next_tonode, arginfo_mecab__mecab)
577 PHP_FE(mecab_format_node, arginfo_mecab_format_node)
578 PHP_FE(mecab_dictionary_info, arginfo_mecab__mecab)
579 /* Dumper for mecab_node */
580 PHP_FE(mecab_node_toarray, arginfo_mecab_node_toarray)
581 PHP_FE(mecab_node_tostring, arginfo_mecab_node__node)
582 /* Getters for mecab_node */
583 PM_NODE_FE(prev)
584 PM_NODE_FE(next)
585 PM_NODE_FE(enext)
586 PM_NODE_FE(bnext)
587 PM_NODE_FE(rpath)
588 PM_NODE_FE(lpath)
589 PM_NODE_FE(surface)
590 PM_NODE_FE(feature)
591 PM_NODE_FE(id)
592 PM_NODE_FE(length)
593 PM_NODE_FE(rlength)
594 PM_NODE_FE(rcattr)
595 PM_NODE_FE(lcattr)
596 PM_NODE_FE(posid)
597 PM_NODE_FE(char_type)
598 PM_NODE_FE(stat)
599 PM_NODE_FE(isbest)
600 PM_NODE_FE(alpha)
601 PM_NODE_FE(beta)
602 PM_NODE_FE(prob)
603 PM_NODE_FE(wcost)
604 PM_NODE_FE(cost)
605 /* Getters for mecab_path */
606 PM_PATH_FE(rnext)
607 PM_PATH_FE(lnext)
608 PM_PATH_FE(rnode)
609 PM_PATH_FE(lnode)
610 PM_PATH_FE(prob)
611 PM_PATH_FE(cost)
612 PHP_FE_END
613 };
614 /* }}} */
615
616 /* {{{ cross-extension dependencies */
617
618 static zend_module_dep mecab_deps[] = {
619 ZEND_MOD_REQUIRED("spl")
620 { NULL, NULL, NULL, 0 }
621 };
622
623 /* }}} */
624
625 /* {{{ mecab_module_entry */
626 zend_module_entry mecab_module_entry = {
627 STANDARD_MODULE_HEADER_EX,
628 NULL,
629 mecab_deps,
630 "mecab",
631 mecab_functions,
632 PHP_MINIT(mecab),
633 PHP_MSHUTDOWN(mecab),
634 NULL,
635 NULL,
636 PHP_MINFO(mecab),
637 PHP_MECAB_MODULE_VERSION,
638 PHP_MODULE_GLOBALS(mecab),
639 PHP_GINIT(mecab),
640 NULL,
641 NULL,
642 STANDARD_MODULE_PROPERTIES_EX
643 };
644 /* }}} */
645
646 #ifdef COMPILE_DL_MECAB
647 ZEND_GET_MODULE(mecab)
648 #endif
649
650 /* {{{ ini entries */
651
PHP_INI_BEGIN()652 PHP_INI_BEGIN()
653 STD_PHP_INI_ENTRY("mecab.default_rcfile", "", PHP_INI_ALL,
654 OnUpdateString, default_rcfile, zend_mecab_globals, mecab_globals)
655 STD_PHP_INI_ENTRY("mecab.default_dicdir", "", PHP_INI_ALL,
656 OnUpdateString, default_dicdir, zend_mecab_globals, mecab_globals)
657 STD_PHP_INI_ENTRY("mecab.default_userdic", "", PHP_INI_ALL,
658 OnUpdateString, default_userdic, zend_mecab_globals, mecab_globals)
659 PHP_INI_END()
660
661 /* }}} */
662
663 /* {{{ PHP_MINIT_FUNCTION */
664 static PHP_MINIT_FUNCTION(mecab)
665 {
666 REGISTER_INI_ENTRIES();
667
668 REGISTER_NS_STRING_CONSTANT("MeCab", "VERSION", (char *)mecab_version(), CONST_PERSISTENT | CONST_CS);
669 PHP_MECAB_REGISTER_NS_CONSTANT(NOR_NODE);
670 PHP_MECAB_REGISTER_NS_CONSTANT(UNK_NODE);
671 PHP_MECAB_REGISTER_NS_CONSTANT(BOS_NODE);
672 PHP_MECAB_REGISTER_NS_CONSTANT(EOS_NODE);
673 PHP_MECAB_REGISTER_NS_CONSTANT(SYS_DIC);
674 PHP_MECAB_REGISTER_NS_CONSTANT(USR_DIC);
675 PHP_MECAB_REGISTER_NS_CONSTANT(UNK_DIC);
676
677 REGISTER_STRING_CONSTANT("MECAB_VERSION", (char *)mecab_version(), CONST_PERSISTENT | CONST_CS);
678 PHP_MECAB_REGISTER_CONSTANT(MECAB_NOR_NODE);
679 PHP_MECAB_REGISTER_CONSTANT(MECAB_UNK_NODE);
680 PHP_MECAB_REGISTER_CONSTANT(MECAB_BOS_NODE);
681 PHP_MECAB_REGISTER_CONSTANT(MECAB_EOS_NODE);
682 PHP_MECAB_REGISTER_CONSTANT(MECAB_SYS_DIC);
683 PHP_MECAB_REGISTER_CONSTANT(MECAB_USR_DIC);
684 PHP_MECAB_REGISTER_CONSTANT(MECAB_UNK_DIC);
685
686 le_mecab = zend_register_list_destructors_ex(
687 php_mecab_free_resource, NULL, "mecab", module_number);
688 le_mecab_node = zend_register_list_destructors_ex(
689 php_mecab_node_free_resource, NULL, "mecab_node", module_number);
690 le_mecab_path = zend_register_list_destructors_ex(
691 php_mecab_path_free_resource, NULL, "mecab_path", module_number);
692
693 ext_ce_Iterator = php_mecab_get_class_entry("iterator" TSRMLS_CC);
694 ext_ce_IteratorAggregate = php_mecab_get_class_entry("iteratoraggregate" TSRMLS_CC);
695 ext_ce_BadMethodCallException = php_mecab_get_class_entry("badmethodcallexception" TSRMLS_CC);
696 ext_ce_InvalidArgumentException = php_mecab_get_class_entry("invalidargumentexception" TSRMLS_CC);
697 ext_ce_OutOfRangeException = php_mecab_get_class_entry("outofrangeexception" TSRMLS_CC);
698 if (ext_ce_Iterator == NULL ||
699 ext_ce_IteratorAggregate == NULL ||
700 ext_ce_BadMethodCallException == NULL ||
701 ext_ce_InvalidArgumentException == NULL ||
702 ext_ce_OutOfRangeException == NULL)
703 {
704 return FAILURE;
705 }
706 {
707 zend_class_entry ce1, ce1a, ce1d;
708
709 INIT_NS_CLASS_ENTRY(ce1, "MeCab", "Tagger", mecab_methods);
710 ce_MeCab_Tagger = zend_register_internal_class(&ce1 TSRMLS_CC);
711 if (!ce_MeCab_Tagger) {
712 return FAILURE;
713 }
714 ce_MeCab_Tagger->create_object = php_mecab_object_new;
715
716 memcpy(&php_mecab_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
717 php_mecab_object_handlers.clone_obj = NULL;
718
719 zend_declare_class_constant_string(ce_MeCab_Tagger, "VERSION", 7, (char *)mecab_version() TSRMLS_CC);
720 zend_declare_class_constant_long(ce_MeCab_Tagger, "SYS_DIC", 7, MECAB_SYS_DIC TSRMLS_CC);
721 zend_declare_class_constant_long(ce_MeCab_Tagger, "USR_DIC", 7, MECAB_USR_DIC TSRMLS_CC);
722 zend_declare_class_constant_long(ce_MeCab_Tagger, "UNK_DIC", 7, MECAB_UNK_DIC TSRMLS_CC);
723
724 zend_declare_class_constant_string(ce_MeCab_Tagger, "VERSION", 7, (char *)mecab_version() TSRMLS_CC);
725 zend_declare_class_constant_long(ce_MeCab_Tagger, "SYS_DIC", 7, MECAB_SYS_DIC TSRMLS_CC);
726 zend_declare_class_constant_long(ce_MeCab_Tagger, "USR_DIC", 7, MECAB_USR_DIC TSRMLS_CC);
727 zend_declare_class_constant_long(ce_MeCab_Tagger, "UNK_DIC", 7, MECAB_UNK_DIC TSRMLS_CC);
728
729 INIT_CLASS_ENTRY(ce1a, "MeCab", mecab_deprecated_methods);
730 ce_MeCab_Deprecated = zend_register_internal_class_ex(&ce1a, ce_MeCab_Tagger, ZEND_NS_NAME("MeCab", "Tagger") TSRMLS_CC);
731 if (!ce_MeCab_Deprecated) {
732 return FAILURE;
733 }
734 ce_MeCab_Deprecated->create_object = php_mecab_object_new;
735
736 INIT_CLASS_ENTRY(ce1d, "MeCab_Tagger", mecab_deprecated_methods);
737 ce_MeCab_Tagger_Deprecated = zend_register_internal_class_ex(&ce1d, ce_MeCab_Tagger, ZEND_NS_NAME("MeCab", "Tagger") TSRMLS_CC);
738 if (!ce_MeCab_Tagger_Deprecated) {
739 return FAILURE;
740 }
741 ce_MeCab_Tagger_Deprecated->create_object = php_mecab_object_new;
742 }
743 {
744 zend_class_entry ce2, ce2d, ce2i;
745
746 INIT_NS_CLASS_ENTRY(ce2, "MeCab", "Node", mecab_node_methods);
747 ce_MeCab_Node = zend_register_internal_class(&ce2 TSRMLS_CC);
748 if (!ce_MeCab_Node) {
749 return FAILURE;
750 }
751 ce_MeCab_Node->create_object = php_mecab_node_object_new;
752
753 INIT_NS_CLASS_ENTRY(ce2i, "MeCab", "NodeIterator", mecab_iterator_methods);
754 ce_MeCab_NodeIterator = zend_register_internal_class(&ce2i TSRMLS_CC);
755 if (!ce_MeCab_NodeIterator) {
756 return FAILURE;
757 }
758 ce_MeCab_NodeIterator->create_object = php_mecab_node_object_new;
759
760 memcpy(&php_mecab_node_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
761 php_mecab_node_object_handlers.clone_obj = NULL;
762
763 zend_class_implements(ce_MeCab_Node TSRMLS_CC, 1, ext_ce_IteratorAggregate);
764 zend_class_implements(ce_MeCab_NodeIterator TSRMLS_CC, 1, ext_ce_Iterator);
765
766 zend_declare_class_constant_long(ce_MeCab_Node, "NOR", 3, MECAB_NOR_NODE TSRMLS_CC);
767 zend_declare_class_constant_long(ce_MeCab_Node, "UNK", 3, MECAB_UNK_NODE TSRMLS_CC);
768 zend_declare_class_constant_long(ce_MeCab_Node, "BOS", 3, MECAB_BOS_NODE TSRMLS_CC);
769 zend_declare_class_constant_long(ce_MeCab_Node, "EOS", 3, MECAB_EOS_NODE TSRMLS_CC);
770
771 zend_declare_class_constant_long(ce_MeCab_Node, "TRAVERSE_NEXT", 13, (long)TRAVERSE_NEXT TSRMLS_CC);
772 zend_declare_class_constant_long(ce_MeCab_Node, "TRAVERSE_ENEXT", 14, (long)TRAVERSE_ENEXT TSRMLS_CC);
773 zend_declare_class_constant_long(ce_MeCab_Node, "TRAVERSE_BNEXT", 14, (long)TRAVERSE_BNEXT TSRMLS_CC);
774
775 INIT_CLASS_ENTRY(ce2d, "MeCab_Node", mecab_node_deprecated_methods);
776 ce_MeCab_Node_Deprecated = zend_register_internal_class_ex(&ce2d, ce_MeCab_Node, ZEND_NS_NAME("MeCab", "Node") TSRMLS_CC);
777 if (!ce_MeCab_Node_Deprecated) {
778 return FAILURE;
779 }
780 ce_MeCab_Node_Deprecated->create_object = php_mecab_node_object_new;
781 }
782 {
783 zend_class_entry ce3, ce3d;
784
785 INIT_NS_CLASS_ENTRY(ce3, "MeCab", "Path", mecab_path_methods);
786 ce_MeCab_Path = zend_register_internal_class(&ce3 TSRMLS_CC);
787 if (!ce_MeCab_Path) {
788 return FAILURE;
789 }
790 ce_MeCab_Path->create_object = php_mecab_path_object_new;
791
792 memcpy(&php_mecab_path_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
793 php_mecab_path_object_handlers.clone_obj = NULL;
794
795 INIT_CLASS_ENTRY(ce3d, "MeCab_Path", mecab_path_deprecated_methods);
796 ce_MeCab_Path_Deprecated = zend_register_internal_class_ex(&ce3d, ce_MeCab_Path, ZEND_NS_NAME("MeCab", "Path") TSRMLS_CC);
797 if (!ce_MeCab_Path_Deprecated) {
798 return FAILURE;
799 }
800 ce_MeCab_Path_Deprecated->create_object = php_mecab_path_object_new;
801 }
802
803 return SUCCESS;
804 }
805 /* }}} */
806
807 /* {{{ PHP_MSHUTDOWN_FUNCTION */
PHP_MSHUTDOWN_FUNCTION(mecab)808 static PHP_MSHUTDOWN_FUNCTION(mecab)
809 {
810 UNREGISTER_INI_ENTRIES();
811 return SUCCESS;
812 }
813 /* }}} */
814
815 /* {{{ PHP_MINFO_FUNCTION */
PHP_MINFO_FUNCTION(mecab)816 static PHP_MINFO_FUNCTION(mecab)
817 {
818 php_info_print_table_start();
819 php_info_print_table_row(2, "MeCab Support", "enabled");
820 php_info_print_table_row(2, "Module Version", PHP_MECAB_MODULE_VERSION);
821 php_info_print_table_end();
822
823 php_info_print_table_start();
824 php_info_print_table_header(3, "Version Info", "Compiled", "Linked");
825 php_info_print_table_row(3, "MeCab Library", PHP_MECAB_VERSION_STRING, mecab_version());
826 php_info_print_table_end();
827
828 DISPLAY_INI_ENTRIES();
829 }
830 /* }}} */
831
832 /* {{{ PHP_GINIT_FUNCTION */
PHP_GINIT_FUNCTION(mecab)833 static PHP_GINIT_FUNCTION(mecab)
834 {
835 mecab_globals->default_rcfile = NULL;
836 mecab_globals->default_dicdir = NULL;
837 mecab_globals->default_userdic = NULL;
838 }
839 /* }}} */
840
841 /* {{{ internal function implementation for mecab_t */
842
843 /* {{{ php_mecab_ctor()
844 * allocate for mecab
845 */
846 static php_mecab *
php_mecab_ctor(TSRMLS_D)847 php_mecab_ctor(TSRMLS_D)
848 {
849 php_mecab *mecab = NULL;
850
851 mecab = (php_mecab *)ecalloc(1, sizeof(php_mecab));
852 if (mecab == NULL) {
853 return NULL;
854 }
855
856 mecab->ptr = NULL;
857 mecab->str = NULL;
858 mecab->len = 0;
859 mecab->ref = 1;
860
861 return mecab;
862 }
863 /* }}} */
864
865 /* {{{ php_mecab_dtor()
866 * free the mecab
867 */
868 static void
php_mecab_dtor(php_mecab * mecab TSRMLS_DC)869 php_mecab_dtor(php_mecab *mecab TSRMLS_DC)
870 {
871 mecab->ref--;
872 if (mecab->ref == 0) {
873 if (mecab->str != NULL) {
874 efree(mecab->str);
875 }
876 mecab_destroy(mecab->ptr);
877 efree(mecab);
878 }
879 }
880 /* }}} */
881
882 /* {{{ php_mecab_free_resource()
883 * free the mecab resource
884 */
885 static void
php_mecab_free_resource(zend_rsrc_list_entry * rsrc TSRMLS_DC)886 php_mecab_free_resource(zend_rsrc_list_entry *rsrc TSRMLS_DC)
887 {
888 php_mecab_dtor((php_mecab *)rsrc->ptr TSRMLS_CC);
889 }
890 /* }}} */
891
892 /* {{{ php_mecab_set_string()
893 * set string to the mecab
894 */
895 static void
php_mecab_set_string(php_mecab * mecab,const char * str,int len TSRMLS_DC)896 php_mecab_set_string(php_mecab *mecab, const char *str, int len TSRMLS_DC)
897 {
898 if (mecab->str != NULL) {
899 efree(mecab->str);
900 }
901 if (str == NULL) {
902 mecab->str = NULL;
903 mecab->len = 0;
904 } else {
905 mecab->str = estrndup(str, len);
906 mecab->len = (size_t)len;
907 }
908 }
909 /* }}} */
910
911 /* {{{ php_mecab_object_new()
912 * allocate for mecab object
913 */
914 zend_object_value
php_mecab_object_new(zend_class_entry * ce TSRMLS_DC)915 php_mecab_object_new(zend_class_entry *ce TSRMLS_DC)
916 {
917 zend_object_value retval;
918 php_mecab_object *intern;
919
920 intern = (php_mecab_object *)ecalloc(1, sizeof(php_mecab_object));
921 intern->ptr = php_mecab_ctor(TSRMLS_C);
922
923 zend_object_std_init(&intern->std, ce TSRMLS_CC);
924 object_properties_init(&intern->std, ce);
925
926 retval.handle = zend_objects_store_put(intern,
927 (zend_objects_store_dtor_t)zend_objects_destroy_object,
928 (zend_objects_free_object_storage_t)php_mecab_free_object_storage,
929 NULL TSRMLS_CC);
930 retval.handlers = &php_mecab_object_handlers;
931
932 return retval;
933 }
934 /* }}} */
935
936 /* {{{ php_mecab_free_object_storage()
937 * free the mecab object
938 */
939 static void
php_mecab_free_object_storage(void * object TSRMLS_DC)940 php_mecab_free_object_storage(void *object TSRMLS_DC)
941 {
942 php_mecab_object *intern = (php_mecab_object *)object;
943 php_mecab_dtor(intern->ptr TSRMLS_CC);
944 zend_object_std_dtor(&intern->std TSRMLS_CC);
945 efree(object);
946 }
947 /* }}} */
948
949 /* }}} mecab_t */
950
951 /* {{{ internal function implementation for mecab_node_t */
952
953 /* {{{ php_mecab_node_ctor()
954 * allocate for mecab_node
955 */
956 static php_mecab_node *
php_mecab_node_ctor(TSRMLS_D)957 php_mecab_node_ctor(TSRMLS_D)
958 {
959 php_mecab_node *node = NULL;
960
961 node = (php_mecab_node *)ecalloc(1, sizeof(php_mecab_node));
962 if (node == NULL) {
963 return NULL;
964 }
965
966 node->tagger = NULL;
967 node->ptr = NULL;
968
969 return node;
970 }
971 /* }}} */
972
973 /* {{{ php_mecab_node_dtor()
974 * free the mecab_node
975 */
976 static void
php_mecab_node_dtor(php_mecab_node * node TSRMLS_DC)977 php_mecab_node_dtor(php_mecab_node *node TSRMLS_DC)
978 {
979 if (node->tagger != NULL) {
980 php_mecab_dtor(node->tagger TSRMLS_CC);
981 }
982 efree(node);
983 }
984 /* }}} */
985
986 /* {{{ php_mecab_node_free_resource()
987 * free the mecab_node resource
988 */
989 static void
php_mecab_node_free_resource(zend_rsrc_list_entry * rsrc TSRMLS_DC)990 php_mecab_node_free_resource(zend_rsrc_list_entry *rsrc TSRMLS_DC)
991 {
992 php_mecab_node_dtor((php_mecab_node *)rsrc->ptr TSRMLS_CC);
993 }
994 /* }}} */
995
996 /* {{{ php_mecab_node_set_tagger()
997 * set mecab to the mecab_node
998 */
999 static void
php_mecab_node_set_tagger(php_mecab_node * node,php_mecab * mecab TSRMLS_DC)1000 php_mecab_node_set_tagger(php_mecab_node *node, php_mecab *mecab TSRMLS_DC)
1001 {
1002 if (node->tagger != NULL) {
1003 php_mecab_dtor(node->tagger TSRMLS_CC);
1004 }
1005 if (mecab == NULL) {
1006 node->tagger = NULL;
1007 } else {
1008 node->tagger = mecab;
1009 node->tagger->ref++;
1010 }
1011 }
1012 /* }}} */
1013
1014 /* {{{ php_mecab_node_object_new()
1015 * allocate for mecab_node object
1016 */
1017 zend_object_value
php_mecab_node_object_new(zend_class_entry * ce TSRMLS_DC)1018 php_mecab_node_object_new(zend_class_entry *ce TSRMLS_DC)
1019 {
1020 zend_object_value retval;
1021 php_mecab_node_object *intern;
1022
1023 intern = (php_mecab_node_object *)ecalloc(1, sizeof(php_mecab_node_object));
1024 intern->ptr = php_mecab_node_ctor(TSRMLS_C);
1025 intern->mode = TRAVERSE_NEXT;
1026
1027 zend_object_std_init(&intern->std, ce TSRMLS_CC);
1028 object_properties_init(&intern->std, ce);
1029
1030 retval.handle = zend_objects_store_put(intern,
1031 (zend_objects_store_dtor_t)zend_objects_destroy_object,
1032 (zend_objects_free_object_storage_t)php_mecab_node_free_object_storage,
1033 NULL TSRMLS_CC);
1034 retval.handlers = &php_mecab_node_object_handlers;
1035
1036 return retval;
1037 }
1038 /* }}} */
1039
1040 /* {{{ php_mecab_node_free_object_storage()
1041 * free the mecab_node object
1042 */
1043 static void
php_mecab_node_free_object_storage(void * object TSRMLS_DC)1044 php_mecab_node_free_object_storage(void *object TSRMLS_DC)
1045 {
1046 php_mecab_node_object *intern = (php_mecab_node_object *)object;
1047 php_mecab_node_dtor(intern->ptr TSRMLS_CC);
1048 zend_object_std_dtor(&intern->std TSRMLS_CC);
1049 efree(object);
1050 }
1051 /* }}} */
1052
1053 /* }}} mecab_node_t */
1054
1055 /* {{{ php_mecab_path_ctor()
1056 * allocate for mecab_path
1057 */
1058 static php_mecab_path *
php_mecab_path_ctor(TSRMLS_D)1059 php_mecab_path_ctor(TSRMLS_D)
1060 {
1061 php_mecab_path *path = NULL;
1062
1063 path = (php_mecab_path *)ecalloc(1, sizeof(php_mecab_path));
1064 if (path == NULL) {
1065 return NULL;
1066 }
1067
1068 path->tagger = NULL;
1069 path->ptr = NULL;
1070
1071 return path;
1072 }
1073 /* }}} */
1074
1075 /* {{{ php_mecab_path_dtor()
1076 * free the mecab_path
1077 */
1078 static void
php_mecab_path_dtor(php_mecab_path * path TSRMLS_DC)1079 php_mecab_path_dtor(php_mecab_path *path TSRMLS_DC)
1080 {
1081 if (path->tagger != NULL) {
1082 php_mecab_dtor(path->tagger TSRMLS_CC);
1083 }
1084 efree(path);
1085 }
1086 /* }}} */
1087
1088 /* {{{ php_mecab_path_free_resource()
1089 * free the mecab_path resource
1090 */
1091 static void
php_mecab_path_free_resource(zend_rsrc_list_entry * rsrc TSRMLS_DC)1092 php_mecab_path_free_resource(zend_rsrc_list_entry *rsrc TSRMLS_DC)
1093 {
1094 php_mecab_path_dtor((php_mecab_path *)rsrc->ptr TSRMLS_CC);
1095 }
1096 /* }}} */
1097
1098 /* {{{ php_mecab_path_set_tagger()
1099 * set mecab_node to the mecab_path
1100 */
1101 static void
php_mecab_path_set_tagger(php_mecab_path * path,php_mecab * mecab TSRMLS_DC)1102 php_mecab_path_set_tagger(php_mecab_path *path, php_mecab *mecab TSRMLS_DC)
1103 {
1104 if (path->tagger != NULL) {
1105 php_mecab_dtor(path->tagger TSRMLS_CC);
1106 }
1107 if (mecab == NULL) {
1108 path->tagger = NULL;
1109 } else {
1110 path->tagger = mecab;
1111 path->tagger->ref++;
1112 }
1113 }
1114 /* }}} */
1115
1116 /* {{{ php_mecab_path_object_new()
1117 * allocate for mecab_path object
1118 */
1119 zend_object_value
php_mecab_path_object_new(zend_class_entry * ce TSRMLS_DC)1120 php_mecab_path_object_new(zend_class_entry *ce TSRMLS_DC)
1121 {
1122 zend_object_value retval;
1123 php_mecab_path_object *intern;
1124
1125 intern = (php_mecab_path_object *)ecalloc(1, sizeof(php_mecab_path_object));
1126 intern->ptr = php_mecab_path_ctor(TSRMLS_C);
1127
1128 zend_object_std_init(&intern->std, ce TSRMLS_CC);
1129 object_properties_init(&intern->std, ce);
1130
1131 retval.handle = zend_objects_store_put(intern,
1132 (zend_objects_store_dtor_t)zend_objects_destroy_object,
1133 (zend_objects_free_object_storage_t)php_mecab_path_free_object_storage,
1134 NULL TSRMLS_CC);
1135 retval.handlers = &php_mecab_path_object_handlers;
1136
1137 return retval;
1138 }
1139 /* }}} */
1140
1141 /* {{{ php_mecab_path_free_object_storage()
1142 * free the mecab_path object
1143 */
1144 static void
php_mecab_path_free_object_storage(void * object TSRMLS_DC)1145 php_mecab_path_free_object_storage(void *object TSRMLS_DC)
1146 {
1147 php_mecab_path_object *intern = (php_mecab_path_object *)object;
1148 php_mecab_path_dtor(intern->ptr TSRMLS_CC);
1149 zend_object_std_dtor(&intern->std TSRMLS_CC);
1150 efree(object);
1151 }
1152 /* }}} */
1153
1154 /* }}} mecab_path_t */
1155
1156 /* {{{ php_mecab_node_get_sibling()
1157 * get sibling node from mecab_node
1158 */
1159 static zval *
php_mecab_node_get_sibling(zval * zv,zval * object,php_mecab_node * xnode,php_mecab_node_rel rel TSRMLS_DC)1160 php_mecab_node_get_sibling(zval *zv, zval *object, php_mecab_node *xnode, php_mecab_node_rel rel TSRMLS_DC)
1161 {
1162 const mecab_node_t *node = xnode->ptr;
1163 php_mecab_node *xsbl = NULL;
1164 const mecab_node_t *sbl = NULL;
1165 zval *retval = NULL;
1166
1167 if (zv == NULL) {
1168 MAKE_STD_ZVAL(retval);
1169 } else {
1170 zval_dtor(zv);
1171 retval = zv;
1172 }
1173
1174 /* scan */
1175 if (rel == NODE_PREV) {
1176 sbl = node->prev;
1177 } else if (rel == NODE_NEXT) {
1178 sbl = node->next;
1179 } else if (rel == NODE_ENEXT) {
1180 sbl = node->enext;
1181 } else if (rel == NODE_BNEXT) {
1182 sbl = node->bnext;
1183 } else {
1184 ZVAL_FALSE(retval);
1185 return retval;
1186 }
1187
1188 if (sbl == NULL) {
1189 ZVAL_NULL(retval);
1190 return retval;
1191 }
1192
1193 /* set return value */
1194 if (object) {
1195 php_mecab_node_object *newobj;
1196 object_init_ex(retval, ce_MeCab_Node);
1197 PHP_MECAB_FETCH_OBJECT(newobj, php_mecab_node_object *, retval);
1198 xsbl = newobj->ptr;
1199 } else {
1200 xsbl = php_mecab_node_ctor(TSRMLS_C);
1201 ZEND_REGISTER_RESOURCE(retval, xsbl, le_mecab_node);
1202 }
1203 xsbl->ptr = sbl;
1204 php_mecab_node_set_tagger(xsbl, xnode->tagger TSRMLS_CC);
1205
1206 return retval;
1207 }
1208 /* }}} */
1209
1210 /* {{{ php_mecab_node_get_path()
1211 * get related path from mecab_node
1212 */
1213 static zval *
php_mecab_node_get_path(zval * zv,zval * object,php_mecab_node * xnode,php_mecab_node_rel rel TSRMLS_DC)1214 php_mecab_node_get_path(zval *zv, zval *object, php_mecab_node *xnode, php_mecab_node_rel rel TSRMLS_DC)
1215 {
1216 const mecab_node_t *node = xnode->ptr;
1217 php_mecab_path *xpath = NULL;
1218 const mecab_path_t *path = NULL;
1219 zval *retval = NULL;
1220
1221 if (zv == NULL) {
1222 MAKE_STD_ZVAL(retval);
1223 } else {
1224 zval_dtor(zv);
1225 retval = zv;
1226 }
1227
1228 /* scan */
1229 if (rel == NODE_RPATH) {
1230 path = node->rpath;
1231 } else if (rel == NODE_LPATH) {
1232 path = node->lpath;
1233 } else {
1234 ZVAL_FALSE(retval);
1235 return retval;
1236 }
1237
1238 if (path == NULL) {
1239 ZVAL_NULL(retval);
1240 return retval;
1241 }
1242
1243 /* set return value */
1244 if (object) {
1245 php_mecab_path_object *newobj;
1246 object_init_ex(retval, ce_MeCab_Path);
1247 PHP_MECAB_FETCH_OBJECT(newobj, php_mecab_path_object *, retval);
1248 xpath = newobj->ptr;
1249 } else {
1250 xpath = php_mecab_path_ctor(TSRMLS_C);
1251 ZEND_REGISTER_RESOURCE(retval, xpath, le_mecab_path);
1252 }
1253 xpath->ptr = path;
1254 php_mecab_path_set_tagger(xpath, xnode->tagger TSRMLS_CC);
1255
1256 return retval;
1257 }
1258 /* }}} */
1259
1260 /* {{{ php_mecab_path_get_sibling()
1261 * get sibling path from mecab_path
1262 */
1263 static zval *
php_mecab_path_get_sibling(zval * zv,zval * object,php_mecab_path * xpath,php_mecab_path_rel rel TSRMLS_DC)1264 php_mecab_path_get_sibling(zval *zv, zval *object, php_mecab_path *xpath, php_mecab_path_rel rel TSRMLS_DC)
1265 {
1266 const mecab_path_t *path = xpath->ptr;
1267 php_mecab_path *xsbl = NULL;
1268 const mecab_path_t *sbl = NULL;
1269 zval *retval = NULL;
1270
1271 if (zv == NULL) {
1272 MAKE_STD_ZVAL(retval);
1273 } else {
1274 zval_dtor(zv);
1275 retval = zv;
1276 }
1277
1278 /* scan */
1279 if (rel == PATH_RNEXT) {
1280 sbl = path->rnext;
1281 } else if (rel == PATH_LNEXT) {
1282 sbl = path->lnext;
1283 } else {
1284 ZVAL_FALSE(retval);
1285 return retval;
1286 }
1287
1288 if (sbl == NULL) {
1289 ZVAL_NULL(retval);
1290 return retval;
1291 }
1292
1293 /* set return value */
1294 if (object) {
1295 php_mecab_path_object *newobj;
1296 object_init_ex(retval, ce_MeCab_Path);
1297 PHP_MECAB_FETCH_OBJECT(newobj, php_mecab_path_object *, retval);
1298 xsbl = newobj->ptr;
1299 } else {
1300 xsbl = php_mecab_path_ctor(TSRMLS_C);
1301 ZEND_REGISTER_RESOURCE(retval, xsbl, le_mecab_path);
1302 }
1303 xsbl->ptr = sbl;
1304 php_mecab_path_set_tagger(xsbl, xpath->tagger TSRMLS_CC);
1305
1306 return retval;
1307 }
1308 /* }}} */
1309
1310 /* {{{ php_mecab_path_get_node()
1311 * get related node from mecab_path
1312 */
1313 static zval *
php_mecab_path_get_node(zval * zv,zval * object,php_mecab_path * xpath,php_mecab_path_rel rel TSRMLS_DC)1314 php_mecab_path_get_node(zval *zv, zval *object, php_mecab_path *xpath, php_mecab_path_rel rel TSRMLS_DC)
1315 {
1316 const mecab_path_t *path = xpath->ptr;
1317 php_mecab_node *xnode = NULL;
1318 const mecab_node_t *node = NULL;
1319 zval *retval = NULL;
1320
1321 if (zv == NULL) {
1322 MAKE_STD_ZVAL(retval);
1323 } else {
1324 zval_dtor(zv);
1325 retval = zv;
1326 }
1327
1328 /* scan */
1329 if (rel == PATH_RNODE) {
1330 node = path->rnode;
1331 } else if (rel == PATH_LNODE) {
1332 node = path->lnode;
1333 } else {
1334 ZVAL_FALSE(retval);
1335 return retval;
1336 }
1337
1338 if (node == NULL) {
1339 ZVAL_NULL(retval);
1340 return retval;
1341 }
1342
1343 /* set return value */
1344 if (object) {
1345 php_mecab_node_object *newobj;
1346 object_init_ex(retval, ce_MeCab_Node);
1347 PHP_MECAB_FETCH_OBJECT(newobj, php_mecab_node_object *, retval);
1348 xnode = newobj->ptr;
1349 } else {
1350 xnode = php_mecab_node_ctor(TSRMLS_C);
1351 ZEND_REGISTER_RESOURCE(retval, xnode, le_mecab_node);
1352 }
1353 xnode->ptr = node;
1354 php_mecab_node_set_tagger(xnode, xpath->tagger TSRMLS_CC);
1355
1356 return retval;
1357 }
1358 /* }}} */
1359
1360 /* {{{ php_mecab_node_get_sibling_wrapper()
1361 * wraps php_mecab_node_get_sibling()
1362 */
1363 static void
php_mecab_node_get_sibling_wrapper(INTERNAL_FUNCTION_PARAMETERS,php_mecab_node_rel rel)1364 php_mecab_node_get_sibling_wrapper(INTERNAL_FUNCTION_PARAMETERS, php_mecab_node_rel rel)
1365 {
1366 /* declaration of the resources */
1367 zval *object = getThis();
1368 zval *znode = NULL;
1369 php_mecab_node *xnode = NULL;
1370
1371 /* parse the arguments */
1372 PHP_MECAB_NODE_INTERNAL_FROM_PARAMETER();
1373
1374 php_mecab_node_get_sibling(return_value, object, xnode, rel TSRMLS_CC);
1375 }
1376 /* }}} */
1377
1378 /* {{{ php_mecab_node_get_path_wrapper()
1379 * wraps php_mecab_node_get_path()
1380 */
1381 static void
php_mecab_node_get_path_wrapper(INTERNAL_FUNCTION_PARAMETERS,php_mecab_node_rel rel)1382 php_mecab_node_get_path_wrapper(INTERNAL_FUNCTION_PARAMETERS, php_mecab_node_rel rel)
1383 {
1384 /* declaration of the resources */
1385 zval *object = getThis();
1386 zval *znode = NULL;
1387 php_mecab_node *xnode = NULL;
1388
1389 /* parse the arguments */
1390 PHP_MECAB_NODE_INTERNAL_FROM_PARAMETER();
1391
1392 php_mecab_node_get_path(return_value, object, xnode, rel TSRMLS_CC);
1393 }
1394 /* }}} */
1395
1396 /* {{{ php_mecab_path_get_sibling_wrapper()
1397 * wraps php_mecab_path_get_sibling()
1398 */
1399 static void
php_mecab_path_get_sibling_wrapper(INTERNAL_FUNCTION_PARAMETERS,php_mecab_path_rel rel)1400 php_mecab_path_get_sibling_wrapper(INTERNAL_FUNCTION_PARAMETERS, php_mecab_path_rel rel)
1401 {
1402 /* declaration of the resources */
1403 zval *object = getThis();
1404 zval *zpath = NULL;
1405 php_mecab_path *xpath = NULL;
1406
1407 /* parse the arguments */
1408 PHP_MECAB_PATH_INTERNAL_FROM_PARAMETER();
1409
1410 php_mecab_path_get_sibling(return_value, object, xpath, rel TSRMLS_CC);
1411 }
1412 /* }}} */
1413
1414 /* {{{ php_mecab_path_get_node_wrapper()
1415 * wraps php_mecab_path_get_path()
1416 */
1417 static void
php_mecab_path_get_node_wrapper(INTERNAL_FUNCTION_PARAMETERS,php_mecab_path_rel rel)1418 php_mecab_path_get_node_wrapper(INTERNAL_FUNCTION_PARAMETERS, php_mecab_path_rel rel)
1419 {
1420 /* declaration of the resources */
1421 zval *object = getThis();
1422 zval *zpath = NULL;
1423 php_mecab_path *xpath = NULL;
1424
1425 /* parse the arguments */
1426 PHP_MECAB_PATH_INTERNAL_FROM_PARAMETER();
1427
1428 php_mecab_path_get_node(return_value, object, xpath, rel TSRMLS_CC);
1429 }
1430 /* }}} */
1431
1432 /* {{{ php_mecab_get_class_entry()
1433 * get the class entry
1434 */
1435 static zend_class_entry *
php_mecab_get_class_entry(const char * lcname TSRMLS_DC)1436 php_mecab_get_class_entry(const char *lcname TSRMLS_DC)
1437 {
1438 zend_class_entry **pce;
1439 if (zend_hash_find(CG(class_table), lcname, strlen(lcname) + 1, (void **)&pce) == SUCCESS) {
1440 return *pce;
1441 } else {
1442 return NULL;
1443 }
1444 }
1445 /* }}} */
1446
1447 /* {{{ php_mecab_node_list_method()
1448 * check file/dicectory accessibility
1449 */
1450 static zend_bool
php_mecab_check_path(const char * path,size_t length,char * real_path TSRMLS_DC)1451 php_mecab_check_path(const char *path, size_t length, char *real_path TSRMLS_DC)
1452 {
1453 char *full_path;
1454
1455 if (strlen(path) != length ||
1456 (full_path = expand_filepath(path, real_path TSRMLS_CC)) == NULL)
1457 {
1458 return 0;
1459 }
1460
1461 if (VCWD_ACCESS(full_path, F_OK) != 0 ||
1462 VCWD_ACCESS(full_path, R_OK) != 0 ||
1463 php_check_open_basedir(full_path TSRMLS_CC))
1464 {
1465 if (real_path == NULL) {
1466 efree(full_path);
1467 }
1468 return 0;
1469 }
1470
1471 #if !defined(PHP_VERSION_ID) || PHP_VERSION_ID < 50400
1472 if (PG(safe_mode) && !php_checkuid(full_path, NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
1473 if (real_path == NULL) {
1474 efree(full_path);
1475 }
1476 return 0;
1477 }
1478 #endif
1479
1480 if (real_path == NULL) {
1481 efree(full_path);
1482 }
1483 return 1;
1484 }
1485 /* }}} */
1486
1487 /* {{{ macro for checking constructor options */
1488
1489 /* check if default parameter is set */
1490 #define PHP_MECAB_CHECK_DEFAULT(name) \
1491 (MECAB_G(default_##name) != NULL && MECAB_G(default_##name)[0] != '\0')
1492
1493 #define PHP_MECAB_GETOPT_FAILURE -1
1494 #define PHP_MECAB_GETOPT_SUCCESS 0
1495 #define PHP_MECAB_GETOPT_FLAG_EXPECTED (1 << 0)
1496 #define PHP_MECAB_GETOPT_RCFILE_EXPECTED (1 << 2)
1497 #define PHP_MECAB_GETOPT_DICDIR_EXPECTED (1 << 3)
1498 #define PHP_MECAB_GETOPT_USERDIC_EXPECTED (1 << 4)
1499 #define PHP_MECAB_GETOPT_PATH_EXPECTED \
1500 (PHP_MECAB_GETOPT_RCFILE_EXPECTED | PHP_MECAB_GETOPT_DICDIR_EXPECTED | PHP_MECAB_GETOPT_USERDIC_EXPECTED)
1501
1502 /* check for option */
1503 static int
php_mecab_check_option(const char * option)1504 php_mecab_check_option(const char *option)
1505 {
1506 /* not an option */
1507 if (*option != '-') {
1508 return PHP_MECAB_GETOPT_FAILURE;
1509 }
1510
1511 /* resource file */
1512 if (!strcmp(option, "-r") || !strcmp(option, "--rcfile")) {
1513 return PHP_MECAB_GETOPT_RCFILE_EXPECTED;
1514 }
1515
1516 /* system dicdir */
1517 if (!strcmp(option, "-d") || !strcmp(option, "--dicdir")) {
1518 return PHP_MECAB_GETOPT_DICDIR_EXPECTED;
1519 }
1520
1521 /* user dictionary */
1522 if (!strcmp(option, "-u") || !strcmp(option, "--userdic")) {
1523 return PHP_MECAB_GETOPT_USERDIC_EXPECTED;
1524 }
1525
1526 /* options whose parameter is not filename */
1527 if (!strcmp(option, "-l") || !strcmp(option, "--lattice-level") ||
1528 !strcmp(option, "-O") || !strcmp(option, "--output-format-type") ||
1529 !strcmp(option, "-F") || !strcmp(option, "--node-format") ||
1530 !strcmp(option, "-U") || !strcmp(option, "--unk-format") ||
1531 !strcmp(option, "-B") || !strcmp(option, "--bos-format") ||
1532 !strcmp(option, "-E") || !strcmp(option, "--eos-format") ||
1533 !strcmp(option, "-x") || !strcmp(option, "--unk-feature") ||
1534 !strcmp(option, "-b") || !strcmp(option, "--input-buffer-size") ||
1535 !strcmp(option, "-N") || !strcmp(option, "--nbest") ||
1536 !strcmp(option, "-t") || !strcmp(option, "--theta"))
1537 {
1538 return PHP_MECAB_GETOPT_SUCCESS;
1539 }
1540
1541 /* options which does not have parameter */
1542 if (!strcmp(option, "-a") || !strcmp(option, "--all-morphs") ||
1543 !strcmp(option, "-p") || !strcmp(option, "--partial") ||
1544 !strcmp(option, "-C") || !strcmp(option, "--allocate-sentence"))
1545 {
1546 return (PHP_MECAB_GETOPT_SUCCESS | PHP_MECAB_GETOPT_FLAG_EXPECTED);
1547 }
1548
1549 /* invalid options */
1550 return PHP_MECAB_GETOPT_FAILURE;
1551 }
1552
1553 /* check for open_basedir and safe_mode */
1554 #define PHP_MECAB_CHECK_FILE(path, length) \
1555 { \
1556 if (!php_mecab_check_path((path), (length), resolved_path TSRMLS_CC)) { \
1557 efree(argv); \
1558 php_error_docref(NULL TSRMLS_CC, E_WARNING, "'%s' does not exist or is not readable", (path)); \
1559 RETURN_FALSE; \
1560 } \
1561 flag_expected = 1; \
1562 path_expected = 0; \
1563 }
1564
1565 /* }}} */
1566
1567 /* {{{ Functions */
1568
1569 /* {{{ proto string mecab_version(void) */
1570 /**
1571 * string mecab_version(void)
1572 *
1573 * Get the version number of MeCab.
1574 *
1575 * @return string The version of linked MeCab library.
1576 */
PHP_FUNCTION(mecab_version)1577 static PHP_FUNCTION(mecab_version)
1578 {
1579 if (ZEND_NUM_ARGS() != 0) {
1580 WRONG_PARAM_COUNT;
1581 }
1582 RETURN_STRING((char *)mecab_version(), 1);
1583 }
1584 /* }}} mecab_version */
1585
1586 /* {{{ proto array mecab_split(string str[, string dicdir[, string userdic]]) */
1587 /**
1588 * array mecab_split(string str[, string dicdir[, string userdic]])
1589 * array MeCab_Tagger::split(string str[, string dicdir[, string userdic]])
1590 *
1591 * Split string into an array of morphemes.
1592 *
1593 * @param string $str The target string.
1594 * @param string $dicdir The path for system dictionary.
1595 * @param string $userdic The path for user dictionary.
1596 * @return array
1597 */
PHP_FUNCTION(mecab_split)1598 static PHP_FUNCTION(mecab_split)
1599 {
1600 /* variables from argument */
1601 const char *str = NULL;
1602 int str_len = 0;
1603 const char *dicdir = NULL;
1604 int dicdir_len = 0;
1605 const char *userdic = NULL;
1606 int userdic_len = 0;
1607
1608 /* local variables */
1609 mecab_t *mecab = NULL;
1610 const mecab_node_t *node = NULL;
1611 int argc = 2;
1612 char *argv[5] = { "mecab", "-Owakati", NULL, NULL, NULL };
1613 char pathbuf[2][PATHBUFSIZE] = {{'\0'}};
1614 char *dicdir_buf = &(pathbuf[0][0]);
1615 char *userdic_buf = &(pathbuf[1][0]);
1616
1617 /* parse arguments */
1618 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!s!",
1619 &str, &str_len, &dicdir, &dicdir_len, &userdic, &userdic_len) == FAILURE)
1620 {
1621 return;
1622 }
1623
1624 /* apply default options */
1625 if (dicdir_len == 0 && PHP_MECAB_CHECK_DEFAULT(dicdir)) {
1626 dicdir = MECAB_G(default_dicdir);
1627 dicdir_len = (int)strlen(MECAB_G(default_dicdir));
1628 }
1629 if (dicdir_len == 0 && PHP_MECAB_CHECK_DEFAULT(userdic)) {
1630 userdic = MECAB_G(default_userdic);
1631 userdic_len = (int)strlen(MECAB_G(default_userdic));
1632 }
1633
1634 /* check for dictionary */
1635 if (dicdir != NULL && dicdir_len > 0) {
1636 char *dicdir_ptr = dicdir_buf;
1637 *dicdir_ptr++ = '-';
1638 *dicdir_ptr++ = 'd';
1639 if (!php_mecab_check_path(dicdir, dicdir_len, dicdir_ptr TSRMLS_CC)) {
1640 php_error_docref(NULL TSRMLS_CC, E_WARNING,
1641 "'%s' does not exist or is not readable", dicdir);
1642 RETURN_FALSE;
1643 }
1644 argv[argc++] = dicdir_buf;
1645 }
1646 if (userdic != NULL && userdic_len > 0) {
1647 char *userdic_ptr = userdic_buf;
1648 *userdic_ptr++ = '-';
1649 *userdic_ptr++ = 'u';
1650 if (!php_mecab_check_path(userdic, userdic_len, userdic_ptr TSRMLS_CC)) {
1651 php_error_docref(NULL TSRMLS_CC, E_WARNING,
1652 "'%s' does not exist or is not readable", userdic);
1653 RETURN_FALSE;
1654 }
1655 argv[argc++] = userdic_buf;
1656 }
1657
1658 /* create mecab object */
1659 mecab = mecab_new(argc, argv);
1660
1661 /* on error */
1662 if (mecab == NULL) {
1663 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mecab_strerror(NULL));
1664 RETURN_FALSE;
1665 }
1666
1667 /* parse the string */
1668 node = mecab_sparse_tonode(mecab, str);
1669 if (node == NULL) {
1670 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mecab_strerror(mecab));
1671 mecab_destroy(mecab);
1672 RETURN_FALSE;
1673 }
1674
1675 /* initialize */
1676 array_init(return_value);
1677
1678 /* put surfaces of each node to return value */
1679 while (node != NULL) {
1680 if (node->length > 0) {
1681 add_next_index_stringl(return_value, (char *)node->surface, (int)node->length, 1);
1682 }
1683 node = node->next;
1684 }
1685
1686 /* free mecab object */
1687 mecab_destroy(mecab);
1688 }
1689 /* }}} mecab_split */
1690
1691 /* {{{ proto resource mecab mecab_new([array options]) */
1692 /**
1693 * resource mecab mecab_new([array options])
1694 * object MeCab_Tagger MeCab_Tagger::__construct([array options])
1695 *
1696 * Create new tagger resource of MeCab.
1697 *
1698 * @param array $options The analysis/output options. (optional)
1699 * The values are same to command line options.
1700 * The detail is found in the web site and/or the manpage of MeCab.
1701 * @return resource mecab A tagger resource of MeCab.
1702 */
PHP_FUNCTION(mecab_new)1703 static PHP_FUNCTION(mecab_new)
1704 {
1705 /* declaration of the resources */
1706 zval *object = getThis();
1707 php_mecab *xmecab = NULL;
1708 mecab_t *mecab = NULL;
1709
1710 /* declaration of the arguments */
1711 zval *zoptions = NULL;
1712 HashTable *options = NULL;
1713
1714 /* declaration of the local variables */
1715 size_t min_argc = 5; /* "mecab" + "-r" + "-d" + "-u" + NULL */
1716 int argc = 1;
1717 char **argv = NULL;
1718 int flag_expected = 1;
1719 int path_expected = 0;
1720 char pathbuf[3][PATHBUFSIZE] = {{'\0'}};
1721 char *rcfile_buf = &(pathbuf[0][0]);
1722 char *dicdir_buf = &(pathbuf[1][0]);
1723 char *userdic_buf = &(pathbuf[2][0]);
1724 char *resolved_path = NULL;
1725
1726 /* parse arguments */
1727 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &zoptions) == FAILURE) {
1728 return;
1729 }
1730
1731 /* parse options */
1732 if (zoptions != NULL) {
1733 int getopt_result = 0;
1734 char *key;
1735 uint len;
1736 ulong idx;
1737 zval **entry;
1738
1739 ALLOC_HASHTABLE(options);
1740
1741 zend_hash_init(options, zend_hash_num_elements(Z_ARRVAL_P(zoptions)), NULL, ZVAL_PTR_DTOR, 0);
1742 zend_hash_copy(options, Z_ARRVAL_P(zoptions), (copy_ctor_func_t)zval_add_ref, NULL, sizeof(zval *));
1743
1744 argv = (char **)ecalloc(2 * zend_hash_num_elements(options) + min_argc, sizeof(char *));
1745
1746 while (zend_hash_get_current_data(options, (void **)&entry) == SUCCESS) {
1747 convert_to_string_ex(entry);
1748
1749 switch (zend_hash_get_current_key_ex(options, &key, &len, &idx, 0, NULL)) {
1750 case HASH_KEY_IS_STRING:
1751 getopt_result = php_mecab_check_option(key);
1752 if (getopt_result == FAILURE) {
1753 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid option '%s' given", key);
1754 efree(argv);
1755 RETURN_FALSE;
1756 } else {
1757 flag_expected = getopt_result & PHP_MECAB_GETOPT_FLAG_EXPECTED;
1758 path_expected = getopt_result & PHP_MECAB_GETOPT_PATH_EXPECTED;
1759 if (getopt_result & PHP_MECAB_GETOPT_RCFILE_EXPECTED) {
1760 resolved_path = rcfile_buf;
1761 } else if (getopt_result & PHP_MECAB_GETOPT_DICDIR_EXPECTED) {
1762 resolved_path = dicdir_buf;
1763 } else if (getopt_result & PHP_MECAB_GETOPT_USERDIC_EXPECTED) {
1764 resolved_path = userdic_buf;
1765 }
1766 }
1767 argv[argc++] = key;
1768 if (path_expected) {
1769 PHP_MECAB_CHECK_FILE(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry));
1770 argv[argc++] = resolved_path;
1771 } else {
1772 argv[argc++] = Z_STRVAL_PP(entry);
1773 }
1774 flag_expected = 1;
1775 path_expected = 0;
1776 break;
1777
1778 case HASH_KEY_IS_LONG:
1779 if (flag_expected) {
1780 getopt_result = php_mecab_check_option(Z_STRVAL_PP(entry));
1781 if (getopt_result == FAILURE) {
1782 php_error_docref(NULL TSRMLS_CC, E_WARNING,
1783 "Invalid option '%s' given", Z_STRVAL_PP(entry));
1784 efree(argv);
1785 RETURN_FALSE;
1786 } else {
1787 flag_expected = getopt_result & PHP_MECAB_GETOPT_FLAG_EXPECTED;
1788 path_expected = getopt_result & PHP_MECAB_GETOPT_PATH_EXPECTED;
1789 if (getopt_result & PHP_MECAB_GETOPT_RCFILE_EXPECTED) {
1790 resolved_path = rcfile_buf;
1791 } else if (getopt_result & PHP_MECAB_GETOPT_DICDIR_EXPECTED) {
1792 resolved_path = dicdir_buf;
1793 } else if (getopt_result & PHP_MECAB_GETOPT_USERDIC_EXPECTED) {
1794 resolved_path = userdic_buf;
1795 }
1796 }
1797 argv[argc++] = Z_STRVAL_PP(entry);
1798 } else if (path_expected) {
1799 PHP_MECAB_CHECK_FILE(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry));
1800 argv[argc++] = resolved_path;
1801 } else {
1802 argv[argc++] = Z_STRVAL_PP(entry);
1803 }
1804 break;
1805 }
1806
1807 zend_hash_move_forward(options);
1808 }
1809 } else {
1810 argv = (char **)ecalloc(min_argc, sizeof(char *));
1811 }
1812
1813 /* apply default options */
1814 if (rcfile_buf[0] == '\0' && PHP_MECAB_CHECK_DEFAULT(rcfile)) {
1815 size_t rcfile_len = strlen(MECAB_G(default_rcfile));
1816 resolved_path = rcfile_buf;
1817 *resolved_path++ = '-';
1818 *resolved_path++ = 'r';
1819 PHP_MECAB_CHECK_FILE(MECAB_G(default_rcfile), rcfile_len);
1820 argv[argc++] = rcfile_buf;
1821 }
1822 if (dicdir_buf[0] == '\0' && PHP_MECAB_CHECK_DEFAULT(dicdir)) {
1823 size_t dicdir_len = strlen(MECAB_G(default_dicdir));
1824 resolved_path = dicdir_buf;
1825 *resolved_path++ = '-';
1826 *resolved_path++ = 'd';
1827 PHP_MECAB_CHECK_FILE(MECAB_G(default_dicdir), dicdir_len);
1828 argv[argc++] = dicdir_buf;
1829 }
1830 if (userdic_buf[0] == '\0' && PHP_MECAB_CHECK_DEFAULT(userdic)) {
1831 size_t userdic_len = strlen(MECAB_G(default_userdic));
1832 resolved_path = userdic_buf;
1833 *resolved_path++ = '-';
1834 *resolved_path++ = 'u';
1835 PHP_MECAB_CHECK_FILE(MECAB_G(default_userdic), userdic_len);
1836 argv[argc++] = userdic_buf;
1837 }
1838
1839 /* create mecab object */
1840 argv[0] = "mecab";
1841 argv[argc] = NULL;
1842 mecab = mecab_new(argc, argv);
1843
1844 efree(argv);
1845 if (options != NULL) {
1846 zend_hash_destroy(options);
1847 FREE_HASHTABLE(options);
1848 }
1849
1850 /* on error */
1851 if (mecab == NULL) {
1852 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mecab_strerror(NULL));
1853 RETURN_FALSE;
1854 }
1855
1856 if (object) {
1857 php_mecab_object *intern;
1858 PHP_MECAB_FETCH_OBJECT(intern, php_mecab_object *, object);
1859 xmecab = intern->ptr;
1860 if (xmecab->ptr != NULL) {
1861 mecab_destroy(mecab);
1862 zend_throw_exception(ext_ce_BadMethodCallException,
1863 "MeCab already initialized", 0 TSRMLS_CC);
1864 return;
1865 }
1866 } else {
1867 xmecab = php_mecab_ctor(TSRMLS_C);
1868 ZEND_REGISTER_RESOURCE(return_value, xmecab, le_mecab);
1869 }
1870 xmecab->ptr = mecab;
1871 }
1872 /* }}} mecab_new */
1873
1874 /* {{{ proto void mecab_destroy(resource mecab mecab) */
1875 /**
1876 * void mecab mecab_destroy(resource mecab mecab)
1877 *
1878 * Free the tagger.
1879 *
1880 * @param resource mecab $mecab The tagger resource of MeCab.
1881 * @return void
1882 */
PHP_FUNCTION(mecab_destroy)1883 static PHP_FUNCTION(mecab_destroy)
1884 {
1885 /* declaration of the arguments */
1886 zval *zmecab = NULL;
1887 php_mecab *mecab = NULL;
1888
1889 /* parse the arguments */
1890 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zmecab) == FAILURE) {
1891 return;
1892 }
1893 ZEND_FETCH_RESOURCE(mecab, php_mecab *, &zmecab, -1, "mecab", le_mecab);
1894
1895 /* free the resource */
1896 FREE_RESOURCE(zmecab);
1897 }
1898 /* }}} mecab_destroy */
1899
1900 /* {{{ proto bool mecab_get_partial(resource mecab mecab) */
1901 /**
1902 * bool mecab_get_partial(resource mecab mecab)
1903 * bool MeCab_Tagger::getPartial()
1904 *
1905 * Get partial parsing mode.
1906 *
1907 * @param resource mecab $mecab The tagger resource of MeCab.
1908 * @return bool
1909 */
PHP_FUNCTION(mecab_get_partial)1910 static PHP_FUNCTION(mecab_get_partial)
1911 {
1912 /* declaration of the resources */
1913 zval *object = getThis();
1914 zval *zmecab = NULL;
1915 php_mecab *xmecab = NULL;
1916 mecab_t *mecab = NULL;
1917
1918 /* parse the arguments */
1919 PHP_MECAB_FROM_PARAMETER();
1920
1921 RETURN_BOOL(mecab_get_partial(mecab))
1922 }
1923 /* }}} */
1924
1925 /* {{{ proto void mecab_set_partial(resource mecab mecab, bool partial) */
1926 /**
1927 * void mecab_set_partial(resource mecab mecab, bool partial)
1928 * void MeCab_Tagger::setPartial(bool partial)
1929 *
1930 * Set partial parsing mode.
1931 *
1932 * @param resource mecab $mecab The tagger resource of MeCab.
1933 * @param bool $partial The partial parsing mode.
1934 * @return void
1935 */
PHP_FUNCTION(mecab_set_partial)1936 static PHP_FUNCTION(mecab_set_partial)
1937 {
1938 /* declaration of the resources */
1939 zval *object = getThis();
1940 zval *zmecab = NULL;
1941 php_mecab *xmecab = NULL;
1942 mecab_t *mecab = NULL;
1943
1944 /* declaration of the arguments */
1945 zend_bool partial = 0;
1946
1947 /* parse the arguments */
1948 PHP_MECAB_PARSE_PARAMETERS("b", &partial);
1949
1950 mecab_set_partial(mecab, (int)partial);
1951 }
1952 /* }}} */
1953
1954 /* {{{ proto float mecab_get_theta(resource mecab mecab) */
1955 /**
1956 * float mecab_get_theta(resource mecab mecab)
1957 * float MeCab_Tagger::getTheta()
1958 *
1959 * Get temparature parameter theta.
1960 *
1961 * @param resource mecab $mecab The tagger resource of MeCab.
1962 * @return float
1963 */
PHP_FUNCTION(mecab_get_theta)1964 static PHP_FUNCTION(mecab_get_theta)
1965 {
1966 /* declaration of the resources */
1967 zval *object = getThis();
1968 zval *zmecab = NULL;
1969 php_mecab *xmecab = NULL;
1970 mecab_t *mecab = NULL;
1971
1972 /* parse the arguments */
1973 PHP_MECAB_FROM_PARAMETER();
1974
1975 RETURN_DOUBLE((double)mecab_get_theta(mecab))
1976 }
1977 /* }}} */
1978
1979 /* {{{ proto void mecab_(resource mecab mecab, float theta) */
1980 /**
1981 * void mecab_set_theta(resource mecab mecab, float theta)
1982 * void MeCab_Tagger::setTheta(float theta)
1983 *
1984 * Set temparature parameter theta.
1985 *
1986 * @param resource mecab $mecab The tagger resource of MeCab.
1987 * @param float $theta The temparature parameter theta.
1988 * @return void
1989 */
PHP_FUNCTION(mecab_set_theta)1990 static PHP_FUNCTION(mecab_set_theta)
1991 {
1992 /* declaration of the resources */
1993 zval *object = getThis();
1994 zval *zmecab = NULL;
1995 php_mecab *xmecab = NULL;
1996 mecab_t *mecab = NULL;
1997
1998 /* declaration of the arguments */
1999 double theta = 0;
2000
2001 /* parse the arguments */
2002 PHP_MECAB_PARSE_PARAMETERS("d", &theta);
2003
2004 mecab_set_theta(mecab, (float)theta);
2005 }
2006 /* }}} */
2007
2008 /* {{{ proto int mecab_get_lattice_level(resource mecab mecab) */
2009 /**
2010 * int mecab_get_lattice_level(resource mecab mecab)
2011 * int MeCab_Tagger::getLatticeLevel()
2012 *
2013 * Get lattice information level.
2014 *
2015 * @param resource mecab $mecab The tagger resource of MeCab.
2016 * @return int
2017 */
PHP_FUNCTION(mecab_get_lattice_level)2018 static PHP_FUNCTION(mecab_get_lattice_level)
2019 {
2020 /* declaration of the resources */
2021 zval *object = getThis();
2022 zval *zmecab = NULL;
2023 php_mecab *xmecab = NULL;
2024 mecab_t *mecab = NULL;
2025
2026 /* parse the arguments */
2027 PHP_MECAB_FROM_PARAMETER();
2028
2029 RETURN_LONG((long)mecab_get_lattice_level(mecab))
2030 }
2031 /* }}} */
2032
2033 /* {{{ proto void mecab_set_lattice_level(resource mecab mecab, int level) */
2034 /**
2035 * void mecab_set_lattice_level(resource mecab mecab, int level)
2036 * void MeCab_Tagger::setLatticeLevel(int level)
2037 *
2038 * Set lattice information level.
2039 *
2040 * @param resource mecab $mecab The tagger resource of MeCab.
2041 * @param int $level The lattice information level.
2042 * @return void
2043 */
PHP_FUNCTION(mecab_set_lattice_level)2044 static PHP_FUNCTION(mecab_set_lattice_level)
2045 {
2046 /* declaration of the resources */
2047 zval *object = getThis();
2048 zval *zmecab = NULL;
2049 php_mecab *xmecab = NULL;
2050 mecab_t *mecab = NULL;
2051
2052 /* declaration of the arguments */
2053 long level = 0L;
2054
2055 /* parse the arguments */
2056 PHP_MECAB_PARSE_PARAMETERS("l", &level);
2057
2058 mecab_set_lattice_level(mecab, (int)level);
2059 }
2060 /* }}} */
2061
2062 /* {{{ proto bool mecab_get_all_morphs(resource mecab mecab) */
2063 /**
2064 * bool mecab_get_all_morphs(resource mecab mecab)
2065 * bool MeCab_Tagger::getAllMorphs()
2066 *
2067 * Get all morphs mode.
2068 *
2069 * @param resource mecab $mecab The tagger resource of MeCab.
2070 * @return bool
2071 */
PHP_FUNCTION(mecab_get_all_morphs)2072 static PHP_FUNCTION(mecab_get_all_morphs)
2073 {
2074 /* declaration of the resources */
2075 zval *object = getThis();
2076 zval *zmecab = NULL;
2077 php_mecab *xmecab = NULL;
2078 mecab_t *mecab = NULL;
2079
2080 /* parse the arguments */
2081 PHP_MECAB_FROM_PARAMETER();
2082
2083 RETURN_BOOL(mecab_get_all_morphs(mecab))
2084 }
2085 /* }}} */
2086
2087 /* {{{ proto void mecab_set_all_morphs(resource mecab mecab, int all_morphs) */
2088 /**
2089 * void mecab_set_all_morphs(resource mecab mecab, int all_morphs)
2090 * void MeCab_Tagger::setAllMorphs(int all_morphs)
2091 *
2092 * Set all morphs mode.
2093 *
2094 * @param resource mecab $mecab The tagger resource of MeCab.
2095 * @param bool $all_morphs The all morphs mode.
2096 * @return void
2097 */
PHP_FUNCTION(mecab_set_all_morphs)2098 static PHP_FUNCTION(mecab_set_all_morphs)
2099 {
2100 /* declaration of the resources */
2101 zval *object = getThis();
2102 zval *zmecab = NULL;
2103 php_mecab *xmecab = NULL;
2104 mecab_t *mecab = NULL;
2105
2106 /* declaration of the arguments */
2107 zend_bool all_morphs = 0;
2108
2109 /* parse the arguments */
2110 PHP_MECAB_PARSE_PARAMETERS("b", &all_morphs);
2111
2112 mecab_set_all_morphs(mecab, (int)all_morphs);
2113 }
2114 /* }}} */
2115
2116 /* {{{ proto string mecab_sparse_tostr(resource mecab mecab, string str[, int len[, int olen]]) */
2117 /**
2118 * string mecab_sparse_tostr(resource mecab mecab, string str[, int len[, int olen]])
2119 * string MeCab_Tagger::parse(string str[, int len[, int olen]])
2120 * string MeCab_Tagger::parseToString(string str[, int len[, int olen]])
2121 *
2122 * Get the parse result as a string.
2123 *
2124 * @param resource mecab $mecab The tagger resource of MeCab.
2125 * @param string $str The parse target.
2126 * @param int $len The maximum length that can be analyzed. (optional)
2127 * @param int $olen The limit length of the output buffer. (optional)
2128 * @return string The parse result.
2129 * If output buffer has overflowed, returns false.
2130 */
PHP_FUNCTION(mecab_sparse_tostr)2131 static PHP_FUNCTION(mecab_sparse_tostr)
2132 {
2133 /* declaration of the resources */
2134 zval *object = getThis();
2135 zval *zmecab = NULL;
2136 php_mecab *xmecab = NULL;
2137 mecab_t *mecab = NULL;
2138
2139 /* declaration of the arguments */
2140 const char *str = NULL;
2141 int str_len = 0;
2142 long len = 0;
2143 long olen = 0;
2144
2145 /* declaration of the local variables */
2146 size_t ilen = 0;
2147 char *ostr = NULL;
2148 zend_bool ostr_free = 0;
2149
2150 /* parse the arguments */
2151 PHP_MECAB_PARSE_PARAMETERS("s|ll", &str, &str_len, &len, &olen);
2152
2153 /* call mecab_sparse_tostr() */
2154 php_mecab_set_string(xmecab, str, str_len TSRMLS_CC);
2155 ilen = (size_t)((len > 0) ? MIN(len, (long)str_len) : str_len);
2156 if (olen == 0) {
2157 ostr = (char *)mecab_sparse_tostr2(mecab, xmecab->str, ilen);
2158 } else {
2159 ostr = (char *)emalloc((size_t)olen + 1);
2160 ostr = mecab_sparse_tostr3(mecab, xmecab->str, ilen, ostr, (size_t)olen);
2161 ostr_free = 1;
2162 }
2163
2164 /* set return value */
2165 if (ostr == NULL) {
2166 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mecab_strerror(mecab));
2167 RETVAL_FALSE;
2168 } else {
2169 RETVAL_STRING(ostr, 1);
2170 }
2171
2172 /* free */
2173 if (ostr_free) {
2174 efree(ostr);
2175 }
2176 }
2177 /* }}} mecab_sparse_tostr */
2178
2179 /* {{{ proto resource mecab_node mecab_sparse_tonode(resource mecab mecab, string str[, int len]) */
2180 /**
2181 * resource mecab_node mecab_sparse_tonode(resource mecab mecab, string str[, int len])
2182 * object MeCab_Node MeCab_Tagger::parseToNode(string str[, int len])
2183 *
2184 * Get the parse result as a node.
2185 *
2186 * @param resource mecab $mecab The tagger resource of MeCab.
2187 * @param string $str The parse target.
2188 * @param int $len The maximum length that can be analyzed. (optional)
2189 * @return resource mecab_node The result node of given string.
2190 */
PHP_FUNCTION(mecab_sparse_tonode)2191 static PHP_FUNCTION(mecab_sparse_tonode)
2192 {
2193 /* declaration of the resources */
2194 zval *object = getThis();
2195 zval *zmecab = NULL;
2196 php_mecab *xmecab = NULL;
2197 mecab_t *mecab = NULL;
2198
2199 /* declaration of the arguments */
2200 const char *str = NULL;
2201 int str_len = 0;
2202 long len = 0;
2203
2204 /* declaration of the local variables */
2205 size_t ilen = 0;
2206 const mecab_node_t *node = NULL;
2207 php_mecab_node *xnode = NULL;
2208
2209 /* parse the arguments */
2210 PHP_MECAB_PARSE_PARAMETERS("s|l", &str, &str_len, &len);
2211
2212 /* call mecab_sparse_tonode() */
2213 php_mecab_set_string(xmecab, str, str_len TSRMLS_CC);
2214 ilen = (size_t)((len > 0) ? MIN(len, (long)str_len) : str_len);
2215 node = mecab_sparse_tonode2(mecab, xmecab->str, ilen);
2216 if (node == NULL) {
2217 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mecab_strerror(mecab));
2218 RETURN_FALSE;
2219 }
2220
2221 /* set return value */
2222 if (object) {
2223 php_mecab_node_object *newobj;
2224 object_init_ex(return_value, ce_MeCab_Node);
2225 PHP_MECAB_FETCH_OBJECT(newobj, php_mecab_node_object *, return_value);
2226 xnode = newobj->ptr;
2227 } else {
2228 xnode = php_mecab_node_ctor(TSRMLS_C);
2229 ZEND_REGISTER_RESOURCE(return_value, xnode, le_mecab_node);
2230 }
2231 xnode->ptr = node;
2232 php_mecab_node_set_tagger(xnode, xmecab TSRMLS_CC);
2233 }
2234 /* }}} mecab_sparse_tonode */
2235
2236 /* {{{ proto string mecab_nbest_sparse_tostr(resource mecab mecab, int n, string str[, int len[, int olen]]) */
2237 /**
2238 * string mecab_nbest_sparse_tostr(resource mecab mecab, int n, string str[, int len[, int olen]])
2239 * string MeCab_Tagger::parseNBest(int n, string str[, int len[, int olen]])
2240 *
2241 * Get the N-Best list as a string.
2242 *
2243 * @param resource mecab $mecab The tagger resource of MeCab.
2244 * @param int $n The number of the result list.
2245 * @param string $str The parse target.
2246 * @param int $len The maximum length that can be analyzed. (optional)
2247 * @param int $olen The maximum length of the output. (optional)
2248 * @return string The N-Best list.
2249 * If output buffer has overflowed, returns false.
2250 */
PHP_FUNCTION(mecab_nbest_sparse_tostr)2251 static PHP_FUNCTION(mecab_nbest_sparse_tostr)
2252 {
2253 /* declaration of the resources */
2254 zval *object = getThis();
2255 zval *zmecab = NULL;
2256 php_mecab *xmecab = NULL;
2257 mecab_t *mecab = NULL;
2258
2259 /* declaration of the arguments */
2260 long n = 0;
2261 const char *str = NULL;
2262 int str_len = 0;
2263 long len = 0;
2264 long olen = 0;
2265
2266 /* declaration of the local variables */
2267 size_t ilen = 0;
2268 char *ostr = NULL;
2269 zend_bool ostr_free = 1;
2270
2271 /* parse the arguments */
2272 PHP_MECAB_PARSE_PARAMETERS("ls|ll", &n, &str, &str_len, &len, &olen);
2273
2274 /* call mecab_nbest_sparse_tostr() */
2275 php_mecab_set_string(xmecab, str, str_len TSRMLS_CC);
2276 ilen = (size_t)((len > 0) ? MIN(len, (long)str_len) : str_len);
2277 if (olen == 0) {
2278 ostr = (char *)mecab_nbest_sparse_tostr2(mecab, n, xmecab->str, ilen);
2279 } else {
2280 ostr = (char *)emalloc(olen + 1);
2281 ostr = mecab_nbest_sparse_tostr3(mecab, n, xmecab->str, ilen, ostr, (size_t)olen);
2282 ostr_free = 1;
2283 }
2284
2285 /* set return value */
2286 if (ostr == NULL) {
2287 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mecab_strerror(mecab));
2288 RETVAL_FALSE;
2289 } else {
2290 RETVAL_STRING(ostr, 1);
2291 }
2292
2293 /* free */
2294 if (ostr_free) {
2295 efree(ostr);
2296 }
2297 }
2298 /* }}} mecab_nbest_sparse_tostr */
2299
2300 /* {{{ proto bool mecab_nbest_init(resource mecab mecab, string str[, int len]) */
2301 /**
2302 * bool mecab_nbest_init(resource mecab mecab, string str[, int len])
2303 * bool MeCab_Tagger::parseNBestInit(string str[, int len])
2304 *
2305 * Initialize the N-Best list.
2306 *
2307 * @param resource mecab $mecab The tagger resource of MeCab.
2308 * @param string $str The parse target.
2309 * @param int $len The maximum length that can be analyzed. (optional)
2310 * @return bool True if succeeded to initilalize, otherwise returns false.
2311 */
PHP_FUNCTION(mecab_nbest_init)2312 static PHP_FUNCTION(mecab_nbest_init)
2313 {
2314 /* declaration of the resources */
2315 zval *object = getThis();
2316 zval *zmecab = NULL;
2317 php_mecab *xmecab = NULL;
2318 mecab_t *mecab = NULL;
2319
2320 /* declaration of the arguments */
2321 const char *str = NULL;
2322 int str_len = 0;
2323 long len = 0;
2324
2325 /* declaration of the local variables */
2326 size_t ilen = 0;
2327 int result = 0;
2328
2329 /* parse the arguments */
2330 PHP_MECAB_PARSE_PARAMETERS("s|l", &str, &str_len, &len);
2331
2332 /* call mecab_nbest_init() */
2333 php_mecab_set_string(xmecab, str, str_len TSRMLS_CC);
2334 ilen = (size_t)((len > 0) ? MIN(len, (long)str_len) : str_len);
2335 result = mecab_nbest_init2(mecab, xmecab->str, ilen);
2336 if (result == 0) {
2337 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mecab_strerror(mecab));
2338 RETURN_FALSE;
2339 }
2340 RETURN_TRUE;
2341 }
2342 /* }}} mecab_nbest_init */
2343
2344 /* {{{ proto string mecab_nbest_next_tostr(resource mecab mecab[, int olen]) */
2345 /**
2346 * string mecab_nbest_next_tostr(resource mecab mecab[, int olen])
2347 * string MeCab_Tagger::next([int olen]])
2348 *
2349 * Get the next result of N-Best as a string.
2350 *
2351 * @param resource mecab $mecab The tagger resource of MeCab.
2352 * @param int $olen The maximum length of the output. (optional)
2353 * @return string The parse result of the next pointer.
2354 * If there are no more results, returns false.
2355 * Also returns false if output buffer has overflowed.
2356 */
PHP_FUNCTION(mecab_nbest_next_tostr)2357 static PHP_FUNCTION(mecab_nbest_next_tostr)
2358 {
2359 /* declaration of the resources */
2360 zval *object = getThis();
2361 zval *zmecab = NULL;
2362 php_mecab *xmecab = NULL;
2363 mecab_t *mecab = NULL;
2364
2365 /* declaration of the arguments */
2366 long olen = 0;
2367
2368 /* declaration of the local variables */
2369 char *ostr = NULL;
2370 zend_bool ostr_free = 0;
2371 const char *what = NULL;
2372
2373 /* parse the arguments */
2374 PHP_MECAB_PARSE_PARAMETERS("|l", &olen);
2375
2376 /* call mecab_nbest_sparse_tostr() */
2377 if (olen == 0) {
2378 ostr = (char *)mecab_nbest_next_tostr(mecab);
2379 } else {
2380 ostr = (char *)emalloc(olen + 1);
2381 ostr = mecab_nbest_next_tostr2(mecab, ostr, (size_t)olen);
2382 ostr_free = 1;
2383 }
2384
2385 /* set return value */
2386 if (ostr == NULL) {
2387 if ((what = mecab_strerror(mecab)) != NULL &&
2388 strcmp((char *)what, "no more results"))
2389 {
2390 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", what);
2391 }
2392 RETVAL_FALSE;
2393 } else {
2394 RETVAL_STRING(ostr, 1);
2395 }
2396
2397 /* free */
2398 if (ostr_free) {
2399 efree(ostr);
2400 }
2401 }
2402 /* }}} mecab_nbest_next_tostr */
2403
2404 /* {{{ proto resource mecab_node mecab_nbest_next_tonode(resource mecab mecab) */
2405 /**
2406 * resource mecab_node mecab_nbest_next_tonode(resource mecab mecab)
2407 * object MeCab_Node MeCab_Tagger::nextNode(void)
2408 *
2409 * Get the next result of N-Best as a node.
2410 *
2411 * @param resource mecab $mecab The tagger resource of MeCab.
2412 * @return resource mecab_node The result node of the next pointer.
2413 * If there are no more results, returns false.
2414 */
PHP_FUNCTION(mecab_nbest_next_tonode)2415 static PHP_FUNCTION(mecab_nbest_next_tonode)
2416 {
2417 /* declaration of the resources */
2418 zval *object = getThis();
2419 zval *zmecab = NULL;
2420 php_mecab *xmecab = NULL;
2421 mecab_t *mecab = NULL;
2422
2423 /* declaration of the local variables */
2424 const mecab_node_t *node = NULL;
2425 php_mecab_node *xnode = NULL;
2426 const char *what = NULL;
2427
2428 /* parse the arguments */
2429 PHP_MECAB_FROM_PARAMETER();
2430
2431 /* call mecab_nbest_next_tonode() */
2432 node = mecab_nbest_next_tonode(mecab);
2433 if (node == NULL) {
2434 if ((what = mecab_strerror(mecab)) != NULL &&
2435 strcmp((char *)what, "no more results"))
2436 {
2437 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", what);
2438 }
2439 RETURN_FALSE;
2440 }
2441
2442 /* set return value */
2443 if (object) {
2444 php_mecab_node_object *newobj;
2445 object_init_ex(return_value, ce_MeCab_Node);
2446 PHP_MECAB_FETCH_OBJECT(newobj, php_mecab_node_object *, return_value);
2447 xnode = newobj->ptr;
2448 } else {
2449 xnode = php_mecab_node_ctor(TSRMLS_C);
2450 ZEND_REGISTER_RESOURCE(return_value, xnode, le_mecab_node);
2451 }
2452 xnode->ptr = node;
2453 php_mecab_node_set_tagger(xnode, xmecab TSRMLS_CC);
2454 }
2455 /* }}} mecab_nbest_next_tonode */
2456
2457 /* {{{ proto string mecab_format_node(resource mecab mecab, resource mecab_node node) */
2458 /**
2459 * string mecab_format_node(resource mecab mecab, resource mecab_node node)
2460 * string MeCab_Tagger::formatNode(object MeCab_Node node)
2461 *
2462 * Format a node to string.
2463 * The format is specified by "-O" option or --{node|unk|bos|eos}-format=STR.
2464 * The detail is found in the web site and/or the manpage of MeCab.
2465 * NOTICE: If the option was "wakati" or "dump", the return string will be empty.
2466 *
2467 * @param resource mecab $mecab The tagger resource of MeCab.
2468 * @param resource mecab_node $node The node of the source string.
2469 * @return string The formatted string.
2470 * @see mecab_node_tostring
2471 */
PHP_FUNCTION(mecab_format_node)2472 static PHP_FUNCTION(mecab_format_node)
2473 {
2474 /* declaration of the resources */
2475 zval *object = getThis();
2476 zval *node_object = NULL;
2477 zval *zmecab = NULL;
2478 zval *znode = NULL;
2479 php_mecab *xmecab = NULL;
2480 php_mecab_node *xnode = NULL;
2481 mecab_t *mecab = NULL;
2482 const mecab_node_t *node = NULL;
2483
2484 /* declaration of the local variables */
2485 const char *fmt = NULL;
2486
2487 /* parse the arguments */
2488 if (object) {
2489 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &node_object, ce_MeCab_Node) == FAILURE) {
2490 return;
2491 } else {
2492 php_mecab_object *intern;
2493 php_mecab_node_object *intern_node;
2494 PHP_MECAB_FETCH_OBJECT(intern, php_mecab_object *, object);
2495 PHP_MECAB_FETCH_OBJECT(intern_node, php_mecab_node_object *, node_object);
2496 xmecab = intern->ptr;
2497 xnode = intern_node->ptr;
2498 }
2499 } else {
2500 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &zmecab, &znode) == FAILURE) {
2501 return;
2502 }
2503 ZEND_FETCH_RESOURCE(xmecab, php_mecab *, &zmecab, -1, "mecab", le_mecab);
2504 ZEND_FETCH_RESOURCE(xnode, php_mecab_node *, &znode, -1, "mecab_node", le_mecab_node);
2505 }
2506 mecab = xmecab->ptr;
2507 node = xnode->ptr;
2508
2509 /* call mecab_format_node() */
2510 fmt = mecab_format_node(mecab, node);
2511 if (fmt == NULL) {
2512 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mecab_strerror(mecab));
2513 RETURN_FALSE;
2514 }
2515
2516 /* set return value */
2517 RETURN_STRING((char *)fmt, 1);
2518 }
2519 /* }}} mecab_format_node */
2520
2521 /* {{{ proto array mecab_dictionary_info(resource mecab mecab) */
2522 /**
2523 * array mecab_dictionary_info(resource mecab mecab)
2524 * array MeCab_Tagger::dictionaryInfo(void)
2525 *
2526 * Get the information of using dictionary as an associative array.
2527 *
2528 * @return array The information of the dictionary.
2529 */
PHP_FUNCTION(mecab_dictionary_info)2530 static PHP_FUNCTION(mecab_dictionary_info)
2531 {
2532 /* declaration of the resources */
2533 zval *object = getThis();
2534 zval *zmecab = NULL;
2535 php_mecab *xmecab = NULL;
2536 mecab_t *mecab = NULL;
2537
2538 /* declaration of the local variables */
2539 const mecab_dictionary_info_t *dicinfo = NULL;
2540
2541 /* parse the arguments */
2542 PHP_MECAB_FROM_PARAMETER();
2543
2544 /* get dictionary information */
2545 dicinfo = mecab_dictionary_info(mecab);
2546 if (dicinfo == NULL) {
2547 RETURN_NULL();
2548 }
2549
2550 /* initialize */
2551 array_init(return_value);
2552
2553 /* get information for each dictionary */
2554 while (dicinfo != NULL) {
2555 zval *tmp = NULL;
2556
2557 MAKE_STD_ZVAL(tmp);
2558 array_init(tmp);
2559
2560 add_assoc_string(tmp, "filename", (char *)dicinfo->filename, 1);
2561 add_assoc_string(tmp, "charset", (char *)dicinfo->charset, 1);
2562 add_assoc_long(tmp, "size", (long)dicinfo->size);
2563 add_assoc_long(tmp, "type", (long)dicinfo->type);
2564 add_assoc_long(tmp, "lsize", (long)dicinfo->lsize);
2565 add_assoc_long(tmp, "rsize", (long)dicinfo->rsize);
2566 add_assoc_long(tmp, "version", (long)dicinfo->version);
2567
2568 add_next_index_zval(return_value, tmp);
2569
2570 dicinfo = dicinfo->next;
2571 }
2572 }
2573 /* }}} mecab_dictionary_info */
2574
2575 /* {{{ proto array mecab_node_toarray(resource mecab_node node[, bool dump_all]) */
2576 /**
2577 * array mecab_node_toarray(resource mecab_node node[, bool dump_all])
2578 * array MeCab_Node::toArray([bool dump_all])
2579 *
2580 * Get all elements of the node as an associative array.
2581 *
2582 * @param resource mecab_node $node The node of the source string.
2583 * @param bool $dump_all Whether dump all related nodes and paths or not.
2584 * @return array All elements of the node.
2585 */
PHP_FUNCTION(mecab_node_toarray)2586 static PHP_FUNCTION(mecab_node_toarray)
2587 {
2588 /* declaration of the resources */
2589 zval *object = getThis();
2590 zval *znode = NULL;
2591 php_mecab_node *xnode = NULL;
2592 const mecab_node_t *node = NULL;
2593
2594 /* declaration of the arguments */
2595 zend_bool dump_all = 0;
2596
2597 /* parse the arguments */
2598 PHP_MECAB_NODE_PARSE_PARAMETERS("|b", &dump_all);
2599
2600 /* initialize */
2601 array_init(return_value);
2602
2603 /* assign siblings and paths */
2604 if (dump_all) {
2605 add_assoc_zval(return_value, "prev", php_mecab_node_get_sibling(NULL, object, xnode, NODE_PREV TSRMLS_CC));
2606 add_assoc_zval(return_value, "next", php_mecab_node_get_sibling(NULL, object, xnode, NODE_NEXT TSRMLS_CC));
2607 add_assoc_zval(return_value, "enext", php_mecab_node_get_sibling(NULL, object, xnode, NODE_ENEXT TSRMLS_CC));
2608 add_assoc_zval(return_value, "bnext", php_mecab_node_get_sibling(NULL, object, xnode, NODE_BNEXT TSRMLS_CC));
2609 add_assoc_zval(return_value, "rpath", php_mecab_node_get_path(NULL, object, xnode, NODE_RPATH TSRMLS_CC));
2610 add_assoc_zval(return_value, "lpath", php_mecab_node_get_path(NULL, object, xnode, NODE_LPATH TSRMLS_CC));
2611 }
2612
2613 /* assign node info */
2614 add_assoc_stringl(return_value, "surface", (char *)node->surface, (int)node->length, 1);
2615 add_assoc_string(return_value, "feature", (char *)node->feature, 1);
2616 add_assoc_long(return_value, "id", (long)node->id);
2617 add_assoc_long(return_value, "length", (long)node->length);
2618 add_assoc_long(return_value, "rlength", (long)node->rlength);
2619 add_assoc_long(return_value, "rcAttr", (long)node->rcAttr);
2620 add_assoc_long(return_value, "lcAttr", (long)node->lcAttr);
2621 add_assoc_long(return_value, "posid", (long)node->posid);
2622 add_assoc_long(return_value, "char_type", (long)node->char_type);
2623 add_assoc_long(return_value, "stat", (long)node->stat);
2624 add_assoc_bool(return_value, "isbest", (long)node->isbest);
2625 add_assoc_double(return_value, "alpha", (double)node->alpha);
2626 add_assoc_double(return_value, "beta", (double)node->beta);
2627 add_assoc_double(return_value, "prob", (double)node->prob);
2628 add_assoc_long(return_value, "wcost", (long)node->wcost);
2629 add_assoc_long(return_value, "cost", (long)node->cost);
2630 }
2631 /* }}} mecab_node_toarray */
2632
2633 /* {{{ proto string mecab_node_tostring(resource mecab_node node) */
2634 /**
2635 * string mecab_node_tostring(resource mecab_node node)
2636 * string MeCab_Node::toString(void)
2637 * string MeCab_Node::__toString(void)
2638 *
2639 * Get the formatted string of the node.
2640 *
2641 * @param resource mecab_node $node The node of the source string.
2642 * @return string The formatted string.
2643 * @see mecab_format_node
2644 */
PHP_FUNCTION(mecab_node_tostring)2645 static PHP_FUNCTION(mecab_node_tostring)
2646 {
2647 /* declaration of the resources */
2648 zval *object = getThis();
2649 zval *znode = NULL;
2650 php_mecab_node *xnode = NULL;
2651 const mecab_node_t *node = NULL;
2652
2653 /* local variables */
2654 mecab_t *mecab = NULL;
2655 const char *fmt = NULL;
2656
2657 /* parse the arguments */
2658 PHP_MECAB_NODE_FROM_PARAMETER();
2659
2660 /* call mecab_format_node() */
2661 mecab = xnode->tagger->ptr;
2662 fmt = mecab_format_node(mecab, node);
2663 if (fmt == NULL) {
2664 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mecab_strerror(mecab));
2665 RETURN_FALSE;
2666 }
2667
2668 /* set return value */
2669 RETURN_STRING((char *)fmt, 1);
2670 }
2671 /* }}} mecab_node_tostring */
2672
2673 /* {{{ proto resource mecab_node mecab_node_prev(resource mecab_node node) */
2674 /**
2675 * resource mecab_node mecab_node_prev(resource mecab_node node)
2676 * object MeCab_Node MeCab_Node::getPrev(void)
2677 *
2678 * Get the previous node.
2679 *
2680 * @param resource mecab_node $node The node of the source string.
2681 * @return resource mecab_node The previous node.
2682 * If the given node is the first one, returns FALSE.
2683 */
PHP_FUNCTION(mecab_node_prev)2684 static PHP_FUNCTION(mecab_node_prev)
2685 {
2686 php_mecab_node_get_sibling_wrapper(INTERNAL_FUNCTION_PARAM_PASSTHRU, NODE_PREV);
2687 }
2688 /* }}} mecab_node_prev */
2689
2690 /* {{{ proto resource mecab_node mecab_node_next(resource mecab_node node) */
2691 /**
2692 * resource mecab_node mecab_node_next(resource mecab_node node)
2693 * object MeCab_Node MeCab_Node::getNext(void)
2694 *
2695 * Get the next node.
2696 *
2697 * @param resource mecab_node $node The node of the source string.
2698 * @return resource mecab_node The next node.
2699 * If the given node is the last one, returns FALSE.
2700 */
PHP_FUNCTION(mecab_node_next)2701 static PHP_FUNCTION(mecab_node_next)
2702 {
2703 php_mecab_node_get_sibling_wrapper(INTERNAL_FUNCTION_PARAM_PASSTHRU, NODE_NEXT);
2704 }
2705 /* }}} mecab_node_next */
2706
2707 /* {{{ proto resource mecab_node mecab_node_enext(resource mecab_node node) */
2708 /**
2709 * resource mecab_node mecab_node_enext(resource mecab_node node)
2710 * object MeCab_Node MeCab_Node::getENext(void)
2711 *
2712 * Get the enext node.
2713 *
2714 * @param resource mecab_node $node The node of the source string.
2715 * @return resource mecab_node The next node which has same end point as the given node.
2716 * If there is no `enext' node, returns false.
2717 */
PHP_FUNCTION(mecab_node_enext)2718 static PHP_FUNCTION(mecab_node_enext)
2719 {
2720 php_mecab_node_get_sibling_wrapper(INTERNAL_FUNCTION_PARAM_PASSTHRU, NODE_ENEXT);
2721 }
2722 /* }}} mecab_node_enext */
2723
2724 /* {{{ proto resource mecab_node mecab_node_bnext(resource mecab_node node) */
2725 /**
2726 * resource mecab_node mecab_node_bnext(resource mecab_node node)
2727 * object MeCab_Node MeCab_Node::getBNext(void)
2728 *
2729 * Get the bnext node.
2730 *
2731 * @param resource mecab_node $node The node of the source string.
2732 * @return resource mecab_node The next node which has same beggining point as the given one.
2733 * If there is no `bnext' node, returns false.
2734 */
PHP_FUNCTION(mecab_node_bnext)2735 static PHP_FUNCTION(mecab_node_bnext)
2736 {
2737 php_mecab_node_get_sibling_wrapper(INTERNAL_FUNCTION_PARAM_PASSTHRU, NODE_BNEXT);
2738 }
2739 /* }}} mecab_node_bnext */
2740
2741 /* {{{ proto resource mecab_path mecab_node_rpath(resource mecab_node node) */
2742 /**
2743 * resource mecab_path mecab_node_rpath(resource mecab_node node)
2744 * object MeCab_Path MeCab_Node::getRPath(void)
2745 *
2746 * Get the rpath.
2747 *
2748 * @param resource mecab_node $node The node of the source string.
2749 * @return resource mecab_path The next node which has same end point as the given node.
2750 * If there is no `rpath' node, returns false.
2751 */
PHP_FUNCTION(mecab_node_rpath)2752 static PHP_FUNCTION(mecab_node_rpath)
2753 {
2754 php_mecab_node_get_path_wrapper(INTERNAL_FUNCTION_PARAM_PASSTHRU, NODE_RPATH);
2755 }
2756 /* }}} mecab_node_rpath */
2757
2758 /* {{{ proto resource mecab_path mecab_node_lpath(resource mecab_node node) */
2759 /**
2760 * resource mecab_path mecab_node_lpath(resource mecab_node node)
2761 * object MeCab_Path MeCab_Node::getLPath(void)
2762 *
2763 * Get the lpath.
2764 *
2765 * @param resource mecab_node $node The node of the source string.
2766 * @return resource mecab_path The next node which has same beggining point as the given one.
2767 * If there is no `lpath' node, returns false.
2768 */
PHP_FUNCTION(mecab_node_lpath)2769 static PHP_FUNCTION(mecab_node_lpath)
2770 {
2771 php_mecab_node_get_path_wrapper(INTERNAL_FUNCTION_PARAM_PASSTHRU, NODE_LPATH);
2772 }
2773 /* }}} mecab_node_lpath */
2774
2775 /* {{{ proto string mecab_node_surface(resource mecab_node node) */
2776 /**
2777 * string mecab_node_surface(resource mecab_node node)
2778 * string MeCab_Node::getSurface(void)
2779 *
2780 * Get the surface.
2781 *
2782 * @param resource mecab_node $node The node of the source string.
2783 * @return string The surface of the node.
2784 */
PHP_FUNCTION(mecab_node_surface)2785 static PHP_FUNCTION(mecab_node_surface)
2786 {
2787 PHP_MECAB_NODE_RETURN_PROPERTY(STRINGL, (char *)node->surface, (int)node->length, 1);
2788 }
2789 /* }}} mecab_node_surface */
2790
2791 /* {{{ proto string mecab_node_feature(resource mecab_node node) */
2792 /**
2793 * string mecab_node_feature(resource mecab_node node)
2794 * string MeCab_Node::getFeature(void)
2795 *
2796 * Get the feature.
2797 *
2798 * @param resource mecab_node $node The node of the source string.
2799 * @return string The feature of the node.
2800 */
PHP_FUNCTION(mecab_node_feature)2801 static PHP_FUNCTION(mecab_node_feature)
2802 {
2803 PHP_MECAB_NODE_RETURN_PROPERTY(STRING, (char *)node->feature, 1);
2804 }
2805 /* }}} mecab_node_feature */
2806
2807 /* {{{ proto int mecab_node_id(resource mecab_node node) */
2808 /**
2809 * int mecab_node_id(resource mecab_node node)
2810 * int MeCab_Node::getId(void)
2811 *
2812 * Get the ID.
2813 *
2814 * @param resource mecab_node $node The node of the source string.
2815 * @return int The ID of the node.
2816 */
PHP_FUNCTION(mecab_node_id)2817 static PHP_FUNCTION(mecab_node_id)
2818 {
2819 PHP_MECAB_NODE_RETURN_PROPERTY(LONG, (long)node->id);
2820 }
2821 /* }}} mecab_node_id */
2822
2823 /* {{{ proto int mecab_node_length(resource mecab_node node) */
2824 /**
2825 * int mecab_node_length(resource mecab_node node)
2826 * int MeCab_Node::getLength(void)
2827 *
2828 * Get the length of the surface.
2829 *
2830 * @param resource mecab_node $node The node of the source string.
2831 * @return int The length of the surface of the node.
2832 */
PHP_FUNCTION(mecab_node_length)2833 static PHP_FUNCTION(mecab_node_length)
2834 {
2835 PHP_MECAB_NODE_RETURN_PROPERTY(LONG, (long)node->length);
2836 }
2837 /* }}} mecab_node_length */
2838
2839 /* {{{ proto int mecab_node_rlength(resource mecab_node node) */
2840 /**
2841 * int mecab_node_rlength(resource mecab_node node)
2842 * int MeCab_Node::getRLength(void)
2843 *
2844 * Get the length of the surface and its leading whitespace.
2845 *
2846 * @param resource mecab_node $node The node of the source string.
2847 * @return int The length of the surface and its leading whitespace of the node.
2848 */
PHP_FUNCTION(mecab_node_rlength)2849 static PHP_FUNCTION(mecab_node_rlength)
2850 {
2851 PHP_MECAB_NODE_RETURN_PROPERTY(LONG, (long)node->rlength);
2852 }
2853 /* }}} mecab_node_rlength */
2854
2855 /* {{{ proto int mecab_node_rcattr(resource mecab_node node) */
2856 /**
2857 * int mecab_node_rcattr(resource mecab_node node)
2858 * int MeCab_Node::getRcAttr(void)
2859 *
2860 * Get the ID of the right context.
2861 *
2862 * @param resource mecab_node $node The node of the source string.
2863 * @return int The ID of the right context.
2864 */
PHP_FUNCTION(mecab_node_rcattr)2865 static PHP_FUNCTION(mecab_node_rcattr)
2866 {
2867 PHP_MECAB_NODE_RETURN_PROPERTY(LONG, (long)node->rcAttr);
2868 }
2869 /* }}} mecab_node_rcattr */
2870
2871 /* {{{ proto int mecab_node_lcattr(resource mecab_node node) */
2872 /**
2873 * int mecab_node_lcattr(resource mecab_node node)
2874 * int MeCab_Node::getLcAttr(void)
2875 *
2876 * Get the ID of the left context.
2877 *
2878 * @param resource mecab_node $node The node of the source string.
2879 * @return int The ID of the left context.
2880 */
PHP_FUNCTION(mecab_node_lcattr)2881 static PHP_FUNCTION(mecab_node_lcattr)
2882 {
2883 PHP_MECAB_NODE_RETURN_PROPERTY(LONG, (long)node->lcAttr);
2884 }
2885 /* }}} mecab_node_lcattr */
2886
2887 /* {{{ proto int mecab_node_posid(resource mecab_node node) */
2888 /**
2889 * int mecab_node_posid(resource mecab_node node)
2890 * int MeCab_Node::getPosId(void)
2891 *
2892 * Get the ID of the Part-of-Speech.
2893 * (node->posid is not used in MeCab-0.90)
2894 *
2895 * @param resource mecab_node $node The node of the source string.
2896 * @return int The ID of the Part-of-Speech.
2897 * Currently, always returns 0.
2898 */
PHP_FUNCTION(mecab_node_posid)2899 static PHP_FUNCTION(mecab_node_posid)
2900 {
2901 PHP_MECAB_NODE_RETURN_PROPERTY(LONG, (long)node->posid);
2902 }
2903 /* }}} mecab_node_posid */
2904
2905 /* {{{ proto int mecab_node_char_type(resource mecab_node node) */
2906 /**
2907 * int mecab_node_char_type(resource mecab_node node)
2908 * int MeCab_Node::getCharType(void)
2909 *
2910 * Get the type of the character.
2911 *
2912 * @param resource mecab_node $node The node of the source string.
2913 * @return int The type of the character.
2914 */
PHP_FUNCTION(mecab_node_char_type)2915 static PHP_FUNCTION(mecab_node_char_type)
2916 {
2917 PHP_MECAB_NODE_RETURN_PROPERTY(LONG, (long)node->char_type);
2918 }
2919 /* }}} mecab_node_char_type */
2920
2921 /* {{{ proto int mecab_node_stat(resource mecab_node node) */
2922 /**
2923 * int mecab_node_stat(resource mecab_node node)
2924 * int MeCab_Node::getStat(void)
2925 *
2926 * Get the status.
2927 *
2928 * @param resource mecab_node $node The node of the source string.
2929 * @return int The status of the node.
2930 * The return value is one of the following:
2931 * MECAB_NOR_NODE (0:Normal)
2932 * MECAB_UNK_NODE (1:Unknown)
2933 * MECAB_BOS_NODE (2:Beginning-of-Sentence)
2934 * MECAB_EOS_NODE (3:End-of-Sentence)
2935 */
PHP_FUNCTION(mecab_node_stat)2936 static PHP_FUNCTION(mecab_node_stat)
2937 {
2938 PHP_MECAB_NODE_RETURN_PROPERTY(LONG, (long)node->stat);
2939 }
2940 /* }}} mecab_node_stat */
2941
2942 /* {{{ proto bool mecab_node_isbest(resource mecab_node node) */
2943 /**
2944 * bool mecab_node_isbest(resource mecab_node node)
2945 * bool MeCab_Node::isBest(void)
2946 *
2947 * Determine whether the node is the best solution.
2948 *
2949 * @param resource mecab_node $node The node of the source string.
2950 * @return bool True if the node is the best, otherwise returns false.
2951 */
PHP_FUNCTION(mecab_node_isbest)2952 static PHP_FUNCTION(mecab_node_isbest)
2953 {
2954 PHP_MECAB_NODE_RETURN_PROPERTY(BOOL, (node->isbest == 1));
2955 }
2956 /* }}} mecab_node_isbest */
2957
2958 /* {{{ proto double mecab_node_alpha(resource mecab_node node) */
2959 /**
2960 * double mecab_node_alpha(resource mecab_node node)
2961 * double MeCab_Node::getAlpha(void)
2962 *
2963 * Get the forward log probability.
2964 *
2965 * @param resource mecab_node $node The node of the source string.
2966 * @return double The forward log probability of the node.
2967 */
PHP_FUNCTION(mecab_node_alpha)2968 static PHP_FUNCTION(mecab_node_alpha)
2969 {
2970 PHP_MECAB_NODE_RETURN_PROPERTY(DOUBLE, (double)node->alpha);
2971 }
2972 /* }}} mecab_node_alpha */
2973
2974 /* {{{ proto double mecab_node_beta(resource mecab_node node) */
2975 /**
2976 * double mecab_node_beta(resource mecab_node node)
2977 * double MeCab_Node::getBeta(void)
2978 *
2979 * Get the backward log probability.
2980 *
2981 * @param resource mecab_node $node The node of the source string.
2982 * @return double The backward log probability of the node.
2983 */
PHP_FUNCTION(mecab_node_beta)2984 static PHP_FUNCTION(mecab_node_beta)
2985 {
2986 PHP_MECAB_NODE_RETURN_PROPERTY(DOUBLE, (double)node->beta);
2987 }
2988 /* }}} mecab_node_beta */
2989
2990 /* {{{ proto double mecab_node_prob(resource mecab_node node) */
2991 /**
2992 * double mecab_node_prob(resource mecab_node node)
2993 * double MeCab_Node::getProb(void)
2994 *
2995 * Get the marginal probability.
2996 *
2997 * @param resource mecab_node $node The node of the source string.
2998 * @return double The marginal probability of the node.
2999 */
PHP_FUNCTION(mecab_node_prob)3000 static PHP_FUNCTION(mecab_node_prob)
3001 {
3002 PHP_MECAB_NODE_RETURN_PROPERTY(DOUBLE, (double)node->prob);
3003 }
3004 /* }}} mecab_node_prob */
3005
3006 /* {{{ proto int mecab_node_wcost(resource mecab_node node) */
3007 /**
3008 * int mecab_node_wcost(resource mecab_node node)
3009 * int MeCab_Node::getWCost(void)
3010 *
3011 * Get the word arising cost.
3012 *
3013 * @param resource mecab_node $node The node of the source string.
3014 * @return int The word arising cost of the node.
3015 */
PHP_FUNCTION(mecab_node_wcost)3016 static PHP_FUNCTION(mecab_node_wcost)
3017 {
3018 PHP_MECAB_NODE_RETURN_PROPERTY(LONG, (long)node->wcost);
3019 }
3020 /* }}} mecab_node_wcost */
3021
3022 /* {{{ proto int mecab_node_cost(resource mecab_node node) */
3023 /**
3024 * int mecab_node_cost(resource mecab_node node)
3025 * int MeCab_Node::getCost(void)
3026 *
3027 * Get the cumulative cost.
3028 *
3029 * @param resource mecab_node $node The node of the source string.
3030 * @return int The cumulative cost of the node.
3031 */
PHP_FUNCTION(mecab_node_cost)3032 static PHP_FUNCTION(mecab_node_cost)
3033 {
3034 PHP_MECAB_NODE_RETURN_PROPERTY(LONG, (long)node->cost);
3035 }
3036 /* }}} mecab_node_cost */
3037
3038 /* {{{ proto resource mecab_path mecab_path_rnext(resource mecab_path path) */
3039 /**
3040 * resource mecab_path mecab_path_rnext(resource mecab_path path)
3041 * object MeCab_Path MeCab_Path::getRNext(void)
3042 *
3043 * Get the rnext path.
3044 *
3045 * @param resource mecab_path $path The path of the source string.
3046 * @return resource mecab_path The rnext path.
3047 * If the given path is the first one, returns FALSE.
3048 */
PHP_FUNCTION(mecab_path_rnext)3049 static PHP_FUNCTION(mecab_path_rnext)
3050 {
3051 php_mecab_path_get_sibling_wrapper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PATH_RNEXT);
3052 }
3053 /* }}} mecab_path_rnext */
3054
3055 /* {{{ proto resource mecab_path mecab_path_lnext(resource mecab_path path) */
3056 /**
3057 * resource mecab_path mecab_path_lnext(resource mecab_path path)
3058 * object MeCab_Path MeCab_Path::getLNext(void)
3059 *
3060 * Get the lnext path.
3061 *
3062 * @param resource mecab_path $path The path of the source string.
3063 * @return resource mecab_path The lnext path.
3064 * If the given path is the last one, returns FALSE.
3065 */
PHP_FUNCTION(mecab_path_lnext)3066 static PHP_FUNCTION(mecab_path_lnext)
3067 {
3068 php_mecab_path_get_sibling_wrapper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PATH_LNEXT);
3069 }
3070 /* }}} mecab_path_lnext */
3071
3072 /* {{{ proto resource mecab_node mecab_path_rnode(resource mecab_path path) */
3073 /**
3074 * resource mecab_node mecab_path_rnode(resource mecab_path path)
3075 * object MeCab_Node MeCab_Path::getRNode(void)
3076 *
3077 * Get the rnode.
3078 *
3079 * @param resource mecab_path $path The path of the source string.
3080 * @return resource mecab_node The next path which has same end point as the given path.
3081 * If there is no `rnode' path, returns false.
3082 */
PHP_FUNCTION(mecab_path_rnode)3083 static PHP_FUNCTION(mecab_path_rnode)
3084 {
3085 php_mecab_path_get_node_wrapper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PATH_RNODE);
3086 }
3087 /* }}} mecab_path_rnode */
3088
3089 /* {{{ proto resource mecab_node mecab_path_lnode(resource mecab_path path) */
3090 /**
3091 * resource mecab_node mecab_path_lnode(resource mecab_path path)
3092 * object MeCab_Node MeCab_Path::getLNode(void)
3093 *
3094 * Get the lnode.
3095 *
3096 * @param resource mecab_path $path The path of the source string.
3097 * @return resource mecab_node The next path which has same beggining point as the given one.
3098 * If there is no `lnode' path, returns false.
3099 */
PHP_FUNCTION(mecab_path_lnode)3100 static PHP_FUNCTION(mecab_path_lnode)
3101 {
3102 php_mecab_path_get_node_wrapper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PATH_LNODE);
3103 }
3104 /* }}} mecab_path_lnode */
3105
3106 /* {{{ proto double mecab_path_prob(resource mecab_path path) */
3107 /**
3108 * double mecab_path_prob(resource mecab_path path)
3109 * double MeCab_Path::getProb(void)
3110 *
3111 * Get the marginal probability.
3112 *
3113 * @param resource mecab_path $path The path of the source string.
3114 * @return double The marginal probability of the path.
3115 */
PHP_FUNCTION(mecab_path_prob)3116 static PHP_FUNCTION(mecab_path_prob)
3117 {
3118 PHP_MECAB_PATH_RETURN_PROPERTY(DOUBLE, (double)(path->prob));
3119 }
3120 /* }}} mecab_path_prob */
3121
3122 /* {{{ proto int mecab_path_cost(resource mecab_path path) */
3123 /**
3124 * int mecab_path_cost(resource mecab_path path)
3125 * int MeCab_Path::getCost(void)
3126 *
3127 * Get the cumulative cost.
3128 *
3129 * @param resource mecab_path $path The path of the source string.
3130 * @return int The cumulative cost of the path.
3131 */
PHP_FUNCTION(mecab_path_cost)3132 static PHP_FUNCTION(mecab_path_cost)
3133 {
3134 PHP_MECAB_PATH_RETURN_PROPERTY(LONG, (long)(path->cost));
3135 }
3136 /* }}} mecab_node_cost */
3137
3138 /* }}} Functions */
3139
3140 /* {{{ methods */
3141
3142 /* {{{ methods of class MeCab_Node*/
3143
3144 /* {{{ proto object MeCab_Node __construct(void) */
3145 /**
3146 * object MeCab_Node MeCab_Node::__construct(void)
3147 *
3148 * Create MeCab_Node object.
3149 *
3150 * @access private
3151 * @igore
3152 */
PHP_METHOD(MeCab_Node,__construct)3153 static PHP_METHOD(MeCab_Node, __construct)
3154 {
3155 return;
3156 }
3157 /* }}} MeCab_Node::__construct */
3158
3159 /* {{{ proto mixed MeCab_Node::__get(string name) */
3160 /**
3161 * mixed MeCab_Node::__get(string name)
3162 *
3163 * [Overloading implementation]
3164 * A magick getter.
3165 *
3166 * @param string $name The name of property.
3167 * @return mixed The value of the property.
3168 * If there is not a named property, causes E_NOTICE error and returns false.
3169 * @access public
3170 * @ignore
3171 */
PHP_METHOD(MeCab_Node,__get)3172 static PHP_METHOD(MeCab_Node, __get)
3173 {
3174 /* declaration of the resources */
3175 zval *object = getThis();
3176 php_mecab_node *xnode = NULL;
3177 const mecab_node_t *node = NULL;
3178
3179 /* declaration of the arguments */
3180 char *name = NULL;
3181 int name_len = 0;
3182
3183 /* parse the arguments */
3184 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
3185 return;
3186 } else {
3187 php_mecab_node_object *intern;
3188 PHP_MECAB_FETCH_OBJECT(intern, php_mecab_node_object *, object);
3189 xnode = intern->ptr;
3190 node = xnode->ptr;
3191 }
3192
3193 /* check for given property name */
3194 if (!strcmp(name, "prev")) {
3195 php_mecab_node_get_sibling(return_value, object, xnode, NODE_PREV TSRMLS_CC);
3196 return;
3197 }
3198 if (!strcmp(name, "next")) {
3199 php_mecab_node_get_sibling(return_value, object, xnode, NODE_NEXT TSRMLS_CC);
3200 return;
3201 }
3202 if (!strcmp(name, "enext")) {
3203 php_mecab_node_get_sibling(return_value, object, xnode, NODE_ENEXT TSRMLS_CC);
3204 return;
3205 }
3206 if (!strcmp(name, "bnext")) {
3207 php_mecab_node_get_sibling(return_value, object, xnode, NODE_BNEXT TSRMLS_CC);
3208 return;
3209 }
3210 if (!strcmp(name, "rpath")) {
3211 php_mecab_node_get_path(return_value, object, xnode, NODE_RPATH TSRMLS_CC);
3212 return;
3213 }
3214 if (!strcmp(name, "lpath")) {
3215 php_mecab_node_get_path(return_value, object, xnode, NODE_LPATH TSRMLS_CC);
3216 return;
3217 }
3218 if (!strcmp(name, "surface")) RETURN_STRINGL((char *)node->surface, (int)node->length, 1);
3219 if (!strcmp(name, "feature")) RETURN_STRING((char *)node->feature, 1);
3220 if (!strcmp(name, "id")) RETURN_LONG((long)node->id);
3221 if (!strcmp(name, "length")) RETURN_LONG((long)node->length);
3222 if (!strcmp(name, "rlength")) RETURN_LONG((long)node->rlength);
3223 if (!strcmp(name, "rcAttr")) RETURN_LONG((long)node->rcAttr);
3224 if (!strcmp(name, "lcAttr")) RETURN_LONG((long)node->lcAttr);
3225 if (!strcmp(name, "posid")) RETURN_LONG((long)node->posid);
3226 if (!strcmp(name, "char_type")) RETURN_LONG((long)node->char_type);
3227 if (!strcmp(name, "stat")) RETURN_LONG((long)node->stat);
3228 if (!strcmp(name, "isbest")) RETURN_BOOL((long)node->isbest);
3229 if (!strcmp(name, "alpha")) RETURN_DOUBLE((double)node->alpha);
3230 if (!strcmp(name, "beta")) RETURN_DOUBLE((double)node->beta);
3231 if (!strcmp(name, "prob")) RETURN_DOUBLE((double)node->prob);
3232 if (!strcmp(name, "wcost")) RETURN_LONG((long)node->wcost);
3233 if (!strcmp(name, "cost")) RETURN_LONG((long)node->cost);
3234
3235 /* when going to fetch undefined property */
3236 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Undefined property (%s)", name);
3237 RETURN_NULL();
3238 }
3239 /* }}} MeCab_Node::__get */
3240
3241 /* {{{ proto bool MeCab_Node::__isset(string name) */
3242 /**
3243 * bool MeCab_Node::__isset(string name)
3244 *
3245 * [Overloading implementation]
3246 * Determine whether there is a named property.
3247 *
3248 * @param string $name The name of property.
3249 * @return bool True if there is a named property, otherwise returns false.
3250 * @access public
3251 * @ignore
3252 */
PHP_METHOD(MeCab_Node,__isset)3253 static PHP_METHOD(MeCab_Node, __isset)
3254 {
3255 /* declaration of the resources */
3256 zval *object = getThis();
3257 php_mecab_node *xnode = NULL;
3258 const mecab_node_t *node = NULL;
3259
3260 /* declaration of the arguments */
3261 char *name = NULL;
3262 int name_len = 0;
3263
3264 /* parse the arguments */
3265 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
3266 return;
3267 } else {
3268 php_mecab_node_object *intern;
3269 PHP_MECAB_FETCH_OBJECT(intern, php_mecab_node_object *, object);
3270 xnode = intern->ptr;
3271 node = xnode->ptr;
3272 }
3273
3274 /* check for given property name */
3275 if ((!strcmp(name, "prev") && node->prev != NULL) ||
3276 (!strcmp(name, "next") && node->next != NULL) ||
3277 (!strcmp(name, "enext") && node->enext != NULL) ||
3278 (!strcmp(name, "bnext") && node->bnext != NULL) ||
3279 (!strcmp(name, "rpath") && node->rpath != NULL) ||
3280 (!strcmp(name, "lpath") && node->lpath != NULL) ||
3281 !strcmp(name, "surface") ||
3282 !strcmp(name, "feature") ||
3283 !strcmp(name, "id") ||
3284 !strcmp(name, "length") ||
3285 !strcmp(name, "rlength") ||
3286 !strcmp(name, "rcAttr") ||
3287 !strcmp(name, "lcAttr") ||
3288 !strcmp(name, "posid") ||
3289 !strcmp(name, "char_type") ||
3290 !strcmp(name, "stat") ||
3291 !strcmp(name, "isbest") ||
3292 !strcmp(name, "sentence_length") ||
3293 !strcmp(name, "alpha") ||
3294 !strcmp(name, "beta") ||
3295 !strcmp(name, "prob") ||
3296 !strcmp(name, "wcost") ||
3297 !strcmp(name, "cost"))
3298 {
3299 RETURN_TRUE;
3300 }
3301 RETURN_FALSE;
3302 }
3303 /* }}} MeCab_Node::__isset */
3304
3305 /* {{{ proto object MeCab_NodeIterator MeCab_Node::getIterator(void) */
3306 /**
3307 * object MeCab_NodeIterator MeCab_Node::getIterator(void)
3308 *
3309 * [IteratorAggregate implementation]
3310 * Return the iterator object.
3311 *
3312 * @return object MeCab_NodeIterator
3313 * @access public
3314 * @ignore
3315 */
PHP_METHOD(MeCab_Node,getIterator)3316 static PHP_METHOD(MeCab_Node, getIterator)
3317 {
3318 php_mecab_node_object *intern;
3319 php_mecab_node *xnode;
3320 const mecab_node_t *node;
3321 php_mecab_node_object *newobj;
3322 php_mecab_node *newnode;
3323
3324 intern = (php_mecab_node_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
3325 xnode = intern->ptr;
3326 node = xnode->ptr;
3327
3328 if (node == NULL) {
3329 RETURN_NULL();
3330 }
3331
3332 object_init_ex(return_value, ce_MeCab_NodeIterator);
3333 PHP_MECAB_FETCH_OBJECT(newobj, php_mecab_node_object *, return_value);
3334 newobj->root = node;
3335 newobj->mode = intern->mode;
3336 newnode = newobj->ptr;
3337 newnode->ptr = node;
3338 php_mecab_node_set_tagger(newnode, xnode->tagger TSRMLS_CC);
3339 }
3340 /* }}} MeCab_Node::getIterator */
3341
3342 /* {{{ proto void MeCab_Node::setTraverse(int tranverse) */
3343 /**
3344 * void MeCab_Node::setTraverse(int tranverse)
3345 *
3346 * Set the traverse mode.
3347 *
3348 * @param int $traverse The traverse mode.
3349 * @return void
3350 * @throws InvalidArgumentException
3351 * @access public
3352 */
PHP_METHOD(MeCab_Node,setTraverse)3353 static PHP_METHOD(MeCab_Node, setTraverse)
3354 {
3355 php_mecab_node_object *intern;
3356 long traverse = 0;
3357
3358 #if PHP_VERSION_ID >= 50300
3359 zend_error_handling error_handling;
3360
3361 zend_replace_error_handling(EH_THROW, ext_ce_InvalidArgumentException, &error_handling TSRMLS_CC);
3362 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &traverse) == FAILURE) {
3363 zend_restore_error_handling(&error_handling TSRMLS_CC);
3364 return;
3365 }
3366 zend_restore_error_handling(&error_handling TSRMLS_CC);
3367 #else
3368 php_set_error_handling(EH_THROW, ext_ce_InvalidArgumentException TSRMLS_CC);
3369 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &traverse) == FAILURE) {
3370 php_std_error_handling();
3371 return;
3372 }
3373 php_std_error_handling();
3374 #endif
3375
3376 intern = (php_mecab_node_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
3377
3378 if (traverse == (long)TRAVERSE_NEXT ||
3379 traverse == (long)TRAVERSE_ENEXT ||
3380 traverse == (long)TRAVERSE_BNEXT)
3381 {
3382 intern->mode = (php_mecab_traverse_mode)traverse;
3383 } else {
3384 zend_throw_exception(ext_ce_InvalidArgumentException,
3385 "Invalid traverse mdoe given", 0 TSRMLS_CC);
3386 }
3387 }
3388 /* }}} MeCab_Node::setTraverse */
3389
3390 /* }}} methods of class MeCab_Node */
3391
3392 /* {{{ methods of class MeCab_NodeIterator*/
3393
3394 /* {{{ proto object MeCab_NodeIterator __construct(void) */
3395 /**
3396 * object MeCab_Path MeCab_NodeIterator::__construct(void)
3397 *
3398 * Create MeCab_NodeIterator object.
3399 *
3400 * @access private
3401 * @igore
3402 */
PHP_METHOD(MeCab_NodeIterator,__construct)3403 static PHP_METHOD(MeCab_NodeIterator, __construct)
3404 {
3405 return;
3406 }
3407 /* }}} MeCab_NodeIterator::__construct */
3408
3409 /* {{{ object MeCab_Node MeCab_NodeIterator::current(void) */
3410 /**
3411 * object MeCab_Node MeCab_NodeIterator::current(void)
3412 *
3413 * [Iterator implementation]
3414 * Return the current element.
3415 *
3416 * @access public
3417 * @igore
3418 */
PHP_METHOD(MeCab_NodeIterator,current)3419 static PHP_METHOD(MeCab_NodeIterator, current)
3420 {
3421 php_mecab_node_object *intern;
3422 php_mecab_node *xnode;
3423 const mecab_node_t *node;
3424 php_mecab_node_object *newobj;
3425 php_mecab_node *newnode;
3426
3427 if (ZEND_NUM_ARGS() != 0) {
3428 WRONG_PARAM_COUNT;
3429 }
3430 intern = (php_mecab_node_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
3431 xnode = intern->ptr;
3432 node = xnode->ptr;
3433
3434 if (node == NULL) {
3435 RETURN_NULL();
3436 }
3437
3438 object_init_ex(return_value, ce_MeCab_Node);
3439 PHP_MECAB_FETCH_OBJECT(newobj, php_mecab_node_object *, return_value);
3440 newobj->mode = intern->mode;
3441 newnode = newobj->ptr;
3442 newnode->ptr = node;
3443 php_mecab_node_set_tagger(newnode, xnode->tagger TSRMLS_CC);
3444 }
3445 /* }}} MeCab_NodeIterator::current */
3446
3447 /* {{{ proto int MeCab_NodeIterator::key(void) */
3448 /**
3449 * int MeCab_Node::key(void)
3450 *
3451 * [Iterator implementation]
3452 * Return the key of the current element.
3453 *
3454 * @return int The cumulative cost of the node.
3455 * @access public
3456 * @igore
3457 */
PHP_METHOD(MeCab_NodeIterator,key)3458 static PHP_METHOD(MeCab_NodeIterator, key)
3459 {
3460 php_mecab_node_object *intern;
3461 php_mecab_node *xnode;
3462 const mecab_node_t *node;
3463
3464 if (ZEND_NUM_ARGS() != 0) {
3465 WRONG_PARAM_COUNT;
3466 }
3467 intern = (php_mecab_node_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
3468 xnode = intern->ptr;
3469 node = xnode->ptr;
3470
3471 if (node == NULL) {
3472 RETURN_NULL();
3473 }
3474
3475 RETURN_LONG((long)node->id);
3476 }
3477 /* }}} MeCab_NodeIterator::key */
3478
3479 /* {{{ proto void MeCab_NodeIterator::next(void) */
3480 /**
3481 * void MeCab_NodeIterator::next(void)
3482 *
3483 * [Iterator implementation]
3484 * Set the node pointer to the next.
3485 *
3486 * @return void
3487 * @access public
3488 * @igore
3489 */
PHP_METHOD(MeCab_NodeIterator,next)3490 static PHP_METHOD(MeCab_NodeIterator, next)
3491 {
3492 php_mecab_node_object *intern;
3493 php_mecab_node *xnode;
3494 const mecab_node_t *node;
3495
3496 if (ZEND_NUM_ARGS() != 0) {
3497 WRONG_PARAM_COUNT;
3498 }
3499 intern = (php_mecab_node_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
3500 xnode = intern->ptr;
3501 node = xnode->ptr;
3502
3503 if (node == NULL) {
3504 return;
3505 }
3506
3507 switch (intern->mode) {
3508 case TRAVERSE_NEXT:
3509 xnode->ptr = node->next;
3510 break;
3511 case TRAVERSE_ENEXT:
3512 xnode->ptr = node->enext;
3513 break;
3514 case TRAVERSE_BNEXT:
3515 xnode->ptr = node->bnext;
3516 break;
3517 default:
3518 xnode->ptr = NULL;
3519 }
3520 }
3521 /* }}} MeCab_NodeIterator::next */
3522
3523 /* {{{ proto void MeCab_NodeIterator::rewind(void) */
3524 /**
3525 * void MeCab_NodeIterator::rewind(void)
3526 *
3527 * [Iterator implementation]
3528 * Set the node pointer to the beginning.
3529 *
3530 * @return void
3531 * @access public
3532 * @igore
3533 */
PHP_METHOD(MeCab_NodeIterator,rewind)3534 static PHP_METHOD(MeCab_NodeIterator, rewind)
3535 {
3536 php_mecab_node_object *intern;
3537 php_mecab_node *xnode;
3538
3539 if (ZEND_NUM_ARGS() != 0) {
3540 WRONG_PARAM_COUNT;
3541 }
3542 intern = (php_mecab_node_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
3543 xnode = intern->ptr;
3544 xnode->ptr = intern->root;
3545 }
3546 /* }}} MeCab_NodeIterator::rewind */
3547
3548 /* {{{ proto bool MeCab_NodeIterator::valid(void) */
3549 /**
3550 * bool MeCab_NodeIterator::valid(void)
3551 *
3552 * [Iterator implementation]
3553 * Check if there is a current element after calls to rewind() or next().
3554 *
3555 * @return bool True if there is an element after the current element, otherwise returns false.
3556 * @access public
3557 * @igore
3558 */
PHP_METHOD(MeCab_NodeIterator,valid)3559 static PHP_METHOD(MeCab_NodeIterator, valid)
3560 {
3561 php_mecab_node_object *intern;
3562 php_mecab_node *xnode;
3563 const mecab_node_t *node;
3564
3565 if (ZEND_NUM_ARGS() != 0) {
3566 WRONG_PARAM_COUNT;
3567 }
3568 intern = (php_mecab_node_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
3569 xnode = intern->ptr;
3570 node = xnode->ptr;
3571
3572 RETURN_BOOL(node != NULL);
3573 }
3574 /* }}} MeCab_NodeIterator::valid */
3575
3576 /* }}} methods of class MeCab_NodeIterator */
3577
3578 /* {{{ methods of class MeCab_Path*/
3579
3580 /* {{{ proto object MeCab_Path __construct(void) */
3581 /**
3582 * object MeCab_Path MeCab_Path::__construct(void)
3583 *
3584 * Create MeCab_Path object.
3585 *
3586 * @access private
3587 * @igore
3588 */
PHP_METHOD(MeCab_Path,__construct)3589 static PHP_METHOD(MeCab_Path, __construct)
3590 {
3591 return;
3592 }
3593 /* }}} MeCab_Path::__construct */
3594
3595 /* {{{ proto mixed MeCab_Path::__get(string name) */
3596 /**
3597 * mixed MeCab_Path::__get(string name)
3598 *
3599 * [Overloading implementation]
3600 * A magick getter.
3601 *
3602 * @param string $name The name of property.
3603 * @return mixed The value of the property.
3604 * If there is not a named property, causes E_NOTICE error and returns false.
3605 * @access public
3606 * @ignore
3607 */
PHP_METHOD(MeCab_Path,__get)3608 static PHP_METHOD(MeCab_Path, __get)
3609 {
3610 /* declaration of the resources */
3611 zval *object = getThis();
3612 php_mecab_path *xpath = NULL;
3613 const mecab_path_t *path = NULL;
3614
3615 /* declaration of the arguments */
3616 char *name = NULL;
3617 int name_len = 0;
3618
3619 /* parse the arguments */
3620 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
3621 return;
3622 } else {
3623 php_mecab_path_object *intern;
3624 PHP_MECAB_FETCH_OBJECT(intern, php_mecab_path_object *, object);
3625 xpath = intern->ptr;
3626 path = xpath->ptr;
3627 }
3628
3629 /* check for given property name */
3630 if (!strcmp(name, "rnext")) {
3631 php_mecab_path_get_sibling(return_value, object, xpath, PATH_RNEXT TSRMLS_CC);
3632 return;
3633 }
3634 if (!strcmp(name, "lnext")) {
3635 php_mecab_path_get_sibling(return_value, object, xpath, PATH_LNEXT TSRMLS_CC);
3636 return;
3637 }
3638 if (!strcmp(name, "rnode")) {
3639 php_mecab_path_get_node(return_value, object, xpath, PATH_RNODE TSRMLS_CC);
3640 return;
3641 }
3642 if (!strcmp(name, "lnode")) {
3643 php_mecab_path_get_node(return_value, object, xpath, PATH_LNODE TSRMLS_CC);
3644 return;
3645 }
3646 if (!strcmp(name, "prob")) RETURN_DOUBLE((double)(path->prob));
3647 if (!strcmp(name, "cost")) RETURN_LONG((long)(path->cost));
3648
3649 /* when going to fetch undefined property */
3650 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Undefined property (%s)", name);
3651 RETURN_NULL();
3652 }
3653 /* }}} MeCab_Path::__get */
3654
3655 /* {{{ proto boolMeCab_Path:: __isset(string name) */
3656 /**
3657 * bool MeCab_Path::__isset(string name)
3658 *
3659 * [Overloading implementation]
3660 * Determine whether there is a named property.
3661 *
3662 * @param string $name The name of property.
3663 * @return bool True if there is a named property, otherwise returns false.
3664 * @access public
3665 * @ignore
3666 */
PHP_METHOD(MeCab_Path,__isset)3667 static PHP_METHOD(MeCab_Path, __isset)
3668 {
3669 /* declaration of the resources */
3670 zval *object = getThis();
3671 php_mecab_path *xpath = NULL;
3672 const mecab_path_t *path = NULL;
3673
3674 /* declaration of the arguments */
3675 char *name = NULL;
3676 int name_len = 0;
3677
3678 /* parse the arguments */
3679 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
3680 return;
3681 } else {
3682 php_mecab_path_object *intern;
3683 PHP_MECAB_FETCH_OBJECT(intern, php_mecab_path_object *, object);
3684 xpath = intern->ptr;
3685 path = xpath->ptr;
3686 }
3687
3688 /* check for given property name */
3689 if ((!strcmp(name, "rnext") && path->rnext != NULL) ||
3690 (!strcmp(name, "lnext") && path->lnext != NULL) ||
3691 (!strcmp(name, "rnode") && path->rnode != NULL) ||
3692 (!strcmp(name, "lnode") && path->lnode != NULL) ||
3693 !strcmp(name, "prob") ||
3694 !strcmp(name, "cost"))
3695 {
3696 RETURN_TRUE;
3697 }
3698 RETURN_FALSE;
3699 }
3700 /* }}} MeCab_Path::__isset */
3701
3702 /* }}} methods of class MeCab_Path */
3703
3704 /* }}} methods */
3705
3706 /*
3707 * Local variables:
3708 * tab-width: 4
3709 * c-basic-offset: 4
3710 * End:
3711 * vim600: noet sw=4 ts=4 fdm=marker
3712 * vim<600: noet sw=4 ts=4
3713 */
3714