diff options
Diffstat (limited to 'src-main')
-rw-r--r-- | src-main/Makefile.am | 12 | ||||
-rw-r--r-- | src-main/Makefile.in | 465 | ||||
-rw-r--r-- | src-main/context.c | 695 | ||||
-rw-r--r-- | src-main/main.c | 545 | ||||
-rw-r--r-- | src-main/main.h | 68 |
5 files changed, 1785 insertions, 0 deletions
diff --git a/src-main/Makefile.am b/src-main/Makefile.am new file mode 100644 index 0000000..27d2225 --- /dev/null +++ b/src-main/Makefile.am @@ -0,0 +1,12 @@ +## $Id: Makefile.am,v 1.9 2002/03/04 09:43:31 yusuke Exp $ + +INCLUDES = -I$(top_srcdir)/ + +lib_LTLIBRARIES = libanthy.la + +libanthy_la_LIBADD = ../src-splitter/libsplit.la ../src-ordering/libordering.la -lm ../src-worddic/libanthydic.la + +libanthy_la_LDFLAGS = -version-info 1:0:1 + +libanthy_la_SOURCES = \ + main.c context.c main.h diff --git a/src-main/Makefile.in b/src-main/Makefile.in new file mode 100644 index 0000000..b2db7bd --- /dev/null +++ b/src-main/Makefile.in @@ -0,0 +1,465 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src-main +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(libdir)" +libLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(lib_LTLIBRARIES) +libanthy_la_DEPENDENCIES = ../src-splitter/libsplit.la \ + ../src-ordering/libordering.la ../src-worddic/libanthydic.la +am_libanthy_la_OBJECTS = main.lo context.lo +libanthy_la_OBJECTS = $(am_libanthy_la_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libanthy_la_SOURCES) +DIST_SOURCES = $(libanthy_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ELISP_FALSE = @ELISP_FALSE@ +ELISP_TRUE = @ELISP_TRUE@ +EMACS = @EMACS@ +EMACSLOADPATH = @EMACSLOADPATH@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +lispdir = @lispdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +INCLUDES = -I$(top_srcdir)/ +lib_LTLIBRARIES = libanthy.la +libanthy_la_LIBADD = ../src-splitter/libsplit.la ../src-ordering/libordering.la -lm ../src-worddic/libanthydic.la +libanthy_la_LDFLAGS = -version-info 1:0:1 +libanthy_la_SOURCES = \ + main.c context.c main.h + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src-main/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src-main/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libanthy.la: $(libanthy_la_OBJECTS) $(libanthy_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libanthy_la_LDFLAGS) $(libanthy_la_OBJECTS) $(libanthy_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/context.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: install-libLTLIBRARIES + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-exec \ + install-exec-am install-info install-info-am \ + install-libLTLIBRARIES install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am \ + uninstall-libLTLIBRARIES + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src-main/context.c b/src-main/context.c new file mode 100644 index 0000000..7b426db --- /dev/null +++ b/src-main/context.c @@ -0,0 +1,695 @@ +/* + * 変換や文節の伸縮などの操作が進行中の文字列や候補などを + * まとめて変換コンテキストと呼ぶ。 + * Anthyのコンテキストに対する操作は全てここから呼ばれる。 + * 各操作に対して変換パイプラインの必要なモジュールを順に呼びだす。 + * + * personalityの管理もする。 + * + * Funded by IPA未踏ソフトウェア創造事業 2001 10/29 + * Copyright (C) 2000-2007 TABATA Yusuke + * + * $Id: context.c,v 1.26 2002/11/17 14:45:47 yusuke Exp $ + */ +/* + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <anthy/anthy.h> +#include <anthy/alloc.h> +#include <anthy/record.h> +#include <anthy/ordering.h> +#include <anthy/splitter.h> +#include <anthy/xstr.h> +#include "main.h" + +/**/ +static allocator context_ator; + +/** 現在のpersonality + * 未設定時: null + * 未設定のまま変換を開始した場合: "default" + * anonymousの場合: "" + */ +static char *current_personality; + +/**/ +#define HISTORY_FILE_LIMIT 100000 + +static void +context_dtor(void *p) +{ + anthy_do_reset_context((struct anthy_context *)p); +} + +/** 現在のpersonalityを返す */ +static char * +get_personality(void) +{ + if (!current_personality) { + current_personality = strdup("default"); + anthy_dic_set_personality(current_personality); + } + return current_personality; +} + +static void +release_segment(struct seg_ent *s) +{ + if (s->cands) { + int i; + for (i = 0; i < s->nr_cands; i++) { + anthy_release_cand_ent(s->cands[i]); + } + free (s->cands); + } + if (s->mw_array) { + free(s->mw_array); + } + free(s); + +} + +/** 文節リストの最後の要素を削除する */ +static void +pop_back_seg_ent(struct anthy_context *c) +{ + struct seg_ent *s; + s = c->seg_list.list_head.prev; + if (s == &c->seg_list.list_head) { + return ; + } + s->prev->next = s->next; + s->next->prev = s->prev; + release_segment(s); + c->seg_list.nr_segments --; +} + + +/** n番目の文節の文字のindexを求める */ +static int +get_nth_segment_index(struct anthy_context *c, int n) +{ + int i,s; + for (i = 0, s = 0; i < c->str.len; i++) { + if (c->split_info.ce[i].seg_border) { + if (s == n) { + return i; + } + s++; + } + } + return -1; +} + +/** n番目の文節の長さを求める. + * segment_listが構成されていなくても計算できるようにする. + */ +static int +get_nth_segment_len(struct anthy_context *c, int sindex) +{ + int a,i,l; + a = get_nth_segment_index(c, sindex); + if ( a == -1){ + return -1; + } + l = 1; + for (i = a+1; !c->split_info.ce[i].seg_border; i++) { + l++; + } + return l; +} + +/** metawordの配列を作る */ +static void +make_metaword_array(struct anthy_context *ac, + struct seg_ent *se) +{ + int i; + se->mw_array = NULL; + for (i = se->len; i > 0; i--) { + int j; + /* 最後に濁点とかがついてたら直前の文字ごと落す */ + if (i < se->len && + anthy_get_xchar_type(se->str.str[i]) & XCT_PART) { + /* FIXME 濁点とかがありえない並びをしてたら */ + i--; + continue ; + } + + se->nr_metaword = anthy_get_nr_metaword(&ac->split_info, se->from, i); + if (!se->nr_metaword) { + continue ; + } + /* metawordを配列に取り込む */ + se->mw_array = malloc(sizeof(struct meta_word*) * se->nr_metaword); + for (j = 0; j < se->nr_metaword; j++) { + se->mw_array[j] = anthy_get_nth_metaword(&ac->split_info, se->from, i, j); + } + return; + } +} + +static struct seg_ent* +create_segment(struct anthy_context *ac, int from, int len, + struct meta_word* best_mw) +{ + struct seg_ent* s; + s = (struct seg_ent *)malloc(sizeof(struct seg_ent)); + s->str.str = &ac->str.str[from]; + s->str.len = len; + s->from = from; + s->len = s->str.len; + s->nr_cands = 0; + s->cands = NULL; + s->best_seg_class = ac->split_info.ce[from].best_seg_class; + s->best_mw = best_mw; + make_metaword_array(ac, s); + return s; +} + +/** 変換コンテキストに文節を追加する */ +static void +push_back_segment(struct anthy_context *ac, struct seg_ent *se) +{ + se->next = &ac->seg_list.list_head; + se->prev = ac->seg_list.list_head.prev; + ac->seg_list.list_head.prev->next = se; + ac->seg_list.list_head.prev = se; + ac->seg_list.nr_segments ++; + se->committed = -1; +} + +/** splitterによって配列中に付けられた文節境界のマークから、 + * 文節のリストを構成する + */ +static void +create_segment_list(struct anthy_context *ac, int from, int to) +{ + int i, n; + struct seg_ent *s; + /* from の所までにいくつの文節があるか調べる */ + i = 0; n = 0; + while (i < from) { + i += get_nth_segment_len(ac, n); + n++; + }; + /**/ + for (i = from; i < to; i++) { + if (ac->split_info.ce[i].seg_border) { + int len = get_nth_segment_len(ac, n); + s = create_segment(ac, i, len, ac->split_info.ce[i].best_mw); + + push_back_segment(ac, s); + n++; + } + } +} + +/** コンテキストを作る */ +struct anthy_context * +anthy_do_create_context(int encoding) +{ + struct anthy_context *ac; + char *p = get_personality(); + + if (!p) { + return NULL; + } + + ac = (struct anthy_context *)anthy_smalloc(context_ator); + ac->str.str = NULL; + ac->str.len = 0; + ac->seg_list.nr_segments = 0; + ac->seg_list.list_head.prev = &ac->seg_list.list_head; + ac->seg_list.list_head.next = &ac->seg_list.list_head; + ac->split_info.word_split_info = NULL; + ac->split_info.ce = NULL; + ac->ordering_info.oc = NULL; + ac->dic_session = NULL; + ac->prediction.str.str = NULL; + ac->prediction.str.len = 0; + ac->prediction.nr_prediction = 0; + ac->prediction.predictions = NULL; + ac->encoding = encoding; + ac->reconversion_mode = ANTHY_RECONVERT_AUTO; + + return ac; +} + +/** コンテキストのアロケータを作る */ +void +anthy_init_contexts(void) +{ + context_ator = anthy_create_allocator(sizeof(struct anthy_context), + context_dtor); +} + +void +anthy_quit_contexts(void) +{ + anthy_free_allocator(context_ator); +} + +static void +release_prediction(struct prediction_cache *pc) +{ + int i; + if (pc->str.str) { + free(pc->str.str); + pc->str.str = NULL; + } + if (pc->predictions) { + for (i = 0; i < pc->nr_prediction; ++i) { + anthy_free_xstr(pc->predictions[i].src_str); + anthy_free_xstr(pc->predictions[i].str); + } + free(pc->predictions); + pc->predictions = NULL; + } +} + +void +anthy_release_segment_list(struct anthy_context *ac) +{ + int i, sc; + sc = ac->seg_list.nr_segments; + for (i = 0; i < sc; i++) { + pop_back_seg_ent(ac); + } + ac->seg_list.nr_segments = 0; +} + +/* resetではcontextのために確保されたリソースを全て解放する */ +void +anthy_do_reset_context(struct anthy_context *ac) +{ + /* まず辞書セッションを解放 */ + if (ac->dic_session) { + anthy_dic_release_session(ac->dic_session); + ac->dic_session = NULL; + } + if (!ac->str.str) { + /* 文字列が設定されていなければ解放すべき物はもう無い */ + return ; + } + free(ac->str.str); + ac->str.str = NULL; + anthy_release_split_context(&ac->split_info); + anthy_release_segment_list(ac); + + /* 予測された文字列の解放 */ + release_prediction(&ac->prediction); +} + +void +anthy_do_release_context(struct anthy_context *ac) +{ + anthy_sfree(context_ator, ac); +} + +static void +make_candidates(struct anthy_context *ac, int from, int from2, int is_reverse) +{ + int i; + int len = ac->str.len; + + /* 文節の境界を設定 */ + /* from と from2の間に境界を作ることを禁止する */ + anthy_mark_border(&ac->split_info, from, from2, len); + create_segment_list(ac, from, len); + anthy_sort_metaword(&ac->seg_list); + + /* 候補を列挙 */ + for (i = 0; i < ac->seg_list.nr_segments; i++) { + anthy_do_make_candidates(&ac->split_info, + anthy_get_nth_segment(&ac->seg_list, i), + is_reverse); + } + /* 候補をソート */ + anthy_sort_candidate(&ac->seg_list, 0); +} + +int +anthy_do_context_set_str(struct anthy_context *ac, xstr *s, int is_reverse) +{ + int i; + + /* 文字列をコピー(一文字分余計にして0をセット) */ + ac->str.str = (xchar *)malloc(sizeof(xchar)*(s->len+1)); + anthy_xstrcpy(&ac->str, s); + ac->str.str[s->len] = 0; + + /* splitterの初期化*/ + anthy_init_split_context(&ac->str, &ac->split_info, is_reverse); + + /* 解の候補を作成 */ + make_candidates(ac, 0, 0, is_reverse); + + /* 最初に設定した文節境界を覚えておく */ + for (i = 0; i < ac->seg_list.nr_segments; i++) { + struct seg_ent *s = anthy_get_nth_segment(&ac->seg_list, i); + ac->split_info.ce[s->from].initial_seg_len = s->len; + } + + return 0; +} + +void +anthy_do_resize_segment(struct anthy_context *ac, + int nth, int resize) +{ + int i; + int index, len, sc; + + /* resizeが可能か検査する */ + if (nth >= ac->seg_list.nr_segments) { + return ; + } + index = get_nth_segment_index(ac, nth); + len = get_nth_segment_len(ac, nth); + if (index + len + resize > ac->str.len) { + return ; + } + if (len + resize < 1) { + return ; + } + + /* nth以降のseg_entを解放する */ + sc = ac->seg_list.nr_segments; + for (i = nth; i < sc; i++) { + pop_back_seg_ent(ac); + } + + /* resizeしたseg_borderをマークする */ + /* 現在のマークを消して新しいマークをつける */ + ac->split_info.ce[index+len].seg_border = 0; + ac->split_info.ce[ac->str.len].seg_border = 1; + for (i = index+len+resize+1; i < ac->str.len; i++) { + ac->split_info.ce[i].seg_border = 0; + } + ac->split_info.ce[index+len+resize].seg_border = 1; + for (i = index; i < ac->str.len; i++) { + ac->split_info.ce[i].best_mw = NULL; + } + + /* 解の候補を作成 */ + make_candidates(ac, index, index+len+resize, 0); +} + +/* + * n番めの文節を取得する、無い場合にはNULLを返す + */ +struct seg_ent * +anthy_get_nth_segment(struct segment_list *sl, int n) +{ + int i; + struct seg_ent *se; + if (n >= sl->nr_segments || + n < 0) { + return NULL; + } + for (i = 0, se = sl->list_head.next; i < n; i++, se = se->next); + return se; +} + +int +anthy_do_set_prediction_str(struct anthy_context *ac, xstr* xs) +{ + struct prediction_cache* prediction = &ac->prediction; + int nr_prediction; + + /* まず辞書セッションを解放 */ + if (ac->dic_session) { + anthy_dic_release_session(ac->dic_session); + ac->dic_session = NULL; + } + /* 予測された文字列の解放 */ + release_prediction(&ac->prediction); + + /* 辞書セッションの開始 */ + if (!ac->dic_session) { + ac->dic_session = anthy_dic_create_session(); + if (!ac->dic_session) { + return -1; + } + } + + prediction->str.str = (xchar*)malloc(sizeof(xchar*)*(xs->len+1)); + anthy_xstrcpy(&prediction->str, xs); + prediction->str.str[xs->len]=0; + + nr_prediction = anthy_traverse_record_for_prediction(xs, NULL); + prediction->nr_prediction = nr_prediction; + + if (nr_prediction) { + prediction->predictions = (struct prediction_t*)malloc(sizeof(struct prediction_t) * + nr_prediction); + anthy_traverse_record_for_prediction(xs, prediction->predictions); + } + return 0; +} + +static const char * +get_change_state(struct anthy_context *ac) +{ + int resize = 0, cand_change = 0; + int i; + for (i = 0; i < ac->seg_list.nr_segments; i++) { + struct seg_ent *s = anthy_get_nth_segment(&ac->seg_list, i); + if (ac->split_info.ce[s->from].initial_seg_len != s->len) { + resize = 1; + } + if (s->committed > 0) { + cand_change = 1; + } + } + /**/ + if (resize && cand_change) { + return "SC"; + } + if (resize) { + return "S"; + } + if (cand_change) { + return "C"; + } + return "-"; +} + +static void +write_history(FILE *fp, struct anthy_context *ac) +{ + int i; + /* 読み */ + fprintf(fp, "|"); + for (i = 0; i < ac->seg_list.nr_segments; i++) { + struct seg_ent *s = anthy_get_nth_segment(&ac->seg_list, i); + char *c = anthy_xstr_to_cstr(&s->str, ANTHY_EUC_JP_ENCODING); + fprintf(fp, "%s|", c); + free(c); + } + fprintf(fp, " |"); + /* 結果 */ + for (i = 0; i < ac->seg_list.nr_segments; i++) { + struct seg_ent *s = anthy_get_nth_segment(&ac->seg_list, i); + char *c; + /**/ + if (s->committed < 0) { + fprintf(fp, "?|"); + continue ; + } + c = anthy_xstr_to_cstr(&s->cands[s->committed]->str, + ANTHY_EUC_JP_ENCODING); + fprintf(fp, "%s|", c); + free(c); + } +} + +void +anthy_save_history(const char *fn, struct anthy_context *ac) +{ + FILE *fp; + struct stat st; + if (!fn) { + return ; + } + fp = fopen(fn, "a"); + if (!fp) { + return ; + } + if (stat(fn, &st) || + st.st_size > HISTORY_FILE_LIMIT) { + fclose(fp); + return ; + } + /**/ + fprintf(fp, "anthy-%s ", anthy_get_version_string()); + fprintf(fp, "%s ", get_change_state(ac)); + write_history(fp, ac); + fprintf(fp, "\n"); + fclose(fp); + /**/ + chmod(fn, S_IREAD | S_IWRITE); +} + +/** 候補を表示する */ +void +anthy_print_candidate(struct cand_ent *ce) +{ + int mod = (ce->score % 1000); + int seg_score = 0; + + if (ce->mw) { + seg_score = ce->mw->score; + } + anthy_putxstr(&ce->str); + printf(":("); + /*if (ce->nr_words == 1) {printf("%d,", ce->elm[0].id); }*/ + if (ce->flag & CEF_OCHAIRE) { + putchar('o'); + } + if (ce->flag & CEF_SINGLEWORD) { + putchar('1'); + } + if (ce->flag & CEF_GUESS) { + putchar('g'); + } + if (ce->flag & (CEF_KATAKANA | CEF_HIRAGANA)) { + putchar('N'); + } + if (ce->flag & CEF_USEDICT) { + putchar('U'); + } + if (ce->flag & CEF_CONTEXT) { + putchar('C'); + } + printf(",%d,", seg_score); + + + if (ce->mw) { + printf("%s,%d", anthy_seg_class_sym(ce->mw->seg_class), + ce->mw->struct_score); + } else { + putchar('-'); + } + printf(")"); + + if (ce->score >= 1000) { + printf("%d,", ce->score/1000); + if (mod < 100) { + printf("0"); + } + if (mod < 10) { + printf("0"); + } + printf("%d ", mod); + } else { + printf("%d ", ce->score); + } +} + +/** 文節を表示する */ +static void +print_segment(struct seg_ent *e) +{ + int i; + + anthy_putxstr(&e->str); + printf("("); + for ( i = 0 ; i < e->nr_cands ; i++) { + anthy_print_candidate(e->cands[i]); + printf(","); + } + printf(")"); + printf(":\n"); +} + +/** コンテキストを表示する */ +void +anthy_do_print_context(struct anthy_context *ac, int encoding) +{ + int i; + struct char_ent *ce; + anthy_xstr_set_print_encoding(encoding); + + ce = ac->split_info.ce; + if (!ce) { + printf("(invalid)\n"); + return ; + } + /* 各文字を表示する */ + for (i = 0, ce = ac->split_info.ce; i < ac->str.len; i++, ce++) { + if (ce->seg_border) { + printf("|"); + } + anthy_putxchar(*(ce->c)); + } + printf("\n"); + /* 各文節を表示する */ + for (i = 0; i < ac->seg_list.nr_segments; i++) { + print_segment(anthy_get_nth_segment(&ac->seg_list, i)); + } + printf("\n"); +} + +void +anthy_release_cand_ent(struct cand_ent *ce) +{ + if (ce->elm) { + free(ce->elm); + } + if (&ce->str) { + anthy_free_xstr_str(&ce->str); + } + free(ce); +} + +int +anthy_do_set_personality(const char *id) +{ + if (current_personality) { + /* すでに設定されてる */ + return -1; + } + if (!id || strchr(id, '/')) { + return -1; + } + current_personality = strdup(id); + anthy_dic_set_personality(current_personality); + return 0; +} + +void +anthy_init_personality(void) +{ + current_personality = NULL; +} + +void +anthy_quit_personality(void) +{ + if (current_personality) { + free(current_personality); + current_personality = NULL; + } +} diff --git a/src-main/main.c b/src-main/main.c new file mode 100644 index 0000000..024cb6e --- /dev/null +++ b/src-main/main.c @@ -0,0 +1,545 @@ +/* + * Comments in this program are written in Japanese, + * because this program is a Japanese input method. + * (many Japanese gramatical terms will appear.) + * + * Kana-Kanji conversion engine Anthy. + * 仮名漢字変換エンジンAnthy(アンシー) + * + * Funded by IPA未踏ソフトウェア創造事業 2001 9/22 + * Funded by IPA未踏ソフトウェア創造事業 2005 + * Copyright (C) 2000-2007 TABATA Yusuke, UGAWA Tomoharu + * Copyright (C) 2004-2006 YOSHIDA Yuichi + * Copyright (C) 2000-2007 KMC(Kyoto University Micro Computer Club) + * Copyright (C) 2001-2002 TAKAI Kosuke, Nobuoka Takahiro + * + */ +/* + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* + * Anthyの変換機能はライブラリとして構成されており、この + * ファイルにはライブラリの提供する関数(API)が記述されています。 + * + * ライブラリの提供する関数は下記のようなものがあります + * (1)ライブラリ全体の初期化、終了、設定 + * (2)変換コンテキストの作成、解放 + * (3)変換コンテキストに対する文字列の設定、文節長の変更、候補の取得等 + * + * インターフェイスに関しては doc/LIBを参照してください + * Anthyのコードを理解しようとする場合は + * doc/GLOSSARY で用語を把握することを勧めます + */ +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +#include <anthy/dic.h> +#include <anthy/splitter.h> +#include <anthy/conf.h> +#include <anthy/ordering.h> +#include <anthy/logger.h> +#include <anthy/record.h> +#include <anthy/anthy.h> +#include <anthy/record.h> +#include <anthy/xchar.h> /* for KK_VU */ +#include "main.h" +#include "config.h" + + +/** Anthyの初期化が完了したかどうかのフラグ */ +static int is_init_ok; +/** コンテキスト生成時のエンコーディング */ +static int default_encoding; +/***/ +static char *history_file; + +/** (API) 全体の初期化 */ +int +anthy_init(void) +{ + char *hfn; + if (is_init_ok) { + /* 2度初期化しないように */ + return 0; + } + + /* 各サブシステムを順に初期化する */ + if (anthy_init_dic()) { + anthy_log(0, "Failed to initialize dictionary.\n"); + return -1; + } + + if (anthy_init_splitter()) { + anthy_log(0, "Failed to init splitter.\n"); + return -1; + } + anthy_init_contexts(); + anthy_init_personality(); + anthy_infosort_init(); + anthy_relation_init(); + + /**/ + default_encoding = ANTHY_EUC_JP_ENCODING; + is_init_ok = 1; + history_file = NULL; + hfn = getenv("ANTHY_HISTORY_FILE"); + if (hfn) { + history_file = strdup(hfn); + } + + /**/ + return 0; +} + +/** (API) 全データの解放 */ +void +anthy_quit(void) +{ + if (!is_init_ok) { + return ; + } + anthy_quit_contexts(); + anthy_quit_personality(); + anthy_quit_splitter(); + /* 多くのデータ構造はここでallocatorによって解放される */ + anthy_quit_dic(); + + is_init_ok = 0; + /**/ + if (history_file) { + free(history_file); + } + history_file = NULL; +} + +/** (API) 設定項目の上書き */ +void +anthy_conf_override(const char *var, const char *val) +{ + anthy_do_conf_override(var, val); +} + +/** (API) personalityの設定 */ +int +anthy_set_personality(const char *id) +{ + return anthy_do_set_personality(id); +} + +/** (API) 変換contextの作成 */ +struct anthy_context * +anthy_create_context(void) +{ + if (!is_init_ok) { + return 0; + } + return anthy_do_create_context(default_encoding); +} + +/** (API) 変換contextのリセット */ +void +anthy_reset_context(struct anthy_context *ac) +{ + anthy_do_reset_context(ac); +} + +/** (API) 変換contextの解放 */ +void +anthy_release_context(struct anthy_context *ac) +{ + anthy_do_release_context(ac); +} + +/** + * 再変換が必要かどうかの判定 + */ +static int +need_reconvert(struct anthy_context *ac, xstr *xs) +{ + int i; + + if (ac->reconversion_mode == ANTHY_RECONVERT_ALWAYS) { + return 1; + } + if (ac->reconversion_mode == ANTHY_RECONVERT_DISABLE) { + return 0; + } + + for (i = 0; i < xs->len; ++i) { + xchar xc = xs->str[i]; + int type = anthy_get_xchar_type(xc); + + /* これらの文字種の場合は逆変換する + * 「ヴ」はフロントエンドが平仮名モードの文字列として送ってくるので、 + * 逆変換の対象とはしない + */ + if (!(type & (XCT_HIRA | XCT_SYMBOL | XCT_NUM | + XCT_WIDENUM | XCT_OPEN | XCT_CLOSE | + XCT_ASCII)) && + xc != KK_VU) { + return 1; + } + } + return 0; +} + + +/** (API) 変換文字列の設定 */ +int +anthy_set_string(struct anthy_context *ac, const char *s) +{ + xstr *xs; + int retval; + + if (!ac) { + return -1; + } + + /*初期化*/ + anthy_do_reset_context(ac); + + /* 辞書セッションの開始 */ + if (!ac->dic_session) { + ac->dic_session = anthy_dic_create_session(); + if (!ac->dic_session) { + return -1; + } + } + + anthy_dic_activate_session(ac->dic_session); + /* 変換を開始する前に個人辞書をreloadする */ + anthy_reload_record(); + + xs = anthy_cstr_to_xstr(s, ac->encoding); + /**/ + if (!need_reconvert(ac, xs)) { + /* 普通に変換する */ + retval = anthy_do_context_set_str(ac, xs, 0); + } else { + /* 漢字やカタカナが混じっていたら再変換してみる */ + struct anthy_conv_stat stat; + struct seg_ent *seg; + int i; + xstr* hira_xs; + /* 与えられた文字列に変換をかける */ + retval = anthy_do_context_set_str(ac, xs, 1); + + /* 各文節の第一候補を取得して平仮名列を得る */ + anthy_get_stat(ac, &stat); + hira_xs = NULL; + for (i = 0; i < stat.nr_segment; ++i) { + seg = anthy_get_nth_segment(&ac->seg_list, i); + hira_xs = anthy_xstrcat(hira_xs, &seg->cands[0]->str); + } + /* 改めて変換を行なう */ + anthy_release_segment_list(ac); + retval = anthy_do_context_set_str(ac, hira_xs, 0); + anthy_free_xstr(hira_xs); + } + + anthy_free_xstr(xs); + return retval; +} + +/** (API) 文節長の変更 */ +void +anthy_resize_segment(struct anthy_context *ac, int nth, int resize) +{ + anthy_dic_activate_session(ac->dic_session); + anthy_do_resize_segment(ac, nth, resize); +} + +/** (API) 変換の状態の取得 */ +int +anthy_get_stat(struct anthy_context *ac, struct anthy_conv_stat *s) +{ + s->nr_segment = ac->seg_list.nr_segments; + return 0; +} + +/** (API) 文節の状態の取得 */ +int +anthy_get_segment_stat(struct anthy_context *ac, int n, + struct anthy_segment_stat *s) +{ + struct seg_ent *seg; + seg = anthy_get_nth_segment(&ac->seg_list, n); + if (seg) { + s->nr_candidate = seg->nr_cands; + s->seg_len = seg->str.len; + return 0; + } + return -1; +} + +static int +get_special_candidate_index(int nth, struct seg_ent *seg) +{ + int i; + int mask = XCT_NONE; + if (nth >= 0) { + return nth; + } + if (nth == NTH_UNCONVERTED_CANDIDATE || + nth == NTH_HALFKANA_CANDIDATE) { + return nth; + } + if (nth == NTH_KATAKANA_CANDIDATE) { + mask = XCT_KATA; + } else if (nth == NTH_HIRAGANA_CANDIDATE) { + mask = XCT_HIRA; + } + for (i = 0; i < seg->nr_cands; i++) { + if (anthy_get_xstr_type(&seg->cands[i]->str) & mask) { + return i; + } + } + return NTH_UNCONVERTED_CANDIDATE; +} + +/** (API) 文節の取得 */ +int +anthy_get_segment(struct anthy_context *ac, int nth_seg, + int nth_cand, char *buf, int buflen) +{ + struct seg_ent *seg; + char *p; + int len; + + /* 文節を取り出す */ + if (nth_seg < 0 || nth_seg >= ac->seg_list.nr_segments) { + return -1; + } + seg = anthy_get_nth_segment(&ac->seg_list, nth_seg); + + /* 文節から候補を取り出す */ + p = NULL; + if (nth_cand < 0) { + nth_cand = get_special_candidate_index(nth_cand, seg); + } + if (nth_cand == NTH_HALFKANA_CANDIDATE) { + xstr *xs = anthy_xstr_hira_to_half_kata(&seg->str); + p = anthy_xstr_to_cstr(xs, ac->encoding); + anthy_free_xstr(xs); + } else if (nth_cand == NTH_UNCONVERTED_CANDIDATE) { + /* 変換前の文字列を取得する */ + p = anthy_xstr_to_cstr(&seg->str, ac->encoding); + } else if (nth_cand >= 0 && nth_cand < seg->nr_cands) { + p = anthy_xstr_to_cstr(&seg->cands[nth_cand]->str, ac->encoding); + } + if (!p) { + return -1; + } + + /* バッファに書き込む */ + len = strlen(p); + if (!buf) { + free(p); + return len; + } + if (len + 1 > buflen) { + /* バッファが足りません */ + free(p); + return -1; + } + strcpy(buf, p); + free(p); + return len; +} + +/* すべての文節がコミットされたかcheckする */ +static int +commit_all_segment_p(struct anthy_context *ac) +{ + int i; + struct seg_ent *se; + for (i = 0; i < ac->seg_list.nr_segments; i++) { + se = anthy_get_nth_segment(&ac->seg_list, i); + if (se->committed < 0) { + return 0; + } + } + return 1; +} + +/** (API) 文節の確定 */ +int +anthy_commit_segment(struct anthy_context *ac, int s, int c) +{ + struct seg_ent *seg; + if (!ac->str.str) { + return -1; + } + if (s < 0 || s >= ac->seg_list.nr_segments) { + return -1; + } + if (commit_all_segment_p(ac)) { + /* すでに全てのセグメントがコミットされている */ + return -1; + } + + anthy_dic_activate_session(ac->dic_session); + seg = anthy_get_nth_segment(&ac->seg_list, s); + if (c < 0) { + c = get_special_candidate_index(c, seg); + } + if (c == NTH_UNCONVERTED_CANDIDATE) { + /* + * 変換前の文字列がコミットされたので,それに対応する候補の番号を探す + */ + int i; + for (i = 0; i < seg->nr_cands; i++) { + if (!anthy_xstrcmp(&seg->str, &seg->cands[i]->str)) { + c = i; + } + } + } + if (c < 0 || c >= seg->nr_cands) { + return -1; + } + seg->committed = c; + + if (commit_all_segment_p(ac)) { + /* 今、すべてのセグメントがコミットされた */ + anthy_proc_commit(&ac->seg_list, &ac->split_info); + /**/ + anthy_save_history(history_file, ac); + } + return 0; +} + +/** (API) 予測してほしい文字列の設定 */ +int +anthy_set_prediction_string(struct anthy_context *ac, const char* s) +{ + int retval; + xstr *xs; + + anthy_dic_activate_session(ac->dic_session); + /* 予測を開始する前に個人辞書をreloadする */ + anthy_reload_record(); + + + xs = anthy_cstr_to_xstr(s, ac->encoding); + + retval = anthy_do_set_prediction_str(ac, xs); + + anthy_free_xstr(xs); + + return retval; +} + +/** (API) 予測変換の状態の取得 */ +int +anthy_get_prediction_stat(struct anthy_context *ac, struct anthy_prediction_stat * ps) +{ + ps->nr_prediction = ac->prediction.nr_prediction; + return 0; +} + +/** (API) 予測変換の候補の取得 */ +int +anthy_get_prediction(struct anthy_context *ac, int nth, char* buf, int buflen) +{ + struct prediction_cache* prediction = &ac->prediction; + int nr_prediction = prediction->nr_prediction; + char* p; + int len; + + if (nth < 0 || nr_prediction <= nth) { + return -1; + } + + p = anthy_xstr_to_cstr(prediction->predictions[nth].str, ac->encoding); + + /* バッファに書き込む */ + len = strlen(p); + if (!buf) { + free(p); + return len; + } + if (len + 1 > buflen) { + free(p); + return -1; + } else { + strcpy(buf, p); + free(p); + return len; + } +} + +/** (API) 予測の結果を確定する + */ +int +anthy_commit_prediction(struct anthy_context *ac, int nth) +{ + struct prediction_cache* pc = &ac->prediction; + if (nth < 0 || nth >= pc->nr_prediction) { + return -1; + } + anthy_do_commit_prediction(pc->predictions[nth].src_str, + pc->predictions[nth].str); + return 0; +} + +/** (API) 開発用 */ +void +anthy_print_context(struct anthy_context *ac) +{ + anthy_do_print_context(ac, default_encoding); +} + +/** (API) Anthy ライブラリのバージョンを表す文字列を返す + * 共有ライブラリでは外部変数のエクスポートは好ましくないので関数にしてある + */ +const char * +anthy_get_version_string (void) +{ +#ifdef VERSION + return VERSION; +#else /* just in case */ + return "(unknown)"; +#endif +} + +/** (API) */ +int +anthy_context_set_encoding(struct anthy_context *ac, int encoding) +{ + if (!ac) { + return ANTHY_EUC_JP_ENCODING; + } + if (encoding == ANTHY_UTF8_ENCODING || + encoding == ANTHY_EUC_JP_ENCODING) { + ac->encoding = encoding; + } + return ac->encoding; +} + +/** (API) */ +int +anthy_set_reconversion_mode(anthy_context_t ac, int mode) +{ + if (!ac) { + return ANTHY_RECONVERT_AUTO; + } + if (mode == ANTHY_RECONVERT_AUTO || + mode == ANTHY_RECONVERT_DISABLE || + mode == ANTHY_RECONVERT_ALWAYS) { + ac->reconversion_mode = mode; + } + return ac->reconversion_mode; +} diff --git a/src-main/main.h b/src-main/main.h new file mode 100644 index 0000000..d5f2df0 --- /dev/null +++ b/src-main/main.h @@ -0,0 +1,68 @@ +#ifndef _main_h_included_ +#define _main_h_included_ + +#include <anthy/xstr.h> +#include <anthy/dic.h> +#include <anthy/splitter.h> +#include <anthy/segment.h> +#include <anthy/ordering.h> +#include <anthy/prediction.h> + +/* + 予測変換の候補のキャッシュ + */ +struct prediction_cache { + /* 予測元の文字列 */ + xstr str; + /* 予測された候補の数 */ + int nr_prediction; + /* 予測された候補 */ + struct prediction_t* predictions; +}; + +/** Anthyの変換コンテキスト + * 変換中の文字列などが入っている + */ +struct anthy_context { + /** コンテキストの持つ文字列 */ + xstr str; + /** 文節のリスト */ + struct segment_list seg_list; + /** 辞書セッション */ + dic_session_t dic_session; + /** splitterの情報 */ + struct splitter_context split_info; + /** 候補の並び替え情報 */ + struct ordering_context_wrapper ordering_info; + /** 予測候補 */ + struct prediction_cache prediction; + /** エンコーディング */ + int encoding; + /** 再変換のモード */ + int reconversion_mode; +}; + + +/* context.c */ +void anthy_init_contexts(void); +void anthy_quit_contexts(void); +void anthy_init_personality(void); +void anthy_quit_personality(void); +int anthy_do_set_personality(const char *id); +struct anthy_context *anthy_do_create_context(int); +int anthy_do_context_set_str(struct anthy_context *c, xstr *x, int is_reverse); +void anthy_do_reset_context(struct anthy_context *c); +void anthy_do_release_context(struct anthy_context *c); + +void anthy_do_resize_segment(struct anthy_context *c,int nth,int resize); + +int anthy_do_set_prediction_str(struct anthy_context *c, xstr *x); +void anthy_release_segment_list(struct anthy_context *ac); +void anthy_save_history(const char *fn, struct anthy_context *ac); + +/* for debug */ +void anthy_do_print_context(struct anthy_context *c, int encoding); + + +#endif +/* なるべく階層をフラットにするよろし */ |