diff Wnn/jlib/jl.c @ 0:bbc77ca4def5

initial import
author Yoshiki Yazawa <yaz@cc.rim.or.jp>
date Thu, 13 Dec 2007 04:30:14 +0900
parents
children 790205f476c0
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Wnn/jlib/jl.c	Thu Dec 13 04:30:14 2007 +0900
@@ -0,0 +1,3671 @@
+/*
+ *  $Id: jl.c,v 1.14 2005/04/10 15:26:37 aonoto Exp $
+ */
+
+/*
+ * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
+ * This file is part of FreeWnn.
+ * 
+ * Copyright Kyoto University Research Institute for Mathematical Sciences
+ *                 1987, 1988, 1989, 1990, 1991, 1992
+ * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
+ * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991, 1992
+ * Copyright FreeWnn Project 1999, 2000, 2002, 2003
+ *
+ * Maintainer:  FreeWnn Project   <freewnn@tomo.gr.jp>
+ *
+ * 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.
+ */
+
+/*
+        Nihongo Henkan Hi-level Library
+*/
+
+#if defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <time.h>
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#else
+#  if HAVE_STRINGS_H
+#    include <strings.h>
+#  endif
+#  if HAVE_MALLOC_H
+#    include <malloc.h>
+#  endif
+#endif /* STDC_HEADERS */
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <pwd.h>
+
+#include "commonhd.h"
+#include "wnn_config.h"
+#include "wnnerror.h"
+#include "jd_sock.h"
+#include "jslib.h"
+#include "jllib.h"
+#include "msg.h"
+#include "wnn_string.h"
+#include "wnn_os.h"
+
+extern struct msg_cat *wnn_msg_cat;
+
+
+#define MAXENVS 32
+
+#define MAXINCLUDE 10
+
+#define DEFAULT_BUN_LEN 3
+
+#define DEFAULT_ZENKOUHO_LEN 3
+
+#define DEFAULT_HEAP_LEN 3
+
+#define INCREMENT 2
+
+#define SHO 0
+#define DAI 1
+
+#define BUN 0
+#define ZENKOUHO 1              /* Must not change!, they are assigned to two bit flag */
+#define ZENKOUHO_DAI 3          /* DAI << 1 | ZENKOUHO */
+
+#define if_dead_disconnect(env, ret) \
+{ \
+        if (wnn_errorno == WNN_JSERVER_DEAD) { \
+                jl_disconnect_if_server_dead(env);\
+                return(ret); \
+        } else { \
+                return(ret); \
+        } \
+}
+
+#define if_dead_disconnect_b(buf, ret) \
+{ \
+        if (wnn_errorno == WNN_JSERVER_DEAD) { \
+                jl_disconnect_if_server_dead(buf->env);\
+                buf->env = 0; \
+                return(ret); \
+        } else { \
+                return(ret); \
+        } \
+}
+
+static struct wnn_ret_buf rb = { 0, NULL };
+static struct wnn_ret_buf dicrb = { 0, NULL };
+static struct wnn_ret_buf wordrb = { 0, NULL };
+
+static int dumbhinsi;
+static w_char *mae_fzk;
+static int syuutanv;
+static int syuutanv1;
+
+#define CONFIRM  1
+#define CONFIRM1 2
+#define CREATE_WITHOUT_CONFIRM  3
+#define NO_CREATE 4
+
+int confirm_state;
+
+static void add_down_bnst ();
+static int alloc_heap ();
+static int call_error_handler ();
+static int change_ascii_to_int ();
+static int create_file ();
+static int dai_end ();
+static int expand_expr ();
+static int expand_expr_all ();
+static int file_discard ();
+static int file_exist ();
+static int file_read ();
+static int file_remove ();
+static int find_same_kouho ();
+static int find_same_kouho_dai ();
+static void free_bun ();
+static void free_down ();
+static void free_sho ();
+static void free_zenkouho ();
+static int get_c_jikouho ();
+static int get_c_jikouho_dai ();
+static int get_c_jikouho_from_zenkouho ();
+static int get_c_jikouho_from_zenkouho_dai ();
+static int get_pwd ();
+static int insert_dai ();
+static int insert_sho ();
+static int make_dir1 ();
+static int make_dir_rec1 ();
+static void make_space_for ();
+static void make_space_for_bun ();
+static void make_space_for_zenkouho ();
+static void message_out ();
+static int ren_conv1 ();
+static void set_dai ();
+static void set_sho ();
+static int tan_conv1 ();
+
+/*
+ * Sub-routines to handle files, enviroments and connections.
+ */
+
+struct wnn_file_name_id
+{
+  struct wnn_file_name_id *next;
+  int id;
+  char name[1];
+};
+
+struct wnn_jl_env
+{
+  WNN_JSERVER_ID *js;
+  struct wnn_env *env;
+  char env_n[WNN_ENVNAME_LEN];
+  char server_n[WNN_HOSTLEN];
+  char lang[32];
+  int ref_cnt;
+  struct wnn_file_name_id *file;
+}
+envs[MAXENVS];
+
+/* 
+ * File management routines.
+ */
+
+static struct wnn_jl_env *
+find_jl_env (env)
+     register struct wnn_env *env;
+{
+  register int k;
+  for (k = 0; k < MAXENVS; k++)
+    {
+      if (envs[k].env == env)
+        return (envs + k);
+    }
+  return (NULL);
+}
+
+
+static struct wnn_env *
+find_env_of_same_js_id (js_id)
+     register WNN_JSERVER_ID *js_id;
+{
+  register int k;
+
+  for (k = 0; k < MAXENVS; k++)
+    {
+      if (envs[k].js == js_id)
+        {
+          return (envs[k].env);
+        }
+    }
+  return (NULL);
+}
+
+static WNN_JSERVER_ID *
+find_same_server (server_n, lang)
+     register char *server_n, *lang;
+{
+  register int k;
+
+  if (server_n == NULL || lang == NULL)
+    return (NULL);
+  for (k = 0; k < MAXENVS; k++)
+    {
+      if (strncmp (envs[k].server_n, server_n, WNN_HOSTLEN - 1) == 0 && strcmp (envs[k].lang, lang) == 0)
+        {
+          return (envs[k].js);
+        }
+    }
+  return (NULL);
+}
+
+static int
+find_same_server_from_id (js)
+     register WNN_JSERVER_ID *js;
+{
+  register int k;
+  for (k = 0; k < MAXENVS; k++)
+    {
+      if (envs[k].js == js)
+        return (1);
+    }
+  return (0);
+}
+
+#ifdef nodef
+static
+delete_server_from_id (js)
+     WNN_JSERVER_ID *js;
+{
+  int k;
+  for (k = 0; k < MAXENVS; k++)
+    {
+      if (envs[k].js == js)
+        {
+          envs[k].js = 0;
+          strcpy (envs[k].server_n, "");
+          break;
+        }
+    }
+}
+#endif
+
+
+static struct wnn_env *
+find_same_env (js, env_n, lang)
+     register WNN_JSERVER_ID *js;
+     register char *env_n;
+     char *lang;
+{
+  register int k;
+
+  if (env_n == NULL || lang == NULL)
+    return (NULL);
+  for (k = 0; k < MAXENVS; k++)
+    {
+      if (envs[k].js == js && strcmp (envs[k].env_n, env_n) == 0 && strcmp (envs[k].lang, lang) == 0)
+        {
+          envs[k].ref_cnt++;
+          return (envs[k].env);
+        }
+    }
+  return (NULL);
+}
+
+static char *
+env_name (env)
+     register struct wnn_env *env;
+{
+  register int k;
+
+  for (k = 0; k < MAXENVS; k++)
+    {
+      if (envs[k].env == env)
+        {
+          return (envs[k].env_n);
+        }
+    }
+  return (NULL);
+}
+
+
+static void
+add_new_env (js, env, env_n, server_n, lang)
+     register WNN_JSERVER_ID *js;
+     register struct wnn_env *env;
+     char *env_n, *server_n, *lang;
+{
+  register int k;
+
+  for (k = 0; k < MAXENVS; k++)
+    {
+      if (envs[k].ref_cnt == 0)
+        {
+          strncpy (envs[k].server_n, server_n, WNN_HOSTLEN - 1);
+          envs[k].server_n[WNN_HOSTLEN - 1] = '\0';
+          strcpy (envs[k].env_n, env_n);
+          strcpy (envs[k].lang, lang);
+          envs[k].js = js;
+          envs[k].env = env;
+          envs[k].ref_cnt = 1;
+          envs[k].file = NULL;
+          break;
+        }
+    }
+}
+
+static int
+delete_env (env)
+     register struct wnn_env *env;
+{
+  register int k;
+
+  for (k = 0; k < MAXENVS; k++)
+    {
+      if (envs[k].env == env)
+        {
+          if (--envs[k].ref_cnt == 0)
+            {
+              strcpy (envs[k].server_n, "");
+              strcpy (envs[k].env_n, "");
+              strcpy (envs[k].lang, "");
+              envs[k].js = NULL;
+              envs[k].env = NULL;
+              return (1);       /* Need To delete env */
+            }
+          else
+            {
+              return (0);       /* Need not to delete env */
+            }
+        }
+    }
+  return (-1);                  /* This must not happen */
+}
+
+
+/* Routines to manipulate files */
+
+static int
+add_file_to_env (env, id, name)
+     struct wnn_env *env;
+     int id;
+     register char *name;
+{
+  register struct wnn_file_name_id *f, *f1;
+  if ((f = (struct wnn_file_name_id *) malloc (sizeof (struct wnn_file_name_id) + strlen (name) + 1)) == NULL)
+    {
+      wnn_errorno = WNN_ALLOC_FAIL;
+      return (-1);
+    }
+  strcpy (f->name, name);
+  f->id = id;
+  f1 = find_jl_env (env)->file;
+  f->next = f1;
+  find_jl_env (env)->file = f;
+  return (0);
+}
+
+static char *
+find_file_name_from_id (env, id)
+     struct wnn_env *env;
+     register int id;
+{
+  register struct wnn_file_name_id *f;
+  f = find_jl_env (env)->file;
+  for (; f; f = f->next)
+    {
+      if (f->id == id)
+        {
+          return (f->name);
+        }
+    }
+/*    wnn_errorno=WNN_FILE_NOT_READ_FROM_CLIENT; */
+  return (NULL);
+}
+
+static int
+delete_file_from_env (env, id)
+     struct wnn_env *env;
+     register int id;
+{
+  struct wnn_file_name_id *f;
+  register struct wnn_file_name_id **prev;
+  register struct wnn_jl_env *jl_env_p;
+
+  jl_env_p = find_jl_env (env);
+  if (!jl_env_p->file)
+    return (0);
+  for (prev = &jl_env_p->file; f = *prev; prev = &f->next)
+    {
+      if (f->id == id)
+        {
+          *prev = f->next;
+          free (f);
+          return (0);
+        }
+    }
+  wnn_errorno = WNN_FILE_NOT_READ_FROM_CLIENT;
+  return (-1);
+}
+
+/*
+ * Libraries which handle Connection To Jserver
+ */
+
+struct wnn_env *
+jl_connect_lang (env_n, server_n, lang, wnnrc_n, error_handler, message_handler, timeout)
+     register char *env_n, *server_n, *wnnrc_n, *lang;
+     int (*error_handler) (), (*message_handler) ();
+     int timeout;
+{
+  register WNN_JSERVER_ID *js = NULL;
+  struct wnn_env *env;
+  int env_exist;
+  char p_lang[16];
+  register char *p, *l;
+  extern char *getenv ();
+  extern char *_wnn_get_machine_of_serv_defs ();
+
+  wnn_errorno = 0;
+  /* if lang not specified use $LANG */
+  if (!lang || !*lang)
+    {
+      lang = getenv ("LANG");
+    }
+  if (!lang || !*lang)
+    {
+/* Sorry! Default is Japanese. :-) */
+      strcpy (p_lang, "ja_JP");
+    }
+  else
+    {
+      /* Use only [language]_[teritorry] */
+      for (p = p_lang, l = lang; *l != '@' && *l != '.' && *l != 0; p++, l++)
+        *p = *l;
+      *p = 0;
+    }
+
+  /* To See serverdefs file when server_n is not specified. */
+  if (!server_n || !*server_n)
+    {
+      /* find server machine name from table by lang */
+      if (server_n = _wnn_get_machine_of_serv_defs (p_lang))
+        {
+          if ((js = find_same_server (server_n, p_lang)) == NULL)
+            {
+              if ((js = js_open_lang (server_n, p_lang, timeout)) == NULL)
+                {
+                  server_n = NULL;
+                }
+            }
+        }
+      if (!server_n || !*server_n)
+        {
+          server_n = "unix";
+        }
+    }
+
+  if (js == NULL)
+    {
+      if ((js = find_same_server (server_n, p_lang)) == NULL)
+        {
+          if ((js = js_open_lang (server_n, p_lang, timeout)) == NULL)
+            {
+              return (NULL);
+            }
+          /*  js_hinsi_list(js); */
+        }
+    }
+  if ((env_exist = js_env_exist (js, env_n)) < 0)
+    return (NULL);
+  if ((env = find_same_env (js, env_n, p_lang)) == NULL)
+    {                           /* Incr ref_cnt */
+      if ((env = js_connect_lang (js, env_n, p_lang)) == NULL)
+        {
+          return (NULL);
+        }
+      add_new_env (js, env, env_n, server_n, p_lang);
+    }
+  if (env_exist == 0 && wnnrc_n)
+    {
+      jl_set_env_wnnrc (env, wnnrc_n, error_handler, message_handler);
+    }
+  return (env);
+}
+
+void
+jl_disconnect (env)
+     register struct wnn_env *env;
+{
+  int ret;
+  wnn_errorno = 0;
+  if ((ret = delete_env (env)) < 0)
+    {
+      return;
+    }
+  else if (ret)
+    {
+      js_disconnect (env);
+    }
+  if (!find_same_server_from_id (env->js_id))
+    {
+      js_close (env->js_id);
+      env->js_id = 0;
+    }
+}
+
+int
+jl_isconnect_e (env)
+     register struct wnn_env *env;
+{
+  if (js_isconnect (env) == 0)
+    return (1);
+  else
+    return (0);
+}
+
+/* JSERVER が死んだら env を disconnect して回る */
+void
+jl_disconnect_if_server_dead (env)
+     register struct wnn_env *env;
+{
+  register struct wnn_env *same_env;
+  int ret;
+
+  if ((ret = delete_env (env)) < 0)
+    {
+      return;
+    }
+  else if (ret)
+    {
+      js_disconnect (env);
+    }
+  while ((same_env = find_env_of_same_js_id (env->js_id)) != 0)
+    {
+      if (delete_env (same_env))
+        {
+          js_disconnect (same_env);
+        }
+
+    }
+  js_close (env->js_id);
+  env->js_id = 0;
+}
+
+
+struct wnn_buf *
+jl_open_lang (env_n, server_n, lang, wnnrc_n, error_handler, message_handler, timeout)
+     char *env_n, *server_n, *wnnrc_n, *lang;
+     int (*error_handler) (), (*message_handler) ();
+     int timeout;
+{
+  register int k, dmy;
+  register struct wnn_buf *buf;
+  struct wnn_env *env;
+
+  wnn_errorno = 0;
+  if (rb.size == 0)
+    rb.buf = (char *) malloc ((unsigned) (rb.size = 1024));
+
+#define ALLOC_SET(pter, type, size, size_var) \
+    ((pter) = ((type *)malloc((unsigned)(sizeof(type) * ((size_var) = (size))))))
+
+  if (!ALLOC_SET (buf, struct wnn_buf, 1, dmy))
+    {
+      wnn_errorno = WNN_ALLOC_FAIL;
+      return NULL;
+    }
+
+  buf->bun_suu = 0;
+  buf->zenkouho_suu = 0;
+  buf->zenkouho_daip = 0;
+  buf->c_zenkouho = -1;
+  buf->zenkouho_bun = -1;
+  buf->zenkouho_end_bun = -1;
+  buf->free_heap = NULL;
+  buf->heap = NULL;
+  buf->zenkouho_dai_suu = 0;
+
+  if (!ALLOC_SET (buf->bun, WNN_BUN *, DEFAULT_BUN_LEN, buf->msize_bun) ||
+      !ALLOC_SET (buf->zenkouho_dai, int, DEFAULT_ZENKOUHO_LEN + 1, buf->msize_zenkouho) ||
+      !ALLOC_SET (buf->zenkouho, WNN_BUN *, DEFAULT_ZENKOUHO_LEN, buf->msize_zenkouho) || !ALLOC_SET (buf->down_bnst, WNN_BUN *, DEFAULT_BUN_LEN, buf->msize_bun))
+    {
+      wnn_errorno = WNN_ALLOC_FAIL;
+      return NULL;
+    }
+
+  for (k = 0; k < DEFAULT_BUN_LEN; k++)
+    {
+      buf->down_bnst[k] = NULL;
+    }
+
+  if (alloc_heap (buf, DEFAULT_HEAP_LEN) == -1)
+    {
+      return NULL;
+    }
+
+  env = jl_connect_lang (env_n, server_n, lang, wnnrc_n, error_handler, message_handler, timeout);
+  buf->env = env;
+  return (buf);
+}
+
+
+static int
+alloc_heap (buf, len)
+     struct wnn_buf *buf;
+     register int len;
+{
+  char **c;
+  register WNN_BUN *d;
+
+  if ((c = (char **) malloc ((unsigned) (len * sizeof (WNN_BUN) + sizeof (char *)))) == NULL)
+    {
+      wnn_errorno = WNN_ALLOC_FAIL;
+      return (-1);
+    }
+
+  *c = buf->heap;
+  buf->heap = (char *) c;
+  d = (WNN_BUN *) (c + 1);
+  for (--len; len > 0; len--, d++)
+    {
+      d->free_next = d + 1;
+    }
+  d->free_next = buf->free_heap;
+  buf->free_heap = (WNN_BUN *) (c + 1);
+  return (0);
+}
+
+void
+jl_close (buf)
+     register struct wnn_buf *buf;
+{
+  register char *c, *next;
+
+  wnn_errorno = 0;
+  if (buf == NULL)
+    return;
+
+  if (buf->env)
+    {
+      jl_disconnect (buf->env);
+      buf->env = 0;
+    }
+
+  if (buf->bun)
+    free ((char *) buf->bun);
+  if (buf->zenkouho)
+    free ((char *) buf->zenkouho);
+  if (buf->zenkouho_dai)
+    free ((char *) buf->zenkouho_dai);
+  if (buf->down_bnst)
+    free ((char *) buf->down_bnst);
+  for (c = buf->heap; c; c = next)
+    {
+      next = *(char **) c;
+      free (c);
+    }
+  free ((char *) buf);
+}
+
+/*
+ * Conversion Libraries 
+ */
+
+int
+jl_ren_conv (buf, yomi, bun_no, bun_no2, use_maep)
+     register struct wnn_buf *buf;
+     register w_char *yomi;
+     int bun_no, bun_no2;
+     int use_maep;
+{
+  wnn_errorno = 0;
+  if (bun_no < 0)
+    return (-1);
+  if (bun_no2 >= buf->bun_suu || bun_no2 < 0)
+    bun_no2 = buf->bun_suu;
+  free_down (buf, bun_no, bun_no2);
+  return (ren_conv1 (buf, yomi, bun_no, bun_no2, use_maep));
+}
+
+static int
+ren_conv1 (buf, yomi, bun_no, bun_no2, use_maep)
+     register struct wnn_buf *buf;
+     w_char *yomi;
+     register int bun_no, bun_no2;
+     int use_maep;
+{
+  int dcnt;
+  struct wnn_dai_bunsetsu *dp;
+  int size;
+  w_char yomi1[LENGTHBUNSETSU];
+
+
+  if (yomi == NULL || *yomi == (w_char) 0)
+    return (0);
+  if (bun_no2 >= buf->bun_suu || bun_no2 < 0)
+    bun_no2 = buf->bun_suu;
+
+  if (use_maep & WNN_USE_MAE && bun_no > 0)
+    {
+      dumbhinsi = buf->bun[bun_no - 1]->hinsi;
+      jl_get_yomi (buf, bun_no - 1, bun_no, yomi1);
+      mae_fzk = yomi1 + buf->bun[bun_no - 1]->jirilen;
+    }
+  else
+    {
+      dumbhinsi = WNN_BUN_SENTOU;
+      mae_fzk = (w_char *) 0;
+    }
+  if (use_maep & WNN_USE_ATO && bun_no2 < buf->bun_suu)
+    {
+      syuutanv = buf->bun[bun_no2]->kangovect;
+      syuutanv1 = WNN_VECT_KANREN;
+    }
+  else
+    {
+      syuutanv = WNN_VECT_KANREN;
+      syuutanv1 = WNN_VECT_NO;
+      if (bun_no2 < buf->bun_suu)
+        {
+          buf->bun[bun_no2]->dai_top = 1;
+        }
+    }
+  if ((dcnt = js_kanren (buf->env, yomi, dumbhinsi, mae_fzk, syuutanv, syuutanv1, WNN_VECT_BUNSETSU, &rb)) < 0)
+    {
+      if_dead_disconnect_b (buf, -1);
+    }
+
+  dp = (struct wnn_dai_bunsetsu *) rb.buf;
+
+  free_bun (buf, bun_no, bun_no2);
+
+  if (use_maep & WNN_USE_ATO && bun_no2 < buf->bun_suu)
+    {
+      buf->bun[bun_no2]->dai_top = (dp[dcnt - 1].sbn[dp[dcnt - 1].sbncnt - 1].status_bkwd == WNN_CONNECT_BK) ? 0 : 1;
+    }
+
+  size = insert_dai (buf, BUN, bun_no, bun_no2, dp, dcnt, 0);
+  if (buf->zenkouho_end_bun > bun_no && buf->zenkouho_bun < bun_no2)
+    {
+      free_zenkouho (buf);
+    }
+  else if (buf->zenkouho_bun >= bun_no2)
+    {
+      buf->zenkouho_bun += size - bun_no2;
+      buf->zenkouho_end_bun += size - bun_no2;
+
+    }
+  return (buf->bun_suu);
+}
+
+int
+jl_tan_conv (buf, yomi, bun_no, bun_no2, use_maep, ich_shop)
+     register struct wnn_buf *buf;
+     w_char *yomi;
+     register int bun_no, bun_no2;
+     int use_maep, ich_shop;
+{
+  wnn_errorno = 0;
+  if (bun_no < 0)
+    return (-1);
+  if (bun_no2 >= buf->bun_suu || bun_no2 < 0)
+    bun_no2 = buf->bun_suu;
+  free_down (buf, bun_no, bun_no2);
+  if (tan_conv1 (buf, yomi, bun_no, bun_no2, use_maep, ich_shop) == -1)
+    return (-1);
+  return (buf->bun_suu);
+}
+
+static int
+tan_conv1 (buf, yomi, bun_no, bun_no2, use_maep, ich_shop)
+     register struct wnn_buf *buf;
+     w_char *yomi;
+     register int bun_no, bun_no2;
+     int use_maep, ich_shop;
+{
+  int dcnt;
+  struct wnn_dai_bunsetsu *dp;
+  struct wnn_sho_bunsetsu *sp;
+  int ret;
+  w_char yomi1[LENGTHBUNSETSU];
+
+  if (yomi == NULL || *yomi == (w_char) 0)
+    return (0);
+  if (bun_no2 >= buf->bun_suu || bun_no2 < 0)
+    bun_no2 = buf->bun_suu;
+
+  if (use_maep & WNN_USE_MAE && bun_no > 0)
+    {
+      dumbhinsi = buf->bun[bun_no - 1]->hinsi;
+      jl_get_yomi (buf, bun_no - 1, bun_no, yomi1);
+      mae_fzk = yomi1 + buf->bun[bun_no - 1]->jirilen;
+    }
+  else
+    {
+      dumbhinsi = WNN_BUN_SENTOU;
+      mae_fzk = (w_char *) 0;
+    }
+  if (use_maep & WNN_USE_ATO && bun_no2 < buf->bun_suu)
+    {
+      syuutanv = buf->bun[bun_no2]->kangovect;
+      syuutanv1 = WNN_VECT_KANTAN;
+    }
+  else
+    {
+      syuutanv = WNN_VECT_KANTAN;
+      syuutanv1 = WNN_VECT_NO;
+      if (bun_no2 < buf->bun_suu)
+        {
+          buf->bun[bun_no2]->dai_top = 1;
+        }
+    }
+  if (ich_shop == WNN_SHO)
+    {
+      if ((dcnt = js_kantan_sho (buf->env, yomi, dumbhinsi, mae_fzk, syuutanv, syuutanv1, &rb)) < 0)
+        {
+          if_dead_disconnect_b (buf, -1);
+        }
+      sp = (struct wnn_sho_bunsetsu *) rb.buf;
+      if (use_maep & WNN_USE_ATO && bun_no2 < buf->bun_suu)
+        {
+          buf->bun[bun_no2]->dai_top = (sp[dcnt - 1].status_bkwd == WNN_CONNECT_BK) ? 0 : 1;
+        }
+      free_bun (buf, bun_no, bun_no2);
+      ret = insert_sho (buf, BUN, bun_no, bun_no2, sp, dcnt, 0);
+    }
+  else
+    {
+      if ((dcnt = js_kantan_dai (buf->env, yomi, dumbhinsi, mae_fzk, syuutanv, syuutanv1, &rb)) < 0)
+        {
+          if_dead_disconnect_b (buf, -1);
+        }
+      dp = (struct wnn_dai_bunsetsu *) rb.buf;
+      if (use_maep & WNN_USE_ATO && bun_no2 < buf->bun_suu)
+        {
+          buf->bun[bun_no2]->dai_top = (dp[dcnt - 1].sbn[dp[dcnt - 1].sbncnt - 1].status_bkwd == WNN_CONNECT_BK) ? 0 : 1;
+        }
+      free_bun (buf, bun_no, bun_no2);
+      ret = insert_dai (buf, BUN, bun_no, bun_no2, dp, dcnt, 0);
+    }
+  if (buf->zenkouho_end_bun > bun_no && buf->zenkouho_bun < bun_no2)
+    {
+      free_zenkouho (buf);
+    }
+  else if (buf->zenkouho_bun >= bun_no2)
+    {
+      buf->zenkouho_bun += ret - bun_no2;
+      buf->zenkouho_end_bun += ret - bun_no2;
+    }
+  return (ret);
+}
+
+int
+jl_nobi_conv (buf, bun_no, ichbn_len, bun_no2, use_maep, ich_shop)
+     register struct wnn_buf *buf;
+     int ichbn_len, use_maep, ich_shop;
+     register int bun_no, bun_no2;
+{
+  w_char yomi[LENGTHCONV], ytmp;
+  int ret;
+  int len1;
+
+  register WNN_BUN *b1;         /* 学習がうまくいくように変更しました。H.T. */
+
+  wnn_errorno = 0;
+  if (bun_no < 0)
+    return (-1);
+  if (bun_no2 >= buf->bun_suu || bun_no2 < 0)
+    bun_no2 = buf->bun_suu;
+
+  len1 = jl_get_yomi (buf, bun_no, bun_no2, yomi);
+  ytmp = yomi[ichbn_len];
+  if (len1 < ichbn_len)
+    {
+      ichbn_len = len1;
+    }
+  yomi[ichbn_len] = 0;
+
+  if (buf->bun[bun_no]->nobi_top != 1)
+    {                           /* need to add down_bnst */
+      if (buf->bun[bun_no])
+        add_down_bnst (buf, bun_no, buf->bun[bun_no]);
+      if (bun_no + 1 < buf->bun_suu)
+        {
+          add_down_bnst (buf, bun_no, buf->bun[bun_no + 1]);
+          /* 全て bun_no の down_bnst に加えるように変更 */
+        }
+    }
+  b1 = buf->down_bnst[bun_no];
+  buf->down_bnst[bun_no] = NULL;
+  free_down (buf, bun_no, bun_no2);
+
+  if ((ret = tan_conv1 (buf, yomi, bun_no, bun_no2, use_maep & WNN_USE_MAE, ich_shop)) == -1)
+    {
+      return (-1);
+    }
+  yomi[ichbn_len] = ytmp;
+  if (ytmp)
+    {
+      int maep;
+      if (ich_shop)
+        {
+          maep = use_maep & ~WNN_USE_MAE;
+        }
+      else
+        {
+          maep = use_maep | WNN_USE_MAE;
+        }
+      if (ren_conv1 (buf, yomi + ichbn_len, ret, ret, maep) == -1)
+        {
+          return (-1);
+        }
+    }
+  buf->bun[bun_no]->nobi_top = 1;
+  buf->down_bnst[bun_no] = b1;
+
+  return (buf->bun_suu);
+}
+
+int
+jl_nobi_conv_e2 (buf, env, bun_no, ichbn_len, bun_no2, use_maep, ich_shop)
+     register struct wnn_buf *buf;
+     struct wnn_env *env;
+     int ichbn_len, use_maep, ich_shop;
+     register int bun_no, bun_no2;
+{
+  w_char yomi[LENGTHCONV], ytmp;
+  int ret;
+  int len1;
+
+  wnn_errorno = 0;
+  if (bun_no < 0)
+    return (-1);
+  if (bun_no2 >= buf->bun_suu || bun_no2 < 0)
+    bun_no2 = buf->bun_suu;
+
+  len1 = jl_get_yomi (buf, bun_no, bun_no2, yomi);
+  ytmp = yomi[ichbn_len];
+  if (len1 < ichbn_len)
+    {
+      ichbn_len = len1;
+    }
+  yomi[ichbn_len] = 0;
+
+  if (buf->bun[bun_no]->nobi_top != 1)
+    {                           /* need to add down_bnst */
+      if (buf->bun[bun_no])
+        add_down_bnst (buf, bun_no, buf->bun[bun_no]);
+      if (bun_no + 1 < buf->bun_suu)
+        {
+          if (ichbn_len < jl_yomi_len (buf, bun_no, bun_no + 1))
+            {
+              add_down_bnst (buf, bun_no + 1, buf->bun[bun_no + 1]);
+              free_down (buf, bun_no + 2, bun_no2);
+            }
+          else
+            {
+              add_down_bnst (buf, bun_no, buf->bun[bun_no + 1]);
+              free_down (buf, bun_no + 1, bun_no2);
+            }
+        }
+    }
+
+  if ((ret = tan_conv1 (buf, yomi, bun_no, bun_no2, use_maep & WNN_USE_MAE, ich_shop)) == -1)
+    {
+      return (-1);
+    }
+
+  buf->env = env;
+
+  yomi[ichbn_len] = ytmp;
+  if (ytmp)
+    {
+      int maep;
+      if (ich_shop)
+        {
+          maep = use_maep & ~WNN_USE_MAE;
+        }
+      else
+        {
+          maep = use_maep | WNN_USE_MAE;
+        }
+      if (ren_conv1 (buf, yomi + ichbn_len, ret, ret, maep) == -1)
+        {
+          return (-1);
+        }
+    }
+  buf->bun[bun_no]->nobi_top = 1;
+
+  return (buf->bun_suu);
+}
+
+int
+jl_kill (buf, bun_no, bun_no2)
+     struct wnn_buf *buf;
+     register int bun_no, bun_no2;
+{
+  wnn_errorno = 0;
+  if (bun_no < 0)
+    return (0);
+  if (bun_no2 < bun_no || bun_no2 < 0)
+    bun_no2 = buf->bun_suu;
+  free_zenkouho (buf);          /* toriaezu */
+  free_down (buf, bun_no, bun_no2);
+  free_bun (buf, bun_no, bun_no2);
+  bcopy ((char *) &buf->bun[bun_no2], (char *) &buf->bun[bun_no], (buf->bun_suu - bun_no2) * sizeof (WNN_BUN *));
+  bcopy ((char *) &buf->down_bnst[bun_no2], (char *) &buf->down_bnst[bun_no], (buf->bun_suu - bun_no2) * sizeof (WNN_BUN *));
+  buf->bun_suu -= bun_no2 - bun_no;
+  return (buf->bun_suu);
+}
+
+int
+jl_zenkouho (buf, bun_no, use_maep, uniq_level)
+     register struct wnn_buf *buf;
+     int bun_no, use_maep, uniq_level;
+{
+  int cnt;
+  w_char yomi[LENGTHBUNSETSU], yomi1[LENGTHBUNSETSU];
+  struct wnn_sho_bunsetsu *sp;
+  register int k;
+
+  wnn_errorno = 0;
+  jl_get_yomi (buf, bun_no, bun_no + 1, yomi);
+
+  if (bun_no == buf->zenkouho_bun && buf->zenkouho_daip == SHO)
+    return (buf->c_zenkouho);
+  if (use_maep & WNN_USE_MAE && bun_no > 0)
+    {
+      dumbhinsi = buf->bun[bun_no - 1]->hinsi;
+      jl_get_yomi (buf, bun_no - 1, bun_no, yomi1);
+      mae_fzk = yomi1 + buf->bun[bun_no - 1]->jirilen;
+    }
+  else
+    {
+      dumbhinsi = WNN_BUN_SENTOU;
+      mae_fzk = (w_char *) 0;
+    }
+  if (use_maep & WNN_USE_ATO && bun_no + 1 < buf->bun_suu)
+    {
+
+      syuutanv = buf->bun[bun_no + 1]->kangovect;
+      syuutanv1 = WNN_VECT_KANZEN;
+      buf->zenkouho_endvect = syuutanv;
+    }
+  else
+    {
+      syuutanv = WNN_VECT_KANZEN;
+      syuutanv1 = WNN_VECT_NO;
+      if (bun_no + 1 < buf->bun_suu)
+        {
+          buf->bun[bun_no + 1]->dai_top = 1;
+        }
+      buf->zenkouho_endvect = -1;
+    }
+  if ((cnt = js_kanzen_sho (buf->env, yomi, dumbhinsi, mae_fzk, syuutanv, syuutanv1, &rb)) < 0)
+    {
+      if_dead_disconnect_b (buf, -1);
+    }
+
+  sp = (struct wnn_sho_bunsetsu *) rb.buf;
+  free_zenkouho (buf);
+  if ((buf->bun[bun_no]->from_zenkouho & 1) == BUN)
+    {
+      set_sho (buf->bun[bun_no], &buf->zenkouho[0]);
+      buf->zenkouho_suu = 1;
+      /* Connection information of Old bunsetsu
+       * May not be correct.
+       */
+      k = get_c_jikouho (sp, cnt, buf->bun[bun_no]);
+      if (k >= 0)
+        {
+          buf->zenkouho[0]->dai_top = (sp[k].status == WNN_CONNECT) ? 0 : 1;
+          buf->zenkouho[0]->dai_end = (sp[k].status_bkwd == WNN_CONNECT_BK) ? 0 : 1;
+        }
+      if (uniq_level || k < 0)
+        {
+          insert_sho (buf, ZENKOUHO, -1, -1, sp, cnt, uniq_level);
+        }
+      else
+        {
+          insert_sho (buf, ZENKOUHO, -1, -1, sp, k, uniq_level);
+          insert_sho (buf, ZENKOUHO, -1, -1, sp + k + 1, cnt - k - 1, uniq_level);
+        }
+      buf->c_zenkouho = 0;
+    }
+  else
+    {
+      insert_sho (buf, ZENKOUHO, -1, -1, sp, cnt, uniq_level);
+      k = get_c_jikouho_from_zenkouho (buf, buf->bun[bun_no]);
+      if (k < 0)
+        {
+          k = 0;                /* Only when the kouho has been removed from dict. */
+        }
+      buf->c_zenkouho = k;
+    }
+  buf->zenkouho_bun = bun_no;
+  buf->zenkouho_end_bun = bun_no + 1;
+  buf->zenkouho_daip = SHO;
+  for (k = 0; k < buf->zenkouho_suu; k++)
+    {
+      if (buf->zenkouho[k]->ima && buf->zenkouho[k]->dic_no != -1)
+        {
+          add_down_bnst (buf, bun_no, buf->zenkouho[k]);
+        }
+    }
+  return (buf->c_zenkouho);
+}
+
+int
+jl_zenkouho_dai (buf, bun_no, bun_no2, use_maep, uniq_level)
+     register struct wnn_buf *buf;
+     int bun_no, bun_no2, use_maep, uniq_level;
+{
+  int cnt;
+  w_char yomi[LENGTHBUNSETSU], yomi1[LENGTHBUNSETSU];
+  struct wnn_dai_bunsetsu *dp;
+  int tmp;
+  register int k;
+
+  wnn_errorno = 0;
+  if (bun_no2 > (tmp = dai_end (buf, bun_no)) || bun_no2 < 0)
+    bun_no2 = tmp;
+  jl_get_yomi (buf, bun_no, bun_no2, yomi);
+
+  if (bun_no == buf->zenkouho_bun && buf->zenkouho_daip == DAI)
+    {
+      return (buf->c_zenkouho);
+    }
+  if (use_maep & WNN_USE_MAE && bun_no > 0)
+    {
+      dumbhinsi = buf->bun[bun_no - 1]->hinsi;
+      jl_get_yomi (buf, bun_no - 1, bun_no, yomi1);
+      mae_fzk = yomi1 + buf->bun[bun_no - 1]->jirilen;
+    }
+  else
+    {
+      dumbhinsi = WNN_BUN_SENTOU;
+      mae_fzk = (w_char *) 0;
+    }
+  if (use_maep & WNN_USE_ATO && bun_no2 < buf->bun_suu)
+    {
+      syuutanv = buf->bun[bun_no2]->kangovect;
+      syuutanv1 = WNN_VECT_KANZEN;
+      buf->zenkouho_endvect = syuutanv;
+    }
+  else
+    {
+      syuutanv = WNN_VECT_KANZEN;
+      syuutanv1 = WNN_VECT_NO;
+      if (bun_no2 < buf->bun_suu)
+        {
+          buf->bun[bun_no2]->dai_top = 1;
+        }
+      buf->zenkouho_endvect = -1;
+    }
+  if ((cnt = js_kanzen_dai (buf->env, yomi, dumbhinsi, mae_fzk, syuutanv, syuutanv1, &rb)) < 0)
+    {
+      if_dead_disconnect_b (buf, -1);
+    }
+  dp = (struct wnn_dai_bunsetsu *) rb.buf;
+
+  free_zenkouho (buf);
+  /* Wander if it is OK, that is, only when all the
+   * zenkouho's are got from zenkouho_dai, we need not move
+   * the current dai-bunsetsu to the top of zenkouho's
+   */
+  for (k = bun_no; k < bun_no2; k++)
+    {
+      if (buf->bun[k]->from_zenkouho != ZENKOUHO_DAI)
+        break;
+    }
+  if (k != bun_no2)
+    {                           /* move the current to the top. */
+      make_space_for (buf, ZENKOUHO, buf->zenkouho_suu, buf->zenkouho_suu, bun_no2 - bun_no);
+      set_dai (&buf->bun[bun_no], &buf->zenkouho[0], bun_no2 - bun_no);
+      buf->zenkouho_dai[0] = 0;
+      buf->zenkouho_dai[1] = bun_no2 - bun_no;
+      buf->zenkouho_dai_suu = 1;
+      buf->zenkouho_suu = bun_no2 - bun_no;
+      k = get_c_jikouho_dai (dp, cnt, buf->bun, bun_no);
+      if (k >= 0)
+        {
+          buf->zenkouho[0]->dai_top = (dp[k].sbn->status == WNN_CONNECT) ? 0 : 1;
+          buf->zenkouho[bun_no2 - bun_no - 1]->dai_end = (dp[k].sbn[dp[k].sbncnt - 1].status_bkwd == WNN_CONNECT_BK) ? 0 : 1;
+/* KURI *//* USO*? */
+        }
+      if (uniq_level || k < 0)
+        {
+          insert_dai (buf, ZENKOUHO, -1, -1, dp, cnt, uniq_level);
+        }
+      else
+        {
+          insert_dai (buf, ZENKOUHO, -1, -1, dp, k, uniq_level);
+          insert_dai (buf, ZENKOUHO, -1, -1, dp + k + 1, cnt - k - 1, uniq_level);
+        }
+      buf->c_zenkouho = 0;
+    }
+  else
+    {
+      insert_dai (buf, ZENKOUHO, -1, -1, dp, cnt, uniq_level);
+      k = get_c_jikouho_from_zenkouho_dai (buf, buf->bun[bun_no]);
+      if (k < 0)
+        {
+          k = 0;                /* Only when the kouho has been removed from dict. */
+        }
+      buf->c_zenkouho = k;
+    }
+  buf->zenkouho_bun = bun_no;
+  buf->zenkouho_end_bun = bun_no2;
+  buf->zenkouho_daip = DAI;
+  for (k = 0; k < buf->zenkouho_suu; k++)
+    {
+      if (buf->zenkouho[k]->ima && buf->zenkouho[k]->dic_no != -1)
+        {
+          add_down_bnst (buf, bun_no, buf->zenkouho[k]);
+        }
+    }
+  return (buf->c_zenkouho);
+}
+
+int
+jl_set_jikouho (buf, offset)
+     register struct wnn_buf *buf;
+     register int offset;
+{
+  wnn_errorno = 0;
+  if (buf->zenkouho_suu <= 0)
+    return (-1);
+  if (buf->zenkouho_daip != SHO)
+    {
+      return (-1);
+    }
+  offset = (offset + buf->zenkouho_suu) % buf->zenkouho_suu;
+  if (buf->zenkouho_bun + 1 < buf->bun_suu && buf->zenkouho_endvect != -1)
+    buf->bun[buf->zenkouho_bun + 1]->dai_top = buf->zenkouho[offset]->dai_end;
+  free_sho (buf, &buf->bun[buf->zenkouho_bun]);
+  set_sho (buf->zenkouho[offset], &buf->bun[buf->zenkouho_bun]);
+  buf->c_zenkouho = offset;
+  return (offset);
+}
+
+
+int
+jl_set_jikouho_dai (buf, offset)
+     register struct wnn_buf *buf;
+     int offset;
+{
+  register int st, end, bun, k;
+
+  wnn_errorno = 0;
+  if (buf->zenkouho_suu <= 0)
+    return (-1);
+  if (buf->zenkouho_daip != DAI)
+    {
+      return (-1);
+    }
+  offset = (offset + buf->zenkouho_dai_suu) % buf->zenkouho_dai_suu;
+  if (buf->zenkouho_end_bun < buf->bun_suu && buf->zenkouho_endvect != -1)
+    buf->bun[buf->zenkouho_end_bun]->dai_top = buf->zenkouho[buf->zenkouho_dai[offset + 1] - 1]->dai_end;
+  free_bun (buf, buf->zenkouho_bun, buf->zenkouho_end_bun);
+  st = buf->zenkouho_dai[offset];
+  end = buf->zenkouho_dai[offset + 1];
+  make_space_for (buf, BUN, buf->zenkouho_bun, buf->zenkouho_end_bun, end - st);
+  for (bun = buf->zenkouho_bun, k = st; k < end;)
+    {
+      set_sho (buf->zenkouho[k++], &buf->bun[bun++]);
+    }
+  buf->zenkouho_end_bun = buf->zenkouho_bun + end - st;
+  buf->c_zenkouho = offset;
+  return (offset);
+}
+
+int
+jl_update_hindo (buf, bun_no, bun_no2)
+     register struct wnn_buf *buf;
+     int bun_no, bun_no2;
+{
+  register int k;
+  register WNN_BUN *wb;
+
+  wnn_errorno = 0;
+  if (bun_no < 0)
+    return (-1);
+  if (bun_no2 >= buf->bun_suu || bun_no2 < 0)
+    bun_no2 = buf->bun_suu;
+
+#ifdef JL_DEBUG
+  printf ("\t\tDown Hindo\n");
+#endif
+  for (k = bun_no; k < bun_no2; k++)
+    {
+      if (buf->bun[k]->hindo_updated == 1)
+        continue;
+      for (wb = buf->down_bnst[k]; wb; wb = wb->down)
+        {
+          if (wb->bug == 1)
+            break;
+          wb->bug = 1;
+          if (wb->dic_no != -1)
+            {
+              if (js_hindo_set (buf->env, wb->dic_no, wb->entry, WNN_IMA_OFF, WNN_HINDO_NOP) == -1)
+                {
+                  if (wnn_errorno == WNN_JSERVER_DEAD)
+                    {
+                      jl_disconnect (buf->env);
+                      buf->env = 0;
+                      return (-1);
+                    }
+                }
+#ifdef JL_DEBUG
+              display_bun (wb);
+#endif
+            }
+        }
+    }
+  free_down (buf, bun_no, bun_no2);
+
+#ifdef JL_DEBUG
+  printf ("\t\tUp Hindo\n");
+#endif
+  for (k = bun_no; k < bun_no2; k++)
+    {
+      if (buf->bun[k]->hindo_updated == 1)
+        continue;
+      buf->bun[k]->hindo_updated = 1;
+      wb = buf->bun[k];
+#ifdef JL_DEBUG
+      display_bun (wb);
+#endif
+      if (js_hindo_set (buf->env, wb->dic_no, wb->entry, WNN_IMA_ON, WNN_HINDO_INC) == -1)
+        {
+          if (wnn_errorno == WNN_JSERVER_DEAD)
+            {
+              jl_disconnect (buf->env);
+              buf->env = 0;
+              return (-1);
+            }
+        }
+    }
+  return (0);
+}
+
+
+static w_char *
+wnn_area (bp, area, kanjip)
+     WNN_BUN *bp;
+     w_char *area;
+     int kanjip;
+{
+  register WNN_BUN *bp1;
+  register w_char *c, *end;
+
+  for (bp1 = bp; bp1; bp1 = bp1->next)
+    {
+      if (bp1 != bp)
+        c = (w_char *) bp1;
+      else
+        c = bp1->yomi;
+      end = (w_char *) & bp1->next;
+      for (; c < end;)
+        {
+          if (!kanjip)
+            {
+              if ((*area++ = *c++) == 0)
+                {
+                  area--;
+                  goto out;
+                }
+            }
+          else
+            {
+              if (*c++ == 0)
+                kanjip--;
+            }
+        }
+    }
+out:
+  return (area);
+}
+
+static int
+dai_end (buf, bun_no)
+     register struct wnn_buf *buf;
+     register int bun_no;
+{
+  bun_no++;
+  for (; bun_no < buf->bun_suu && !buf->bun[bun_no]->dai_top; bun_no++);
+  return (bun_no);
+}
+
+#define dai_end_zenkouho(buf, bun_no) (buf->zenkouho_dai[bun_no + 1])
+
+#ifdef  CONVERT_by_STROKE
+/* 筆形 (Bi Xing) */
+void
+jl_get_zenkouho_yomi (buf, zen_num, area)
+     register struct wnn_buf *buf;
+     int zen_num;
+     w_char *area;
+{
+  register int k, end;
+
+  wnn_errorno = 0;
+  if (!buf->zenkouho_daip)
+    {
+      wnn_area (buf->zenkouho[zen_num], area, WNN_YOMI);
+    }
+  else
+    {
+      end = dai_end_zenkouho (buf, zen_num);
+      for (k = buf->zenkouho_dai[zen_num]; k < end; k++)
+        {
+          area = wnn_area (buf->zenkouho[k], area, WNN_KANJI);
+        }
+    }
+}
+#endif
+
+void
+jl_get_zenkouho_kanji (buf, zen_num, area)
+     register struct wnn_buf *buf;
+     int zen_num;
+     w_char *area;
+{
+  register int k, end;
+
+  wnn_errorno = 0;
+  if (!buf->zenkouho_daip)
+    {
+      wnn_area (buf->zenkouho[zen_num], area, WNN_KANJI);
+    }
+  else
+    {
+      end = dai_end_zenkouho (buf, zen_num);
+      for (k = buf->zenkouho_dai[zen_num]; k < end; k++)
+        {
+          area = wnn_area (buf->zenkouho[k], area, WNN_KANJI);
+        }
+    }
+}
+
+int
+wnn_get_area (buf, bun_no, bun_no2, area, kanjip)
+     struct wnn_buf *buf;
+     register int bun_no, bun_no2;
+     w_char *area;
+     int kanjip;
+{
+  register int k;
+  w_char *area1 = area;
+
+  if (bun_no < 0)
+    return (0);
+  if (bun_no2 >= buf->bun_suu || bun_no2 < 0)
+    bun_no2 = buf->bun_suu;
+
+  for (k = bun_no; k < bun_no2; k++)
+    {
+      area = wnn_area (buf->bun[k], area, kanjip);
+    }
+  return (area - area1);
+}
+
+#define JISHO 1
+#define HINDO 2
+
+/*********************************/
+int
+jl_dic_add_e (env, dic_name, hindo_name, rev, prio, rw, hrw, pwd_dic, pwd_hindo, error_handler, message_handler)
+     register struct wnn_env *env;
+     char *dic_name;
+     char *hindo_name;
+     int prio;
+     int rw, hrw, rev;
+     char *pwd_dic, *pwd_hindo;
+     int (*error_handler) (), (*message_handler) ();
+{
+  char tmp[256];
+  char pwd[WNN_PASSWD_LEN], hpwd[WNN_PASSWD_LEN];
+  int fid, hfid = -1;
+  register int ret;
+
+
+  if (file_exist (env, dic_name) == -1)
+    {
+      if (wnn_errorno == WNN_JSERVER_DEAD)
+        {
+          jl_disconnect (env);
+          return (-1);
+        }
+      if ((int) error_handler == WNN_NO_CREATE || (rw == WNN_DIC_RDONLY))
+        {
+          sprintf (tmp, "%s \"%s\" %s", msg_get (wnn_msg_cat, 200, NULL, env->lang), dic_name, msg_get (wnn_msg_cat, 201, NULL, env->lang));
+          /*
+             "辞書ファイル \"%s\" が無いよ。",
+           */
+          message_out (message_handler, tmp);
+          wnn_errorno = WNN_NO_EXIST;
+          return (-1);
+        }
+      sprintf (tmp, "%s \"%s\" %s%s", msg_get (wnn_msg_cat, 200, NULL, env->lang), dic_name, msg_get (wnn_msg_cat, 201, NULL, env->lang), msg_get (wnn_msg_cat, 202, NULL, env->lang));
+      /*
+         "辞書ファイル \"%s\" が無いよ。作る?(Y/N)",
+       */
+      if ((int) error_handler == WNN_CREATE || call_error_handler (error_handler, tmp))
+        {
+          if (create_file (env, dic_name, JISHO, -1,    /* -1 is dummy */
+                           pwd_dic, (hindo_name && *hindo_name) ? "" : pwd_hindo, error_handler, message_handler) == -1)
+            {
+              return (-1);
+            }
+        }
+      else
+        {
+          wnn_errorno = WNN_NO_EXIST;
+          return (-1);
+        }
+    }
+  if ((fid = file_read (env, dic_name)) == -1)
+    if_dead_disconnect (env, -1);
+  if (hindo_name && *hindo_name)
+    {
+      if (file_exist (env, hindo_name) == -1)
+        {
+          if (wnn_errorno == WNN_JSERVER_DEAD)
+            {
+              jl_disconnect (env);
+              return (-1);
+            }
+          if ((int) error_handler == WNN_NO_CREATE || (hrw == WNN_DIC_RDONLY))
+            {
+              sprintf (tmp, "%s \"%s\" %s", msg_get (wnn_msg_cat, 203, NULL, env->lang), hindo_name, msg_get (wnn_msg_cat, 201, NULL, env->lang));
+              /*
+                 "頻度ファイル \"%s\" が無いよ。",
+               */
+              message_out (message_handler, tmp);
+              wnn_errorno = WNN_NO_EXIST;
+              return (-1);
+            }
+          sprintf (tmp, "%s \"%s\" %s%s", msg_get (wnn_msg_cat, 203, NULL, env->lang), hindo_name, msg_get (wnn_msg_cat, 201, NULL, env->lang), msg_get (wnn_msg_cat, 202, NULL, env->lang));
+          /*
+             "頻度ファイル \"%s\" が無いよ。作る?(Y/N)",
+           */
+          if ((int) error_handler == WNN_CREATE || call_error_handler (error_handler, tmp))
+            {
+              if (create_file (env, hindo_name, HINDO, fid, "", pwd_hindo, error_handler, message_handler) == -1)
+                return (-1);
+            }
+          else
+            {
+              wnn_errorno = WNN_NO_EXIST;
+              return (-1);
+            }
+        }
+      if ((hfid = file_read (env, hindo_name)) == -1)
+        {
+          if_dead_disconnect (env, -1);
+        }
+    }
+  if (get_pwd (pwd_dic, pwd) == -1)
+    return (-1);
+  if (get_pwd (pwd_hindo, hpwd) == -1)
+    return (-1);
+  if ((ret = js_dic_add (env, fid, hfid, rev, prio, rw, hrw, pwd, hpwd)) < 0)
+    {
+      if (wnn_errorno == WNN_JSERVER_DEAD)
+        {
+          jl_disconnect (env);
+          return (-1);
+        }
+      else if (wnn_errorno == WNN_HINDO_NO_MATCH)
+        {
+          if ((int) error_handler == WNN_NO_CREATE)
+            {
+              return (-1);
+            }
+          sprintf (tmp, msg_get (wnn_msg_cat, 204, NULL, env->lang), hindo_name);
+          /*
+             "辞書と頻度 \"%s\" の整合性が無いよ。作り直す?(Y/N)",
+           */
+          if (!((int) error_handler == WNN_CREATE || call_error_handler (error_handler, tmp)))
+            {
+              return (-1);
+            }
+          if (file_discard (env, hfid) == -1)
+            if_dead_disconnect (env, -1);
+          if (file_remove (env->js_id, hindo_name, hpwd) == -1)
+            if_dead_disconnect (env, -1);
+          if (create_file (env, hindo_name, HINDO, fid, NULL, pwd_hindo, WNN_CREATE, message_handler) == -1)
+            return (-1);
+          if ((hfid = file_read (env, hindo_name)) == -1)
+            if_dead_disconnect (env, -1);
+          if ((ret = js_dic_add (env, fid, hfid, rev, prio, rw, hrw, pwd, hpwd)) < 0)
+            if_dead_disconnect (env, -1);
+        }
+    }
+  return (ret);
+}
+
+
+int
+jl_dic_delete_e (env, dic_no)
+     register struct wnn_env *env;
+     register int dic_no;
+{
+  WNN_DIC_INFO dic;
+
+  if (js_dic_info (env, dic_no, &dic) < 0)
+    {
+      if_dead_disconnect (env, -1);
+    }
+  if (js_dic_delete (env, dic_no) < 0)
+    if_dead_disconnect (env, -1);
+  /*  dic Body        */
+  if (file_discard (env, dic.body) < 0)
+    {
+      if_dead_disconnect (env, -1);
+    }
+  /*  dic hindo       */
+  if (dic.hindo != -1)
+    {
+      if (file_discard (env, dic.hindo) < 0)
+        {
+          if_dead_disconnect (env, -1);
+        }
+    }
+  return (0);
+}
+
+static int
+get_pwd (pwd_dic, pwd)
+     register char *pwd_dic, *pwd;
+{
+  FILE *fp;
+
+  if (pwd_dic && *pwd_dic)
+    {
+      if ((fp = fopen (pwd_dic, "r")) == NULL)
+        {
+          wnn_errorno = WNN_CANT_OPEN_PASSWD_FILE;
+          return (-1);
+        }
+      fgets (pwd, WNN_PASSWD_LEN, fp);
+      fclose (fp);
+    }
+  else
+    {
+      pwd[0] = 0;
+    }
+  return (0);
+}
+
+static int
+create_pwd_file (env, pwd_file, error_handler, message_handler)
+     register struct wnn_env *env;
+     char *pwd_file;
+     int (*error_handler) (), (*message_handler) ();
+{
+  FILE *fp;
+  char gomi[256];
+
+  if (pwd_file == NULL || *pwd_file == 0)
+    return (0);
+  if (access (pwd_file, F_OK) != -1)
+    return (0);
+  sprintf (gomi, "%s \"%s\" %s%s", msg_get (wnn_msg_cat, 205, NULL, env->lang), pwd_file, msg_get (wnn_msg_cat, 201, NULL, env->lang), msg_get (wnn_msg_cat, 202, NULL, env->lang));
+  /*
+     "password_file \"%s\" が無いよ。作る?(Y/N)",
+   */
+  if (call_error_handler (error_handler, gomi) == 0)
+    {
+      wnn_errorno = WNN_NO_EXIST;
+      return (-1);
+    }
+  if ((fp = fopen (pwd_file, "w")) == NULL)
+    {
+      wnn_errorno = WNN_CANT_OPEN_PASSWD_FILE;
+      message_out (message_handler, wnn_perror_lang (env->lang));
+      return (-1);
+    }
+  SRAND (time (0) + getuid ());
+  fprintf (fp, "%d\n", (int) RAND ());
+  fclose (fp);
+#define MODE_PWD (0000000 | 0000400)
+  chmod (pwd_file, MODE_PWD);
+  return (0);
+}
+
+
+/**     jl_fuzokugo_set **/
+int
+jl_fuzokugo_set_e (env, fname)
+     struct wnn_env *env;
+     char *fname;
+{
+  register int fid, orgfid;
+  int ret;
+
+  wnn_errorno = 0;
+  orgfid = js_fuzokugo_get (env);
+  /* If orgfid == -1, it must be
+     because no fuzokugo_file is set to the env
+   */
+  if ((fid = file_read (env, fname)) == -1)
+    if_dead_disconnect (env, -1);
+  if ((ret = js_fuzokugo_set (env, fid)) < 0)
+    if_dead_disconnect (env, ret);
+  if (fid != orgfid && orgfid != -1)
+    {
+      js_file_discard (env, orgfid);
+    }
+  return (ret);
+}
+
+/**     jl_fuzokugo_get **/
+int
+jl_fuzokugo_get_e (env, fname)
+     register struct wnn_env *env;
+     char *fname;
+{
+  WNN_FILE_INFO_STRUCT file;
+  int fid;
+  char *c;
+
+  wnn_errorno = 0;
+  fname[0] = 0;
+  if ((fid = js_fuzokugo_get (env)) < 0)
+    if_dead_disconnect (env, -1);
+  if (js_file_info (env, fid, &file) < 0)
+    if_dead_disconnect (env, -1);
+  c = find_file_name_from_id (env, fid);
+  if (c == NULL)
+    {
+      c = file.name;
+    }
+  strcpy (fname, c);
+  return (fid);
+}
+
+/**     jl_dic_save     **/
+int
+jl_dic_save_e (env, dic_no)
+     register struct wnn_env *env;
+     int dic_no;
+{
+  WNN_DIC_INFO dic;
+  WNN_FILE_INFO_STRUCT file;
+  char *c;
+
+  wnn_errorno = 0;
+  if (js_dic_info (env, dic_no, &dic) < 0)
+    if_dead_disconnect (env, -1);
+  /*  dic Body        */
+  c = find_file_name_from_id (env, dic.body);
+  if (c == NULL)
+    {
+      if (dic.localf)
+        {
+          c = dic.fname;
+        }
+      else
+        {
+          wnn_errorno = WNN_FILE_NOT_READ_FROM_CLIENT;
+          return (-1);
+        }
+    }
+  if (c[0] != C_LOCAL)
+    {
+      if (js_file_write (env, dic.body, c) < 0)
+        {
+          if (wnn_errorno == WNN_JSERVER_DEAD)
+            {
+              jl_disconnect_if_server_dead (env);
+              return (-1);
+            }
+        }
+    }
+  else
+    {
+      if (js_file_receive (env, dic.body, c + 1) < 0)
+        {
+          if (wnn_errorno == WNN_JSERVER_DEAD)
+            {
+              jl_disconnect_if_server_dead (env);
+              return (-1);
+            }
+        }
+    }
+  /*     dic hindo       */
+  if (dic.hindo != -1)
+    {
+      if (js_file_info (env, dic.hindo, &file) < 0)
+        if_dead_disconnect (env, -1);
+      c = find_file_name_from_id (env, file.fid);
+      if (c == NULL)
+        {
+          if (dic.hlocalf)
+            {
+              c = dic.hfname;
+            }
+          else
+            {
+              wnn_errorno = WNN_FILE_NOT_READ_FROM_CLIENT;
+              return (-1);
+            }
+        }
+      if (c[0] != C_LOCAL)
+        {
+          if (js_file_write (env, dic.hindo, c) < 0)
+            {
+              if_dead_disconnect (env, -1);
+            }
+        }
+      else
+        {
+          if (js_file_receive (env, dic.hindo, c + 1) < 0)
+            {
+              if_dead_disconnect (env, -1);
+            }
+        }
+    }
+  return (0);
+}
+
+int
+jl_dic_save_all_e (env)
+     struct wnn_env *env;
+{
+  register WNN_DIC_INFO *dic;
+  register int k;
+  char *c;
+
+  register int cnt;
+
+  wnn_errorno = 0;
+  if ((cnt = js_dic_list (env, &dicrb)) == -1)
+    if_dead_disconnect (env, -1);
+  dic = (WNN_DIC_INFO *) dicrb.buf;
+  for (k = 0; k < cnt; k++, dic++)
+    {
+      if ((c = find_file_name_from_id (env, dic->body)) == NULL)
+        {
+          if (dic->localf)
+            {
+              c = dic->fname;
+            }
+          else
+            {
+              wnn_errorno = WNN_FILE_NOT_READ_FROM_CLIENT;
+            }
+        }
+      if (c)
+        {
+          if (c[0] != C_LOCAL)
+            {
+              if (js_file_write (env, dic->body, c) < 0)
+                {
+                  if (wnn_errorno == WNN_JSERVER_DEAD)
+                    {
+                      jl_disconnect_if_server_dead (env);
+                      return (-1);
+                    }
+                }
+            }
+          else
+            {
+              if (js_file_receive (env, dic->body, c + 1) < 0)
+                {
+                  if (wnn_errorno == WNN_JSERVER_DEAD)
+                    {
+                      jl_disconnect_if_server_dead (env);
+                      return (-1);
+                    }
+                }
+            }
+        }
+      /*     dic hindo       */
+      if (dic->hindo != -1)
+        {
+          c = find_file_name_from_id (env, dic->hindo);
+          if (c == NULL)
+            {
+              if (dic->hlocalf)
+                {
+                  c = dic->hfname;
+                }
+              else
+                {
+                  wnn_errorno = WNN_FILE_NOT_READ_FROM_CLIENT;
+                }
+            }
+          if (c)
+            {
+              if (c[0] != C_LOCAL)
+                {
+                  if (js_file_write (env, dic->hindo, c) < 0)
+                    {
+                      if (wnn_errorno == WNN_JSERVER_DEAD)
+                        {
+                          if_dead_disconnect (env, -1);
+                        }
+                    }
+                }
+              else
+                {
+                  if (js_file_receive (env, dic->hindo, c + 1) < 0)
+                    {
+                      if (wnn_errorno == WNN_JSERVER_DEAD)
+                        {
+                          if_dead_disconnect (env, -1);
+                        }
+                    }
+                }
+            }
+        }
+    }
+  if (wnn_errorno)
+    return (-1);
+  return (0);
+}
+
+/*
+ *
+ * bun manipulate  routines
+ *
+ */
+
+static void
+free_sho (buf, wbp)
+     register struct wnn_buf *buf;
+     WNN_BUN **wbp;
+{
+  register WNN_BUN *wb;
+  wb = *wbp;
+
+  if (--wb->ref_cnt <= 0)
+    {
+      for (; wb;)
+        {
+          wb->free_next = buf->free_heap;
+          buf->free_heap = wb;
+          wb = wb->next;
+        }
+    }
+  *wbp = NULL;
+}
+
+static void
+free_zenkouho (buf)
+     register struct wnn_buf *buf;
+{
+  register int k;
+
+  for (k = 0; k < buf->zenkouho_suu; k++)
+    {
+      free_sho (buf, &buf->zenkouho[k]);
+    }
+  buf->zenkouho_suu = 0;
+  buf->zenkouho_dai_suu = 0;
+  buf->c_zenkouho = -1;
+  buf->zenkouho_bun = -1;
+  buf->zenkouho_end_bun = -1;
+}
+
+static void
+free_bun (buf, bun_no, bun_no2)
+     struct wnn_buf *buf;
+     register int bun_no, bun_no2;
+{
+  register int k;
+
+  for (k = bun_no; k < bun_no2; k++)
+    {
+      free_sho (buf, &buf->bun[k]);
+    }
+}
+
+static void
+free_down (buf, bun_no, bun_no2)
+     struct wnn_buf *buf;
+     int bun_no, bun_no2;
+{
+  register WNN_BUN **wbp, **wbp1;
+  int k;
+
+  for (k = bun_no; k < bun_no2; k++)
+    {
+      for (wbp = &buf->down_bnst[k]; *wbp; wbp = wbp1)
+        {
+          wbp1 = &(*wbp)->down;
+          free_sho (buf, wbp);
+        }
+    }
+}
+
+static WNN_BUN *
+get_new_bun (buf)
+     register struct wnn_buf *buf;
+{
+  register WNN_BUN *wb;
+
+
+  if (buf->free_heap == NULL)
+    {
+      if (alloc_heap (buf, INCREMENT) == -1)
+        return (NULL);
+    }
+  wb = buf->free_heap;
+  buf->free_heap = wb->free_next;
+  wb->free_next = NULL;
+  wb->daihyoka = -1;
+
+  return (wb);
+}
+
+static WNN_BUN *
+get_sho (buf, sb, zenp, daip)
+     struct wnn_buf *buf;
+     struct wnn_sho_bunsetsu *sb;
+     int zenp, daip;
+{
+  register w_char *c, *end, *s;
+  register WNN_BUN *wb;
+  WNN_BUN *wb1;
+  int where = 1;
+  int len;
+
+  if ((wb = get_new_bun (buf)) == NULL)
+    return (NULL);
+
+  wb->jirilen = sb->jiriend - sb->start + 1;
+  wb->dic_no = sb->dic_no;
+  wb->entry = sb->entry;
+  wb->kangovect = sb->kangovect;
+  wb->hinsi = sb->hinsi;
+  wb->hindo = sb->hindo;
+  wb->ima = sb->ima;
+  wb->hindo_updated = 0;
+  wb->bug = 0;
+  wb->dai_top = 0;
+  wb->nobi_top = 0;
+  wb->ref_cnt = 1;
+  wb->hyoka = sb->hyoka;
+  wb->down = NULL;
+  wb->from_zenkouho = daip << 1 | zenp;
+  len = wnn_Strlen (sb->fuzoku);
+  wb->yomilen = wnn_Strlen (sb->yomi) + len;
+  wb->kanjilen = wnn_Strlen (sb->kanji) + len;
+/*
+    wb->dai_top = (sb->status == WNN_CONNECT)? 0:1;
+大文節の先頭以外の小文節に関しては、status はいい加減な値が入っている。
+*/
+  s = sb->yomi;
+
+  for (wb1 = wb;;)
+    {
+      if (wb1 == wb)
+        c = wb1->yomi;
+      else
+        c = (w_char *) wb1;
+      end = (w_char *) & wb1->next;
+
+      for (; c < end;)
+        {
+          if ((*c++ = *s++) == 0)
+            {
+              if (where == 1)
+                {
+                  where = 3;
+                  c--;
+                  s = sb->fuzoku;
+                }
+              else if (where == 3)
+                {
+                  where = 0;
+                  s = sb->kanji;
+                }
+              else if (where == 0)
+                {
+                  where = 4;
+                  c--;
+                  s = sb->fuzoku;
+                }
+              else
+                {
+                  goto out;
+                }
+            }
+        }
+      wb1->next = get_new_bun (buf);
+      wb1 = wb1->next;
+    }
+out:
+  wb1->next = NULL;
+  return (wb);
+}
+
+static void
+make_space_for (buf, zenp, bun_no, bun_no2, cnt)
+     register struct wnn_buf *buf;
+     int bun_no, bun_no2, zenp;
+     int cnt;
+{
+  switch (zenp)
+    {
+    case BUN:
+      make_space_for_bun (buf, bun_no, bun_no2, cnt);
+      break;
+    case ZENKOUHO:
+      make_space_for_zenkouho (buf, bun_no, bun_no2, cnt);
+    }
+}
+
+static void
+make_space_for_bun (buf, bun_no, bun_no2, cnt)
+     register struct wnn_buf *buf;
+     int bun_no, bun_no2;
+     int cnt;
+{
+  int newsize;
+  register int k;
+
+  newsize = buf->bun_suu + cnt - (bun_no2 - bun_no);
+
+#define Realloc(a, b) realloc((char *)(a), (unsigned)(b))
+
+  if (newsize > buf->msize_bun)
+    {
+      buf->bun = (WNN_BUN **) Realloc (buf->bun, newsize * sizeof (WNN_BUN *));
+      buf->down_bnst = (WNN_BUN **) Realloc (buf->down_bnst, newsize * sizeof (WNN_BUN *));
+      buf->msize_bun = newsize;
+    }
+
+
+  for (k = buf->bun_suu; k < newsize; k++)
+    {
+      buf->down_bnst[k] = NULL;
+    }
+  bcopy ((char *) &buf->bun[bun_no2], (char *) &buf->bun[bun_no + cnt], (buf->bun_suu - bun_no2) * sizeof (WNN_BUN *));
+  bcopy ((char *) &buf->down_bnst[bun_no2], (char *) &buf->down_bnst[bun_no + cnt], (buf->bun_suu - bun_no2) * sizeof (WNN_BUN *));
+  if (bun_no2 < bun_no + cnt)
+    {
+      bzero ((char *) &buf->down_bnst[bun_no2], (bun_no + cnt - bun_no2) * sizeof (WNN_BUN *));
+    }
+  buf->bun_suu = newsize;
+}
+
+static void
+make_space_for_zenkouho (buf, bun_no, bun_no2, cnt)
+     struct wnn_buf *buf;
+     int bun_no, bun_no2;
+     register int cnt;
+{
+  register int newsize;
+
+  newsize = buf->zenkouho_suu + cnt - (bun_no2 - bun_no);
+
+  if (newsize > buf->msize_zenkouho)
+    {
+      buf->zenkouho = (WNN_BUN **) Realloc (buf->zenkouho, newsize * sizeof (WNN_BUN *));
+      buf->zenkouho_dai = (int *) Realloc (buf->zenkouho_dai, (1 + newsize) * sizeof (int *));
+      buf->msize_zenkouho = newsize;
+    }
+  bcopy ((char *) &buf->zenkouho[bun_no2], (char *) &buf->zenkouho[bun_no + cnt], (buf->zenkouho_suu - bun_no2) * sizeof (WNN_BUN *));
+  buf->zenkouho_suu = newsize;
+}
+
+
+static int
+insert_sho (buf, zenp, bun_no, bun_no2, sp, cnt, uniq_level)
+     struct wnn_buf *buf;
+     int bun_no, bun_no2;
+     register struct wnn_sho_bunsetsu *sp;
+     int cnt;
+     int zenp;                  /* daip */
+     int uniq_level;            /* uniq is only supported when bun_no = -1
+                                   and zenp == ZENKOUHO */
+{
+  register WNN_BUN **b;
+  register int k;
+
+  if (bun_no == -1)
+    {
+      bun_no = bun_no2 = (zenp == BUN) ? buf->bun_suu : buf->zenkouho_suu;
+    }
+
+  /* It will make too big space when uniq_level > 0, but That's OK! */
+  make_space_for (buf, zenp, bun_no, bun_no2, cnt);
+
+  b = ((zenp == BUN) ? buf->bun : buf->zenkouho) + bun_no;
+  for (k = bun_no; k < bun_no + cnt; k++, sp++)
+    {
+      if (uniq_level)
+        {
+          if (find_same_kouho (sp, buf->zenkouho, b, uniq_level))
+            continue;
+        }
+      *b = get_sho (buf, sp, zenp, SHO);
+      (*b)->dai_top = (sp->status == WNN_CONNECT) ? 0 : 1;
+      if (zenp != BUN)
+        {
+          if (buf->zenkouho_endvect != -1)
+            {
+              (*b)->dai_end = (sp->status_bkwd == WNN_CONNECT_BK) ? 0 : 1;
+            }
+          else
+            {
+              (*b)->dai_end = 1;
+            }
+        }
+      b++;
+    }
+  if (uniq_level && zenp == ZENKOUHO)
+    {
+      buf->zenkouho_suu = b - buf->zenkouho;
+    }
+  return (cnt + bun_no);
+}
+
+        /* for zenkouho, assume bun_no = bun_no2 = zenkouho_suu */
+static int
+insert_dai (buf, zenp, bun_no, bun_no2, dp, dcnt, uniq_level)
+     struct wnn_buf *buf;
+     int bun_no, bun_no2;
+     struct wnn_dai_bunsetsu *dp;
+     int dcnt;
+     int zenp;
+     int uniq_level;
+{
+  register WNN_BUN **b, **b0;
+  register int k, l, m;
+  register int cnt = 0;
+  struct wnn_sho_bunsetsu *sp, *sp1;
+
+  if (bun_no == -1)
+    {
+      if (zenp == BUN)
+	{
+	  bun_no = bun_no2 = buf->bun_suu;
+	}
+      else
+	{
+	  bun_no = bun_no2 = buf->zenkouho_suu;
+	}
+    }
+
+  for (k = 0; k < dcnt; k++)
+    {
+      cnt += dp[k].sbncnt;
+    }
+  make_space_for (buf, zenp, bun_no, bun_no2, cnt);
+  /* zenkouho_dai_suu must not be initialized */
+
+  if (zenp == BUN)
+    {
+      b = buf->bun + bun_no;
+    }
+  else
+    {
+      b =  buf->zenkouho + bun_no;
+    }
+
+  for (k = 0, m = buf->zenkouho_dai_suu; k < dcnt; k++)
+    {
+      if (uniq_level)
+        {
+          if (find_same_kouho_dai (&dp[k], buf, m, uniq_level))
+            continue;
+        }
+      sp = dp[k].sbn;
+      if (zenp == ZENKOUHO)
+        {
+          buf->zenkouho_dai[m++] = b - buf->zenkouho;
+        }
+      b0 = b;
+      sp1 = sp;
+      for (l = 0; l < dp[k].sbncnt; l++, b++, sp++)
+        {
+          *b = get_sho (buf, sp, zenp, DAI);
+          if (zenp == ZENKOUHO)
+            {
+              if ((l == dp[k].sbncnt - 1)
+		  && (buf->zenkouho_endvect != -1)
+		  && (sp->status_bkwd != WNN_CONNECT_BK))
+                {
+		  (*b)->dai_end = 1;
+                }
+	      else
+		{
+		  (*b)->dai_end = 0;
+		}
+            }
+        }
+      if (sp1->status == WNN_CONNECT)
+	{
+	  (*b0)->dai_top = 0;
+	}
+      else
+	{
+	  (*b0)->dai_top = 1;
+	}
+      (*b0)->daihyoka = dp[k].hyoka;
+    }
+  if (zenp == ZENKOUHO)
+    {
+      buf->zenkouho_dai[m] = b - buf->zenkouho;
+      buf->zenkouho_suu = b - buf->zenkouho;
+      buf->zenkouho_dai_suu = m;
+    }
+  return (cnt + bun_no);
+}
+
+static void
+set_sho (b, p)
+     register WNN_BUN *b;
+     register WNN_BUN **p;
+{
+  b->ref_cnt++;
+  *p = b;
+}
+
+static void
+set_dai (b, p, n)
+     register WNN_BUN **b;
+     register WNN_BUN **p;
+     register int n;
+{
+  for (; n; n--)
+    {
+      (*b)->ref_cnt++;
+      *p++ = *b++;
+    }
+}
+
+static int
+get_c_jikouho_from_zenkouho (buf, dest)
+     struct wnn_buf *buf;
+     WNN_BUN *dest;
+{
+  register int k;
+  w_char area[LENGTHKANJI];
+  w_char area1[LENGTHKANJI];
+  register WNN_BUN *b;
+
+  wnn_area (dest, area, WNN_KANJI);
+  for (k = 0; k < buf->zenkouho_suu; k++)
+    {
+      b = buf->zenkouho[k];
+      if (b->entry == dest->entry && b->dic_no == dest->dic_no)
+        {
+          wnn_area (b, area1, WNN_KANJI);
+          if (wnn_Strcmp (area, area1) == 0)
+            {
+              return (k);
+            }
+        }
+    }
+  return (-1);
+}
+
+static int
+get_c_jikouho_from_zenkouho_dai (buf, dest)
+     struct wnn_buf *buf;
+     WNN_BUN *dest;
+{
+  register int k;
+  w_char area[LENGTHKANJI];
+  w_char area1[LENGTHKANJI];
+  register WNN_BUN *b;
+  register int l;
+
+  wnn_area (dest, area, WNN_KANJI);
+  for (k = 0; k < buf->zenkouho_dai_suu; k++)
+    {
+      b = buf->zenkouho[buf->zenkouho_dai[k]];
+      for (l = 0; l < buf->zenkouho_dai[k + 1]; l++, dest++, b++)
+        {
+          if (b->entry != dest->entry || b->dic_no != dest->dic_no)
+            break;
+          wnn_area (b, area1, WNN_KANJI);
+          if (wnn_Strcmp (area, area1) != 0)
+            {
+              break;
+            }
+        }
+      if (l == buf->zenkouho_dai[k + 1])
+        {
+          return (k);
+        }
+    }
+  return (-1);
+}
+
+
+static int
+get_c_jikouho (sp, cnt, dest)
+     struct wnn_sho_bunsetsu *sp;
+     int cnt;
+     WNN_BUN *dest;
+{
+  register int k;
+  register int len;
+  w_char area[LENGTHKANJI];
+
+  wnn_area (dest, area, WNN_KANJI);
+  for (k = 0; k < cnt; k++, sp++)
+    {
+      if (sp->entry == dest->entry && sp->dic_no == dest->dic_no && sp->kangovect == dest->kangovect)
+        {
+          if (wnn_Strncmp (area, sp->kanji, len = wnn_Strlen (sp->kanji)) == 0 && wnn_Strcmp (area + len, sp->fuzoku) == 0)
+            {
+              return (k);
+            }
+        }
+    }
+  return (-1);
+}
+
+static int
+get_c_jikouho_dai (dp, cnt, dest, bun_no)
+     struct wnn_dai_bunsetsu *dp;
+     int cnt;
+     WNN_BUN **dest;
+     int bun_no;
+{
+  register int k, l;
+  register int len;
+  w_char area[LENGTHKANJI];
+  register struct wnn_sho_bunsetsu *sp;
+
+  for (k = 0; k < cnt; k++, dp++)
+    {
+      sp = dp->sbn;
+      for (l = 0; l < dp->sbncnt; l++, sp++)
+        {
+          if (sp->entry != (dest[bun_no + l])->entry || sp->kangovect != (dest[bun_no + l])->kangovect || sp->dic_no != (dest[bun_no + l])->dic_no)
+            {
+              break;
+            }
+          wnn_area (dest[bun_no + l], area, WNN_KANJI);
+          if (wnn_Strncmp (area, sp->kanji, len = wnn_Strlen (sp->kanji)) != 0 || wnn_Strcmp (area + len, sp->fuzoku) != 0)
+            {
+              break;
+            }
+        }
+      if (l == dp->sbncnt)
+        return (k);
+    }
+  return (-1);
+}
+
+
+static int
+find_same_kouho (sp, st, end, level)
+     struct wnn_sho_bunsetsu *sp;
+     register WNN_BUN **st, **end;
+     int level;
+{
+  register int len;
+  w_char area[LENGTHKANJI];
+  register WNN_BUN *b;
+
+  if (level == WNN_UNIQ)
+    {
+      for (; st < end; st++)
+        {
+          b = *st;
+          if (sp->hinsi == b->hinsi)
+            {
+              wnn_area (b, area, WNN_KANJI);
+              if (wnn_Strncmp (area, sp->kanji, len = wnn_Strlen (sp->kanji)) == 0 && wnn_Strcmp (area + len, sp->fuzoku) == 0)
+                {
+                  return (1);
+                }
+            }
+        }
+    }
+  else
+    {                           /* level = WNN_UNIQ_KNJ */
+      for (; st < end; st++)
+        {
+          b = *st;
+          wnn_area (b, area, WNN_KANJI);
+          if (wnn_Strncmp (area, sp->kanji, len = wnn_Strlen (sp->kanji)) == 0 && wnn_Strcmp (area + len, sp->fuzoku) == 0)
+            {
+              return (1);
+            }
+        }
+    }
+  return (0);
+}
+
+static int
+find_same_kouho_dai (dp, buf, top, level)
+     struct wnn_dai_bunsetsu *dp;
+     struct wnn_buf *buf;
+     int top;
+     int level;
+{
+  int len;
+  register int k, l;
+  w_char area[LENGTHKANJI];
+  WNN_BUN *b;
+  register struct wnn_sho_bunsetsu *sp;
+
+  for (k = 0; k < top; k++)
+    {
+      for (l = 0, sp = dp->sbn; l < dp->sbncnt; l++, sp++)
+        {
+          b = buf->zenkouho[buf->zenkouho_dai[k] + l];
+          if (sp->end - sp->start + 1 != b->yomilen)
+            break;              /* From: tsuiki */
+          if (level != WNN_UNIQ_KNJ)
+            {
+              if (sp->hinsi != b->hinsi)
+                break;
+            }
+          wnn_area (b, area, WNN_KANJI);
+          if (wnn_Strncmp (area, sp->kanji, len = wnn_Strlen (sp->kanji)) != 0 || wnn_Strcmp (area + len, sp->fuzoku) != 0)
+            {
+              break;
+            }
+        }
+      if (l == dp->sbncnt)
+        return (1);
+    }
+  return (0);
+}
+
+int
+wnn_cnt_free (buf)
+     struct wnn_buf *buf;
+{
+  register int n;
+  register WNN_BUN *b;
+
+  for (n = 0, b = buf->free_heap; b; n++, b = b->free_next);
+  return (n);
+}
+
+
+struct wnn_jdata *
+jl_word_info_e (env, dic_no, entry)
+     register struct wnn_env *env;
+     int dic_no, entry;
+{
+  wnn_errorno = 0;
+  if (js_word_info (env, dic_no, entry, &wordrb) < 0)
+    if_dead_disconnect (env, NULL);
+  return ((struct wnn_jdata *) (wordrb.buf));
+}
+
+int
+jl_dic_list_e (env, dicinfo)
+     struct wnn_env *env;
+     WNN_DIC_INFO **dicinfo;
+{
+  WNN_DIC_INFO *info;
+  int cnt;
+  register int k;
+  register char *c;
+
+  wnn_errorno = 0;
+  if ((cnt = js_dic_list (env, &dicrb)) < 0)
+    if_dead_disconnect (env, -1);
+  info = (WNN_DIC_INFO *) (dicrb.buf);
+
+/* If the file is loaded from this client, change the file name to the one
+   used in loading it. */
+  for (k = 0; k < cnt; k++)
+    {
+      c = find_file_name_from_id (env, info[k].body);
+      if (c != NULL)
+        {
+          strcpy (info[k].fname, c);
+        }
+
+      c = find_file_name_from_id (env, info[k].hindo);
+      if (c != NULL)
+        {
+          strcpy (info[k].hfname, c);
+        }
+    }
+  *dicinfo = info;
+  return (cnt);
+}
+
+
+static int
+sort_func_ws (a, b)
+     register char *a, *b;
+{
+  int ah, bh, ai, bi, iah, ibh, iai, ibi;
+  ah = ((struct wnn_jdata *) a)->hindo;
+  bh = ((struct wnn_jdata *) b)->hindo;
+  iah = ((struct wnn_jdata *) a)->int_hindo;
+  ibh = ((struct wnn_jdata *) b)->int_hindo;
+  ai = ((struct wnn_jdata *) a)->ima;
+  bi = ((struct wnn_jdata *) b)->ima;
+  iai = ((struct wnn_jdata *) a)->int_ima;
+  ibi = ((struct wnn_jdata *) b)->int_ima;
+
+  if (ai == WNN_IMA_OFF && ah == WNN_ENTRY_NO_USE)
+    return (1);
+  if (bi == WNN_IMA_OFF && bh == WNN_ENTRY_NO_USE)
+    return (-1);
+  if (iai == WNN_IMA_OFF && iah == WNN_ENTRY_NO_USE)
+    return (1);
+  if (ibi == WNN_IMA_OFF && ibh == WNN_ENTRY_NO_USE)
+    return (-1);
+
+  if (ai != bi)
+    {
+      if (ai < bi)
+        return (1);
+      return (-1);
+    }
+  if (iah >= 0)
+    {
+      ah += iah;
+      bh += ibh;
+    }
+  if (ah > bh)
+    return (-1);
+  if (ah < bh)
+    return (1);
+  return (0);
+}
+
+int
+jl_word_search_e (env, dic_no, yomi, jdp)
+     register struct wnn_env *env;
+     int dic_no;
+     w_char *yomi;
+     struct wnn_jdata **jdp;
+{
+  register int cnt;
+  struct wnn_jdata *jd;
+
+  wnn_errorno = 0;
+  if ((cnt = js_word_search (env, dic_no, yomi, &wordrb)) < 0)
+    if_dead_disconnect (env, -1);
+  jd = (struct wnn_jdata *) wordrb.buf;
+/*    for(cnt = 0 ; jd[cnt].dic_no != -1; cnt++); */
+  qsort ((char *) jd, cnt, sizeof (struct wnn_jdata), sort_func_ws);
+  *jdp = jd;
+  return (cnt);
+}
+
+int
+jl_word_search_by_env_e (env, yomi, jdp)
+     register struct wnn_env *env;
+     struct wnn_jdata **jdp;
+     w_char *yomi;
+{
+  register int cnt;
+  struct wnn_jdata *jd;
+
+  wnn_errorno = 0;
+  if ((cnt = js_word_search_by_env (env, yomi, &wordrb)) < 0)
+    if_dead_disconnect (env, -1);
+  jd = (struct wnn_jdata *) wordrb.buf;
+/*    for(cnt = 0 ; jd[cnt].dic_no != -1; cnt++); */
+  qsort ((char *) jd, cnt, sizeof (struct wnn_jdata), sort_func_ws);
+  *jdp = jd;
+  return (cnt);
+}
+
+#ifdef JL_DEBUG
+static void
+display_bun (b)
+     WNN_BUN *b;
+{
+  w_char yomi[LENGTHBUNSETSU];
+  wnn_area (b, yomi, 1);
+  putws (yomi);
+  printf ("\t");
+  wnn_area (b, yomi, 0);
+  putws (yomi);
+  printf ("\t");
+  printf ("Jirilen:%d Dic_no:%d Serial:%d Hinsi:%d Hindo:%c%d\n Hindo_Updated:%d Nobi_Top:%d Dai_top:%d Ref_cnt:%d Down:%d\n",
+          b->jirilen, b->dic_no, b->entry, b->hinsi, (b->ima) ? '*' : ' ', b->hindo, b->hindo_updated, b->nobi_top, b->dai_top, b->ref_cnt, b->down);
+}
+#endif
+
+
+static void
+add_down_bnst (buf, k, b)
+     register struct wnn_buf *buf;
+     register int k;
+     register WNN_BUN *b;
+{
+  if (b->down)
+    return;                     /* In order to prevent roop! */
+  if (b == buf->down_bnst[k])
+    return;                     /* In order to prevent roop! */
+  /* It occurs when Zenkouho-->Nobi-conv */
+  b->down = buf->down_bnst[k];
+  buf->down_bnst[k] = b;
+  b->ref_cnt++;
+}
+
+#ifdef JL_DEBUG
+static void
+print_jdata (jd)
+     struct wnn_jdata *jd;
+{
+  putws (jd->kanji);
+  printf ("\tDict:%d Serial:%d Hinsi:%s Hindo:%c%d ExHindo:%c%d\n",
+          jd->dic_no, jd->serial, wnn_get_hinsi_name (jd->hinshi), (jd->ima) ? '*' : ' ', jd->hindo, (jd->int_ima) ? '*' : ' ', jd->int_hindo);
+}
+#endif
+
+#define REAL_PARAM(x) (strcmp(x, "-"))
+
+
+/** wnnrc を見てのパラメータの設定 */
+int
+jl_set_env_wnnrc (env, wnnrc_n, error_handler, message_handler)
+     register struct wnn_env *env;
+     char *wnnrc_n;
+     int (*error_handler) (), (*message_handler) ();
+{
+  int level = 0;
+  int x;
+  wnn_errorno = 0;
+  if ((int) error_handler == WNN_CREATE)
+    {
+      confirm_state = CREATE_WITHOUT_CONFIRM;
+    }
+  else if ((int) error_handler == WNN_NO_CREATE)
+    {
+      confirm_state = NO_CREATE;
+    }
+  else
+    {
+      confirm_state = CONFIRM;
+    }
+  x = jl_set_env_wnnrc1 (env, wnnrc_n, error_handler, message_handler, level);
+  confirm_state = 0;
+  return (x);
+}
+
+int
+jl_set_env_wnnrc1 (env, wnnrc_n, error_handler, message_handler, level)
+     register struct wnn_env *env;
+     char *wnnrc_n;
+     int (*error_handler) (), (*message_handler) ();
+     int level;
+{
+  register int num;
+  char s[20][EXPAND_PATH_LENGTH];
+  char code[EXPAND_PATH_LENGTH];
+  char tmp[1024];
+  register FILE *fp;
+
+  wnn_errorno = 0;
+  if (level > MAXINCLUDE)
+    {
+      message_out (message_handler, msg_get (wnn_msg_cat, 206, NULL, env->lang));
+      /*
+         "include のレベルが多過ぎます。"
+       */
+      return (-1);
+    }
+  if ((fp = fopen (wnnrc_n, "r")) == NULL)
+    {
+      message_out (message_handler, msg_get (wnn_msg_cat, 207, NULL, env->lang), wnnrc_n);
+      /*
+         "file \"%s\"が open できません",
+       */
+      return (-1);
+    }
+  while (fgets (tmp, 1024, fp) != NULL)
+    {
+      num = sscanf (tmp,
+                    "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", code,
+                    s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9], s[10], s[11], s[12], s[13], s[14], s[15], s[16], s[17], s[18], s[19]);
+      if (num <= 0)
+        {
+          continue;
+        }
+      if (code[0] == ';')
+        {
+          continue;
+
+        }
+      else if (strcmp (code, "include") == 0)
+        {
+          expand_expr_all (s[0], env);
+          if (jl_set_env_wnnrc1 (env, s[0], error_handler, message_handler, level + 1) == -1)
+            {
+              fclose (fp);
+              return (-1);
+            }
+        }
+      else if (strcmp (code, "setdic") == 0)
+        {
+          /* dic_add */
+          int prio, rdonly, hrdonly, rev;
+          int (*error_handler1) () = (int (*)()) 0;
+          expand_expr_all (s[0], env);
+          if (num < 3 || !REAL_PARAM (s[1]))
+            {
+              s[1][0] = 0;
+            }
+          else
+            {
+              expand_expr_all (s[1], env);
+            }
+          prio = (num >= 4 && REAL_PARAM (s[2])) ? atoi (s[2]) : WNN_DIC_PRIO_DEFAULT;
+          rdonly = (num >= 5 && REAL_PARAM (s[3])) ? atoi (s[3]) : 0;
+          hrdonly = (num >= 6 && REAL_PARAM (s[4])) ? atoi (s[4]) : 0;
+          if (num < 7 || !REAL_PARAM (s[5]))
+            s[5][0] = 0;
+          if (num < 8 || !REAL_PARAM (s[6]))
+            s[6][0] = 0;
+          rev = (num >= 9 && REAL_PARAM (s[7])) ? atoi (s[7]) : 0;
+
+          if (confirm_state == CONFIRM || confirm_state == CONFIRM1)
+            {
+              error_handler1 = error_handler;
+            }
+          else if (confirm_state == CREATE_WITHOUT_CONFIRM)
+            {
+
+              error_handler1 = (int (*)()) WNN_CREATE;
+            }
+          else if (confirm_state == NO_CREATE)
+            {
+              error_handler1 = (int (*)()) WNN_NO_CREATE;
+            }
+          if (jl_dic_add_e (env, s[0], s[1], rev, prio, rdonly, hrdonly, s[5], s[6], error_handler1, message_handler) == -1 && wnn_errorno != 0)
+            {
+              if (wnn_errorno != WNN_JSERVER_DEAD)
+                message_out (message_handler, "%s (%s) :%s\n", s[0], s[1], wnn_perror_lang (env->lang));
+              else
+                message_out (message_handler, "%s\n", wnn_perror_lang (env->lang));
+              goto _Err_happend;
+            }
+
+        }
+      else if ((strcmp (code, "setfuzokugo") == 0) || (strcmp (code, "setgrammar") == 0))
+        {
+          /* fuzokugo_set */
+          expand_expr_all (s[0], env);
+          if (jl_fuzokugo_set_e (env, s[0]) == -1)
+            {
+              if (wnn_errorno != WNN_JSERVER_DEAD)
+                message_out (message_handler, "%s :%s\n", s[0], wnn_perror_lang (env->lang));
+              else
+                message_out (message_handler, "%s\n", wnn_perror_lang (env->lang));
+              goto _Err_happend;
+            }
+        }
+      else if (strcmp (code, "setparam") == 0)
+        {
+          struct wnn_param para;
+          /* setparam --- set parameter */
+          change_ascii_to_int (s[0], &para.n);
+          change_ascii_to_int (s[1], &para.nsho);
+          change_ascii_to_int (s[2], &para.p1);
+          change_ascii_to_int (s[3], &para.p2);
+          change_ascii_to_int (s[4], &para.p3);
+          change_ascii_to_int (s[5], &para.p4);
+          change_ascii_to_int (s[6], &para.p5);
+          change_ascii_to_int (s[7], &para.p6);
+          change_ascii_to_int (s[8], &para.p7);
+          change_ascii_to_int (s[9], &para.p8);
+
+          change_ascii_to_int (s[10], &para.p9);
+          change_ascii_to_int (s[11], &para.p10);
+          change_ascii_to_int (s[12], &para.p11);
+          change_ascii_to_int (s[13], &para.p12);
+          change_ascii_to_int (s[14], &para.p13);
+          change_ascii_to_int (s[15], &para.p14);
+          change_ascii_to_int (s[16], &para.p15);
+
+          if (js_param_set (env, &para) < 0)
+            {
+              fclose (fp);
+              message_out (message_handler, msg_get (wnn_msg_cat, 208, NULL, env->lang), wnnrc_n);
+              /*
+                 "ファイル \"%s\" で環境設定中に、エラーが発生したために、設定を中止します。\n",
+               */
+              if_dead_disconnect (env, -1);
+            }
+        }
+      else if (strcmp (code, "confirm") == 0)
+        {
+          confirm_state = CONFIRM;
+        }
+      else if (strcmp (code, "confirm1") == 0)
+        {
+          confirm_state = CONFIRM1;
+        }
+      else if (strcmp (code, "create_without_confirm") == 0)
+        {
+          confirm_state = CREATE_WITHOUT_CONFIRM;
+        }
+      else if (strcmp (code, "no_create") == 0)
+        {
+          confirm_state = NO_CREATE;
+        }
+    }
+  fclose (fp);
+  return (0);
+
+_Err_happend:
+  message_out (message_handler, msg_get (wnn_msg_cat, 208, NULL, env->lang), wnnrc_n);
+  /*
+     "ファイル \"%s\" で環境設定中に、エラーが発生したために、設定を中止します。\n",
+   */
+  fclose (fp);
+  return (-1);
+}
+
+static int
+expand_expr_all (s, env)
+     struct wnn_env *env;
+     register char *s;
+{
+  register char *c;
+
+  for (c = s; *c; c++)
+    {
+      if (*c == '~' || *c == '@')
+        {
+          if (expand_expr (c, env) == -1)
+            return (-1);
+        }
+    }
+  return (0);
+}
+
+/* copy of js.c */
+static char *
+getlogname ()
+{
+  struct passwd *getpwuid ();
+  return getpwuid (getuid ())->pw_name;
+}
+
+
+static int
+expand_expr (s, env)
+     struct wnn_env *env;
+ /**    ~user、@HOME、@LIBDIR @ENV @USR の展開(但し、文字列の先頭のみ)。
+   できない時は-1が
+   返り、その場合sの中身は着々とそのまんま。sの長さ<256と仮定してる。*/
+     register char *s;
+{
+  char *p, *s1;
+  char tmp[EXPAND_PATH_LENGTH];
+  int noerr, expandsuc;
+  struct passwd *u;
+  extern char *getenv ();
+  extern struct passwd *getpwnam ();
+
+  if (*s != '~' && *s != '@')
+    return (0);
+  if ((int) strlen (s) >= EXPAND_PATH_LENGTH)
+    return (-1);
+
+  s1 = s;
+  if (NULL != (p = strchr (++s1, '/')))
+    {
+      strcpy (tmp, p);
+      *p = '\0';
+    }
+  else
+    *tmp = '\0';
+  /* ここまでは準備。s…先頭、s1…2文字目、p…最初の'/'のあったところ
+     (ここで一旦切る)、tmp…それ以後のコピー。 */
+
+  if (*s == '~')
+    {
+      if (*s1)
+        {
+          noerr = expandsuc = (NULL != (u = getpwnam (s1)) && (int) strlen (p = u->pw_dir) + (int) strlen (tmp) < EXPAND_PATH_LENGTH);
+
+        }
+      else
+        {
+          noerr = expandsuc = (NULL != (p = getenv ("HOME")) && (int) strlen (p) + (int) strlen (tmp) < EXPAND_PATH_LENGTH);
+        }
+
+    }
+  else
+    {                           /* then, *s must be '@' */
+      if (!strcmp (s1, "HOME"))
+        {
+          noerr = expandsuc = (NULL != (p = getenv ("HOME")) && (int) strlen (p) + (int) strlen (tmp) < EXPAND_PATH_LENGTH);
+        }
+      else if (!strcmp (s1, "WNN_DIC_DIR"))
+        {
+          char buf[EXPAND_PATH_LENGTH];
+          expandsuc = 1;
+          noerr = (NULL != (p = getenv ("HOME")) && (int) strlen (p) + (int) strlen (tmp) < EXPAND_PATH_LENGTH);
+          strcpy (buf, p);
+          strcat (buf, "/");
+
+          p = getenv ("WNN_DIC_DIR");
+          if (p)
+            {
+              strcat (buf, p);
+            }
+          else
+            {
+              strcat (buf, "Wnn");
+            }
+          p = buf;
+        }
+      else if (!strcmp (s1, "LIBDIR"))
+        {
+          noerr = expandsuc = ((int) strlen (p = LIBDIR) + (int) strlen (tmp) < EXPAND_PATH_LENGTH);
+        }
+      else if (!strcmp (s1, "ENV"))
+        {                       /* Added */
+          noerr = expandsuc = (NULL != (p = env_name (env)) && (int) strlen (p) + (int) strlen (tmp) < EXPAND_PATH_LENGTH);
+        }
+      else if (!strcmp (s1, "USR"))
+        {
+          noerr = expandsuc = (NULL != (p = getlogname ()) && (int) strlen (p) + (int) strlen (tmp) < EXPAND_PATH_LENGTH);
+        }
+      else
+        {                       /* @HOME, @LIBDIR @ENV igai ha kaenai */
+          noerr = 1;
+          expandsuc = 0;
+        }
+    }
+
+  if (expandsuc)
+    strcpy (s, p);
+  strcat (s, tmp);
+  return (noerr ? 0 : -1);
+}
+
+static int
+change_ascii_to_int (st, dp)
+     register char *st;
+     int *dp;
+{
+  register int total, flag;
+
+  total = 0;
+  flag = 0;
+  while (*st != NULL)
+    {
+      if (isdigit (*st))
+        {
+          total = total * 10 + (*st - '0');
+        }
+      else if (*st == '+')
+        {
+          if (flag != 0)
+            {
+              return (-1);
+            }
+          flag = 1;
+        }
+      else if (*st == '-')
+        {
+          if (flag != 0)
+            {
+              return (-1);
+            }
+          flag = -1;
+        }
+      else
+        {
+          return (-1);
+        }
+      st++;
+    }
+  if (flag == 0)
+    {
+      flag = 1;
+    }
+  *dp = total * flag;
+  return (1);
+}
+
+static int
+file_exist (env, n)
+     struct wnn_env *env;
+     char *n;
+{
+  if (n[0] == C_LOCAL)
+    {
+      wnn_errorno = 0;
+      return (access (n + 1, 4));
+    }
+  else
+    {
+      return (js_access (env, n, 4));
+    }
+}
+
+static int
+create_file (env, n, d, fid, pwd_dic, pwd_hindo, error_handler, message_handler)
+     register struct wnn_env *env;
+     char *n;
+     int d;
+     int fid;
+     char *pwd_dic, *pwd_hindo;
+     int (*error_handler) (), (*message_handler) ();
+{
+  char pwd[WNN_PASSWD_LEN], hpwd[WNN_PASSWD_LEN];
+  int rev_dict_type;
+
+  if (make_dir_rec1 (env, n, error_handler, message_handler) == -1)
+    {
+      wnn_errorno = WNN_MKDIR_FAIL;
+      return (-1);
+    }
+  if (d == HINDO)
+    {
+      if (create_pwd_file (env, pwd_hindo, error_handler, message_handler) == -1)
+        return (-1);
+      if (get_pwd (pwd_hindo, hpwd) == -1)
+        return (-1);
+      if (n[0] == C_LOCAL)
+        {
+          if (js_hindo_file_create_client (env, fid, n + 1, NULL, hpwd) == -1)
+            {
+              message_out (message_handler, wnn_perror_lang (env->lang));
+              if_dead_disconnect (env, -1);
+            }
+          else
+            {
+              message_out (message_handler, "%s \"%s\" %s", msg_get (wnn_msg_cat, 203, NULL, env->lang), n, msg_get (wnn_msg_cat, 209, NULL, env->lang));
+              /*
+                 "頻度ファイル \"%s\" を作りました。",
+               */
+              chown (n + 1, getuid (), -1);     /* H.T. */
+              return (0);
+            }
+        }
+      else
+        {
+          if (js_hindo_file_create (env, fid, n, NULL, hpwd) == -1)
+            {
+              message_out (message_handler, wnn_perror_lang (env->lang));
+              if_dead_disconnect (env, -1);
+            }
+          else
+            {
+              message_out (message_handler, "%s \"%s\" %s", msg_get (wnn_msg_cat, 203, NULL, env->lang), n, msg_get (wnn_msg_cat, 209, NULL, env->lang));
+              /*
+                 "頻度ファイル \"%s\" を作りました。",
+               */
+              return (0);
+            }
+        }
+    }
+  else
+    {
+      if (create_pwd_file (env, pwd_hindo, error_handler, message_handler) == -1)
+        return (-1);
+      if (get_pwd (pwd_hindo, hpwd) == -1)
+        return (-1);
+      if (create_pwd_file (env, pwd_dic, error_handler, message_handler) == -1)
+        return (-1);
+      if (get_pwd (pwd_dic, pwd) == -1)
+        return (-1);
+
+#ifdef  CONVERT_with_SiSheng
+      if (!strncmp (js_get_lang (env), WNN_C_LANG, 5) || !strncmp (js_get_lang (env), WNN_T_LANG, 5))
+        rev_dict_type = CWNN_REV_DICT;
+      else
+#endif
+        rev_dict_type = WNN_REV_DICT;
+
+      if (n[0] == C_LOCAL)
+        {
+          if (js_dic_file_create_client (env, n + 1, rev_dict_type, NULL, pwd, hpwd) == -1)
+            {
+              message_out (message_handler, wnn_perror_lang (env->lang));
+              if_dead_disconnect (env, -1);
+            }
+          else
+            {
+              message_out (message_handler, "%s \"%s\" %s", msg_get (wnn_msg_cat, 200, NULL, env->lang), n, msg_get (wnn_msg_cat, 209, NULL, env->lang));
+              /*
+                 "辞書ファイル \"%s\" を作りました。",
+               */
+              chown (n + 1, getuid (), -1);
+              return (0);
+            }
+        }
+      else
+        {
+          if (js_dic_file_create (env, n, rev_dict_type, NULL, pwd, hpwd) == -1)
+            {
+              message_out (message_handler, wnn_perror_lang (env->lang));
+              if_dead_disconnect (env, -1);
+            }
+          else
+            {
+              message_out (message_handler, "%s \"%s\" %s", msg_get (wnn_msg_cat, 200, NULL, env->lang), n, msg_get (wnn_msg_cat, 209, NULL, env->lang));
+              /*
+                 "辞書ファイル \"%s\" を作りました。",
+               */
+              return (0);
+            }
+        }
+    }
+}
+
+static int
+make_dir_rec1 (env, path, error_handler, message_handler)
+     struct wnn_env *env;
+     register char *path;
+     int (*error_handler) (), (*message_handler) ();
+{
+  char gomi[128];
+  register char *c;
+  for (c = path; *c; c++)
+    {
+      if (*c == '/')
+        {
+          strncpy (gomi, path, c - path);
+          gomi[c - path] = 0;
+          if (make_dir1 (env, gomi, error_handler, message_handler) == -1)
+            {
+              return (-1);
+            }
+        }
+    }
+  return (0);
+}
+
+static int
+make_dir1 (env, dirname, error_handler, message_handler)
+     register struct wnn_env *env;
+     register char *dirname;
+     int (*error_handler) (), (*message_handler) ();
+{
+  char gomi[128];
+  if (dirname[0] == C_LOCAL)
+    {
+      if (*(dirname + 1) == 0)
+        return (0);
+      if (access (dirname + 1, 0) == 0)
+        {                       /* check for existence */
+          return (0);           /* dir already exists */
+        }
+    }
+  else
+    {
+      if (*dirname == 0)
+        return (0);
+      if (js_access (env, dirname, 0) == 0)
+        {                       /* check for existence */
+          return (0);           /* dir already exists */
+        }
+    }
+  if ((int) error_handler != WNN_CREATE)
+    {
+      sprintf (gomi, "%s \"%s\" %s%s", msg_get (wnn_msg_cat, 210, NULL, env->lang), dirname, msg_get (wnn_msg_cat, 201, NULL, env->lang), msg_get (wnn_msg_cat, 202, NULL, env->lang));
+      /*
+         "directry \"%s\" が無いよ。作る?(Y/N)",
+       */
+      if (call_error_handler (error_handler, gomi) == 0)
+        {
+          wnn_errorno = WNN_MKDIR_FAIL;
+          return (-1);
+        }
+    }
+  if (dirname[0] == C_LOCAL)
+    {                           /* Create Directory */
+#define MODE (0000000 | 0000777)
+      if (mkdir (dirname + 1, MODE) != 0)
+        {
+          wnn_errorno = WNN_MKDIR_FAIL;
+          return (-1);
+        }
+
+      chmod (dirname + 1, MODE);
+      chown (dirname + 1, getuid (), -1);
+    }
+  else
+    {
+      if (js_mkdir (env, dirname))
+        {
+          if_dead_disconnect (env, -1);
+        }
+    }
+  return (0);
+}
+
+
+static int
+call_error_handler (error_handler, c)
+     int (*error_handler) ();
+     char *c;
+{
+  register int x;
+  x = error_handler (c);
+  if (confirm_state == CONFIRM1)
+    {
+      if (x)
+        confirm_state = CREATE_WITHOUT_CONFIRM;
+      else
+        confirm_state = NO_CREATE;
+    }
+  return (x);
+}
+
+static void
+message_out (message_handler, format, s1, s2, s3, s4, s5, s6, s7, s8)
+     int (*message_handler) ();
+     char *format;
+     int s1, s2, s3, s4, s5, s6, s7, s8;
+{
+  char buf[256];
+
+  if (message_handler)
+    {
+      sprintf (buf, format, s1, s2, s3, s4, s5, s6, s7, s8);
+      (*message_handler) (buf);
+    }
+}
+
+
+int
+jl_yomi_len (buf, bun_no, bun_no2)
+     struct wnn_buf *buf;
+     register int bun_no, bun_no2;
+{
+  register int len = 0;
+
+  wnn_errorno = 0;
+  if (bun_no2 >= buf->bun_suu || bun_no2 < 0)
+    bun_no2 = buf->bun_suu;
+  for (; bun_no < bun_no2; bun_no++)
+    {
+      len += buf->bun[bun_no]->yomilen;
+    }
+  return (len);
+}
+
+
+int
+jl_kanji_len (buf, bun_no, bun_no2)
+     struct wnn_buf *buf;
+     register int bun_no, bun_no2;
+{
+  register int len = 0;
+
+  wnn_errorno = 0;
+  if (bun_no < 0)
+    return (0);
+  if (bun_no2 >= buf->bun_suu || bun_no2 < 0)
+    bun_no2 = buf->bun_suu;
+  for (; bun_no < bun_no2; bun_no++)
+    {
+      len += buf->bun[bun_no]->kanjilen;
+    }
+  return (len);
+}
+
+int wnn_word_use_initial_hindo = 0;
+
+int
+jl_word_use_e (env, dic_no, entry)
+     register struct wnn_env *env;
+     int dic_no, entry;
+{
+  register struct wnn_jdata *jd;
+
+  wnn_errorno = 0;
+  if (js_word_info (env, dic_no, entry, &rb) == -1)
+    if_dead_disconnect (env, -1);
+  jd = (struct wnn_jdata *) (rb.buf);
+  if (jd->hindo != -1)
+    {
+      if (js_hindo_set (env, dic_no, entry, WNN_IMA_OFF, WNN_ENTRY_NO_USE) == -1)
+        {
+          if_dead_disconnect (env, -1);
+        }
+    }
+  else
+    {
+      if (js_hindo_set (env, dic_no, entry, (wnn_word_use_initial_hindo & 0x80) ? WNN_IMA_ON : WNN_IMA_OFF, wnn_word_use_initial_hindo & 0x7f) == -1)
+        {
+          if_dead_disconnect (env, -1);
+        }
+    }
+  return (0);
+}
+
+void
+jl_env_set (buf, env)
+     register struct wnn_env *env;
+     register struct wnn_buf *buf;
+{
+  wnn_errorno = 0;
+  buf->env = env;
+}
+
+
+struct wnn_env *
+jl_env_get (buf)
+     register struct wnn_buf *buf;
+{
+
+  wnn_errorno = 0;
+  return (buf->env);
+}
+
+
+int
+jl_param_set_e (env, para)
+     register struct wnn_env *env;
+     struct wnn_param *para;
+{
+  register int x;
+
+  wnn_errorno = 0;
+  if ((x = js_param_set (env, para)) == -1)
+    if_dead_disconnect (env, -1);
+  return (x);
+}
+
+int
+jl_param_get_e (env, para)
+     struct wnn_env *env;
+     struct wnn_param *para;
+{
+  register int x;
+  wnn_errorno = 0;
+  if ((x = js_param_get (env, para)) == -1)
+    if_dead_disconnect (env, -1);
+  return (x);
+}
+
+
+int
+jl_dic_use_e (env, dic_no, flag)
+     struct wnn_env *env;
+     int dic_no, flag;
+{
+  register int x;
+  wnn_errorno = 0;
+  if ((x = js_dic_use (env, dic_no, flag)) == -1)
+    if_dead_disconnect (env, -1);
+  return (x);
+}
+
+int
+jl_word_add_e (env, dic_no, yomi, kanji, comment, hinsi, init_hindo)
+     struct wnn_env *env;
+     int dic_no;
+     w_char *yomi, *kanji, *comment;
+     int hinsi, init_hindo;
+
+{
+  register int x;
+  wnn_errorno = 0;
+  if ((x = js_word_add (env, dic_no, yomi, kanji, comment, hinsi, init_hindo)) == -1)
+    if_dead_disconnect (env, -1);
+  return (x);
+}
+
+int
+jl_word_delete_e (env, dic_no, entry)
+     struct wnn_env *env;
+     int dic_no;
+     int entry;
+{
+  register int x;
+  wnn_errorno = 0;
+  if ((x = js_word_delete (env, dic_no, entry)) == -1)
+    if_dead_disconnect (env, -1);
+  return (x);
+}
+
+static int
+file_read (env, fname)
+     struct wnn_env *env;
+     char *fname;
+{
+  register int fid;
+  if (fname[0] == C_LOCAL)
+    {
+      fid = js_file_send (env, fname + 1);
+    }
+  else
+    {
+      fid = js_file_read (env, fname);
+    }
+  if (fid >= 0)
+    {
+      add_file_to_env (env, fid, fname);
+    }
+  return (fid);
+}
+
+static int
+file_remove (server, fname, pwd)
+     register WNN_JSERVER_ID *server;
+     char *fname;
+     char *pwd;
+{
+  if (fname[0] == C_LOCAL)
+    {
+      return (js_file_remove_client (server, fname + 1, pwd));
+    }
+  else
+    {
+      return (js_file_remove (server, fname, pwd));
+    }
+}
+
+
+static int
+file_discard (env, fid)
+     register struct wnn_env *env;
+     register int fid;
+{
+  delete_file_from_env (env, fid);
+  return (js_file_discard (env, fid));
+}
+
+int
+jl_hinsi_number_e (env, name)
+     register struct wnn_env *env;
+     w_char *name;
+{
+  register int x;
+  wnn_errorno = 0;
+  if ((x = js_hinsi_number (env->js_id, name)) == -1)
+    if_dead_disconnect (env, -1);
+  return (x);
+}
+
+w_char *
+jl_hinsi_name_e (env, no)
+     register struct wnn_env *env;
+     register int no;
+{
+  wnn_errorno = 0;
+  if (js_hinsi_name (env->js_id, no, &rb) == -1)
+    if_dead_disconnect (env, NULL);
+  return ((w_char *) (rb.buf));
+}
+
+int
+jl_hinsi_list_e (env, dic_no, name, area)
+     register struct wnn_env *env;
+     int dic_no;
+     w_char *name;
+     w_char ***area;
+{
+  int x;
+  wnn_errorno = 0;
+  if ((x = js_hinsi_list (env, dic_no, name, &rb)) == -1)
+    if_dead_disconnect (env, -1);
+  *area = (w_char **) (rb.buf);
+  return (x);
+}
+
+int
+jl_hinsi_dicts_e (env, no, area)
+     register struct wnn_env *env;
+     int no;
+     int **area;
+{
+  int x;
+  wnn_errorno = 0;
+  if ((x = js_hinsi_dicts (env, no, &rb)) == -1)
+    if_dead_disconnect (env, -1);
+  *area = (int *) (rb.buf);
+  return (x);
+}
+
+
+int
+jl_word_comment_set_e (env, dic_no, entry, comment)
+     register struct wnn_env *env;
+     int dic_no, entry;
+     w_char *comment;
+{
+  register int x;
+  wnn_errorno = 0;
+  if ((x = js_word_comment_set (env, dic_no, entry, comment)) == -1)
+    if_dead_disconnect (env, -1);
+  return (x);
+}
+
+int
+jl_dic_comment_set_e (env, dic_no, comment)
+     register struct wnn_env *env;
+     int dic_no;
+     w_char *comment;
+{
+  register int x;
+  WNN_DIC_INFO dic;
+  WNN_FILE_INFO_STRUCT file;
+
+  wnn_errorno = 0;
+  if (js_dic_info (env, dic_no, &dic) < 0)
+    if_dead_disconnect (env, -1);
+  /*  dic Body        */
+  if (js_file_info (env, dic.body, &file) < 0)
+    if_dead_disconnect (env, -1);
+  if ((x = js_file_comment_set (env, file.fid, comment)) == -1)
+    if_dead_disconnect (env, -1);
+  return (x);
+}
+
+#ifdef nodef                    /*当面の間、頻度ファイルのコメントはユーザに見せない。 */
+int
+jl_hindo_comment_set_e (env, dic_no, comment)
+     register struct wnn_env *env;
+     int dic_no;
+     w_char *comment;
+{
+  register int x;
+  WNN_DIC_INFO dic;
+  WNN_FILE_INFO_STRUCT file;
+
+  wnn_errorno = 0;
+  if (js_dic_info (env, dic_no, &dic) < 0)
+    if_dead_disconnect (env, -1);
+  /*  dic Body        */
+  if (dic.hindo == -1)
+    {
+      wnn_errorno = WNN_NO_HINDO_FILE;
+      return (-1);
+    }
+  if (js_file_info (env, dic.hindo, &file) < 0)
+    if_dead_disconnect (env, -1);
+  if ((x = js_file_comment_set (env, file.fid, comment)) == -1)
+    if_dead_disconnect (env, -1);
+  return (x);
+}
+#endif