しらいです。

 file & directory 管理ツール FDclone 2.09 の patch その 2
です。

Submitted-by: shirai@chandra2
Archive-name: FD-2.09.patch/part02

---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is `FD-2.09.shar.02' (part 2 of FD-2.09.patch).
# Do not concatenate these parts, unpack them in order with `/bin/sh'.
# File `FD-2.09.patch' is being continued...
#
echo=echo
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  $echo 'WARNING: not restoring timestamps.  Consider getting and'
  $echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
if test ! -r _sh00904/seq; then
  $echo 'Please unpack part 1 first!'
  exit 1
fi
shar_sequence=`cat _sh00904/seq`
if test "$shar_sequence" != 2; then
  $echo 'Please unpack part' "$shar_sequence" 'next!'
  exit 1
fi
if test ! -f _sh00904/new; then
  $echo 'x -' 'STILL SKIPPING' 'FD-2.09.patch'
else
  $echo 'x -' 'continuing file' 'FD-2.09.patch'
  sed 's/^X//' << 'SHAR_EOF' >> FD-2.09.patch &&
+#ifndef        _NOEXTRACOPY
+       fshowprogress(path);
+#endif
X 
X       return(APL_OK);
X }
@@ -754,6 +962,9 @@
X       if ((n = checkrmv(path, R_OK | W_OK | X_OK)) < 0)
X               return((n == CHK_CANCEL) ? APL_CANCEL : APL_IGNORE);
X       if (Xrmdir(path) < 0) return(APL_ERROR);
+#ifndef        _NOEXTRACOPY
+       fshowprogress(path);
+#endif
X 
X       return(APL_OK);
X }
@@ -1418,6 +1629,9 @@
X               i = (*func)(fnodospath(path, filepos));
X               if (i == APL_ERROR) warning(-1, filelist[filepos].name);
X               else if (i == APL_OK) ret++;
+#ifndef        _NOEXTRACOPY
+               if (endmes && copyline > 0) _showprogress(n_column);
+#endif
X               return(ret);
X       }
X 
@@ -1443,7 +1657,12 @@
X               old = filepos;
X       }
X 
-       if (endmes) warning(0, endmes);
+       if (endmes) {
+#ifndef        _NOEXTRACOPY
+               if (copyline > 0) _showprogress(n_column);
+#endif
+               warning(0, endmes);
+       }
X       filepos = dupfilepos;
X       movepos(old, 0);
X       Xlocate(win_x, win_y);
@@ -1592,7 +1811,12 @@
X               if (ret == APL_CANCEL) return(ret);
X               warning(-1, dir);
X       }
-       if (endmes) warning(0, endmes);
+       if (endmes) {
+#ifndef        _NOEXTRACOPY
+               if (copyline > 0) _showprogress(n_column);
+#endif
+               warning(0, endmes);
+       }
X 
X       return(ret);
X }
@@ -1649,7 +1873,10 @@
X       destdir = NULL;
X       if (mark > 0
X       || (!isdir(&(filelist[filepos])) || islink(&(filelist[filepos])))) {
-               preparecopy();
+               if (preparecopy(0, mark) < 0) {
+                       free(destpath);
+                       return(FNC_CANCEL);
+               }
X               VOID_C applyfile(safecopy, ENDCP_K);
X       }
X #ifdef        _NOEXTRACOPY
@@ -1660,7 +1887,10 @@
X       }
X #endif
X       else {
-               preparecopy();
+               if (preparecopy(1, 1) < 0) {
+                       free(destpath);
+                       return(FNC_CANCEL);
+               }
X               order = (islowerdir()) ? ORD_LOWER : ORD_NORMAL;
X               VOID_C applydir(filelist[filepos].name, safecopy,
X                       cpdir, touchdir, order, ENDCP_K);
@@ -1717,7 +1947,10 @@
X       }
X       destdir = NULL;
X       if (mark > 0) {
-               preparemove();
+               if (preparemove(0, mark) < 0) {
+                       free(destpath);
+                       return(FNC_CANCEL);
+               }
X               filepos = applyfile(safemove, ENDMV_K);
X       }
X       else if (islowerdir()) warning(EINVAL, filelist[filepos].name);
@@ -1729,7 +1962,10 @@
X               else ret = isxdev(fnodospath(path, filepos), NULL);
X               if (ret < 0) warning(-1, filelist[filepos].name);
X               else if (ret) {
-                       preparemove();
+                       if (preparemove(1, 1) < 0) {
+                               free(destpath);
+                               return(FNC_CANCEL);
+                       }
X # ifndef      _NODOSDRIVE
X                       if (dospath3(nullstr)) waitmes();
X # endif
@@ -1740,7 +1976,10 @@
X               else
X #endif        /* !_NOEXTRACOPY */
X               {
-                       preparemove();
+                       if (preparemove(0, 1) < 0) {
+                               free(destpath);
+                               return(FNC_CANCEL);
+                       }
X                       ret = safemove(fnodospath(path, filepos));
X                       if (ret == APL_ERROR)
X                               warning(-1, filelist[filepos].name);
diff -urNP ../FD-2.08f/archive.c ./archive.c
--- ../FD-2.08f/archive.c       Tue Aug  8 00:00:00 2006
+++ ./archive.c Tue Aug 22 00:00:00 2006
@@ -19,6 +19,9 @@
X #endif
X 
X extern int mark;
+#if    FD >= 2
+extern int sorttype;
+#endif
X extern int stackdepth;
X #ifndef       _NOTRADLAYOUT
X extern int tradlayout;
@@ -2105,7 +2108,11 @@
X       launchp = list;
X       filelist = NULL;
X       maxent = 0;
+#if    FD >= 2
+       if (sorttype < 200) sorton = 0;
+#else
X       sorton = 0;
+#endif
X 
X       if (readarchive(archivefile, launchp, flags) < 0) {
X               arcflist = NULL;
diff -urNP ../FD-2.08f/browse.c ./browse.c
--- ../FD-2.08f/browse.c        Tue Aug  8 00:00:00 2006
+++ ./browse.c  Tue Aug 22 00:00:00 2006
@@ -53,6 +53,7 @@
X #define       CL_FIFO         7
X #define       CL_BLOCK        8
X #define       CL_CHAR         9
+#define        CL_EXE          10
X #define       ANSI_FG         8
X #define       ANSI_BG         9
X 
@@ -130,6 +131,9 @@
X char *macrolist[MAXMACROTABLE];
X int maxmacro = 0;
X int isearch = 0;
+#if    FD >= 2
+int helplayout = 0;
+#endif
X char *helpindex[MAXHELPINDEX] = {
X #ifdef        _NOTREE
X       "help",
@@ -148,6 +152,26 @@
X #else
X       "Unpack",
X #endif
+#if    FD >= 2
+       "Attr", "Info", "Move", "rmDir", "mKdir",
+       "sHell",
+# ifdef        _NOWRITEFS
+       "",
+# else
+       "Write",
+# endif
+# ifdef        _NOARCHIVE
+       "",
+# else
+       "Backup",
+# endif
+       "View",
+# ifdef        _NOARCHIVE
+       "",
+# else
+       "Pack",
+# endif
+#endif /* FD >= 2 */
X };
X char typesymlist[] = "dbclsp";
X u_short typelist[] = {
@@ -171,6 +195,8 @@
X #endif
X #ifndef       _NOSPLITWIN
X int windows = 1;
+#endif
+#if    !defined (_NOSPLITWIN) || !defined (_NOPTY)
X int win = 0;
X #endif
X int calc_x = -1;
@@ -199,6 +225,7 @@
X       ANSI_RED,       /* CL_FIFO */
X       ANSI_FG,        /* CL_BLOCK */
X       ANSI_FG,        /* CL_CHAR */
+       ANSI_FG,        /* CL_EXE */
X };
X #endif        /* !_NOCOLOR */
X #ifndef       _NOPRECEDE
@@ -220,6 +247,7 @@
X       for (i = 0; i < MAXMODELIST; i++)
X               if ((namep -> st_mode & S_IFMT) == modelist[i])
X                       return(colorlist[i]);
+       if (isexec(namep)) return(CL_EXE);
X 
X       return(CL_REG);
X }
@@ -291,8 +319,20 @@
X {
X       int i, j, col, gap, width, len, ofs, max, blk, rest;
X 
-       max = MAXHELPINDEX;
-       blk = 5;
+#if    FD >= 2
+       if (helplayout) {
+               max = helplayout / 100;
+               blk = helplayout % 100;
+               if (max < 0) max = FUNCLAYOUT / 100;
+               else if (max > MAXHELPINDEX) max = MAXHELPINDEX;
+               if (blk <= 0 || blk > max) blk = max;
+       }
+       else
+#endif
+       {
+               max = FUNCLAYOUT / 100;
+               blk = FUNCLAYOUT % 100;
+       }
X 
X       if (ishardomit()) {
X               col = n_column;
@@ -314,6 +354,7 @@
X               col = n_column - 1;
X               gap = 3;
X       }
+       if (max > FUNCLAYOUT / 100) gap = 1;
X 
X       rest = max - 1 + gap * ((max - 1) / blk);
X       width = (col - 4 - rest) / max;
diff -urNP ../FD-2.08f/builtin.c ./builtin.c
--- ../FD-2.08f/builtin.c       Tue Aug  8 00:00:00 2006
+++ ./builtin.c Tue Aug 22 00:00:00 2006
@@ -20,6 +20,10 @@
X #include "termemu.h"
X #endif
X 
+#ifndef        _NOIME
+#include "roman.h"
+#endif
+
X #define       MD5_BUFSIZ      (128 / 32)
X #define       MD5_BLOCKS      16
X 
@@ -69,6 +73,10 @@
X #ifndef       _NOPTY
X extern int parentfd;
X #endif
+#ifndef        _NOIME
+extern romantable *romanlist;
+extern int maxromanlist;
+#endif
X 
X static VOID NEAR builtinerror __P_((char *[], char *, int));
X #ifdef        _NOORIGSHELL
@@ -77,7 +85,7 @@
X #define       hitkey(n)
X #endif
X static VOID NEAR fputsmeta __P_((char *, FILE *));
-#if    !defined (_NOARCHIVE) && !defined(_NOBROWSE)
+#if    (!defined (_NOARCHIVE) && !defined(_NOBROWSE)) || !defined (_NOIME)
X static char **NEAR file2argv __P_((FILE *, char *, int));
X #endif
X #ifndef       _NOARCHIVE
@@ -125,6 +133,11 @@
X #if   !MSDOS && (FD >= 2)
X static int NEAR savetty __P_((int, char *[]));
X #endif
+#ifndef        _NOIME
+static int NEAR setroman __P_((int, char *[]));
+static VOID NEAR disproman __P_((char *, int, FILE *));
+static int NEAR printroman __P_((int, char *[]));
+#endif
X #ifdef        _NOORIGSHELL
X static int NEAR printenv __P_((int, char *[]));
X static int NEAR setalias __P_((int, char *[]));
@@ -216,6 +229,10 @@
X #if   !MSDOS && (FD >= 2)
X       {savetty,       BL_SAVETTY},
X #endif
+#ifndef        _NOIME
+       {setroman,      BL_SETROMAN},
+       {printroman,    BL_PRINTROMAN},
+#endif
X #ifdef        _NOORIGSHELL
X # if  FD >= 2
X       {printenv,      BL_SET},
@@ -305,7 +322,7 @@
X       }
X }
X 
-#if    !defined (_NOARCHIVE) && !defined(_NOBROWSE)
+#if    (!defined (_NOARCHIVE) && !defined(_NOBROWSE)) || !defined (_NOIME)
X static char **NEAR file2argv(fp, s, whole)
X FILE *fp;
X char *s;
@@ -384,7 +401,7 @@
X 
X       return(argv);
X }
-#endif /* !_NOARCHIVE && !_NOBROWSE */
+#endif /* (!_NOARCHIVE && !_NOBROWSE) || !_NOIME */
X 
X #ifndef       _NOARCHIVE
X # if  FD >= 2
@@ -2778,6 +2795,149 @@
X }
X # endif       /* FD >= 2 */
X #endif        /* !MSDOS */
+
+#ifndef        _NOIME
+static int NEAR setroman(argc, argv)
+int argc;
+char *argv[];
+{
+       FILE *fp;
+       char *file, **args;
+       int i, n, skip, clean;
+
+       file = NULL;
+       skip = clean = 0;
+       for (n = 1; n < argc && argv[n][0] == '-'; n++) {
+               skip = 0;
+               for (i = 1; argv[n][i]; i++) {
+                       skip = 0;
+                       switch (argv[n][i]) {
+                               case 'c':
+                                       clean = 2;
+                                       break;
+                               case 'r':
+                                       clean = 1;
+                                       break;
+                               case 'f':
+                                       if (argv[n][i + 1]) {
+                                               file = &(argv[n][i + 1]);
+                                               skip = 1;
+                                       }
+                                       else if (n + 1 < argc) {
+                                               file = argv[++n];
+                                               skip = 1;
+                                       }
+                                       else skip = -1;
+                                       break;
+                               default:
+                                       skip = -1;
+                                       break;
+                       }
+                       if (skip) {
+                               skip--;
+                               break;
+                       }
+               }
+               if (skip) {
+                       skip--;
+                       break;
+               }
+       }
+       if (skip || (!file && !clean && n >= argc)) {
+               fprintf2(stderr,
+                       "%k: usage: %k [-c] [-r] [-f file] [roman [kanji]]]",
+                       argv[0], argv[0]);
+               fputnl(stderr);
+               return(-1);
+       }
+
+       if (clean) {
+               freeroman(clean - 1);
+# ifndef        _NOPTY
+               sendparent(TE_FREEROMAN, clean - 1);
+# endif
+       }
+
+       if (!file) fp = NULL;
+       else if (!(fp = Xfopen(file, "r"))) {
+               builtinerror(argv, file, -1);
+               return(-1);
+       }
+       else for (;;) {
+               args = file2argv(fp, argv[0], 0);
+               i = 1;
+               if (args[i] && !strcommcmp(args[i], BL_SETROMAN)) i++;
+
+               if (!args[i]) /*EMPTY*/;
+               else if (addroman(args[i], args[i + 1]) < 0)
+                       builtinerror(argv, args[i], ER_SYNTAXERR);
+# ifndef        _NOPTY
+               else sendparent(TE_ADDROMAN, args[i], args[i + 1]);
+# endif
+               freevar(args);
+
+               if (Xfeof(fp)) break;
+       }
+       if (fp) Xfclose(fp);
+
+       if (n >= argc) /*EMPTY*/;
+       else if (addroman(argv[n], argv[n + 1]) < 0) {
+               builtinerror(argv, argv[n], ER_SYNTAXERR);
+               return(-1);
+       }
+# ifndef        _NOPTY
+       else sendparent(TE_ADDROMAN, argv[n], argv[n + 1]);
+# endif
+
+       return(0);
+}
+
+static VOID NEAR disproman(s, n, fp)
+char *s;
+int n;
+FILE *fp;
+{
+       char buf[2 + 1];
+       int i;
+
+       if (s && *s) fprintf2(fp, "%s ", s);
+       fprintf2(fp, "%s \"", romanlist[n].str);
+       for (i = 0; i < R_MAXKANA; i++) {
+               if (!romanlist[n].code[i]) break;
+               VOID_C jis2str(buf, romanlist[n].code[i]);
+               fprintf2(fp, "%k", buf);
+       }
+       fputc('"', fp);
+       fputnl(fp);
+}
+
+static int NEAR printroman(argc, argv)
+int argc;
+char *argv[];
+{
+       int i, n, ret;
+
+       initroman();
+       ret = -1;
+
+       if (argc < 2) {
+               for (i = 0; i < maxromanlist; i++)
+                       disproman(BL_SETROMAN, i, stdout);
+               ret = 0;
+       }
+       else for (n = 1; n < argc; n++) {
+               if (!*(argv[n])
+               || (i = searchroman(argv[n], strlen(argv[n]))) < 0) {
+                       builtinerror(argv, argv[n], ER_NOENTRY);
+                       continue;
+               }
+               disproman(BL_PRINTROMAN, i, stdout);
+               ret = 0;
+       }
+
+       return(ret);
+}
+#endif /* !_NOIME */
X 
X #ifdef        _NOORIGSHELL
X static int NEAR printenv(argc, argv)
diff -urNP ../FD-2.08f/command.c ./command.c
--- ../FD-2.08f/command.c       Tue Aug  8 00:00:00 2006
+++ ./command.c Tue Aug 22 00:00:00 2006
@@ -1424,7 +1424,7 @@
X 
X       if (mark > 0) {
X               if (!yesno(DELMK_K)) return(FNC_CANCEL);
-               prepareremove();
+               if (prepareremove(0, mark) < 0) return(FNC_CANCEL);
X               filepos = applyfile(rmvfile, NULL);
X       }
X       else if (isdir(&(filelist[filepos]))) return(warning_bell(arg));
@@ -1433,7 +1433,7 @@
X               len = strlen2(cp) - strsize("%.*s");
X               if (!yesno(cp, n_lastcolumn - len, filelist[filepos].name))
X                       return(FNC_CANCEL);
-               prepareremove();
+               if (prepareremove(0, 1) < 0) return(FNC_CANCEL);
X               filepos = applyfile(rmvfile, NULL);
X       }
X       if (filepos >= maxfile && (filepos -= 2) < 0) filepos = 0;
@@ -1459,14 +1459,14 @@
X       cp = filelist[filepos].name;
X #ifndef       NOSYMLINK
X       if (islink(&(filelist[filepos]))) {
-               prepareremove();
+               if (prepareremove(0, 1) < 0) return(FNC_CANCEL);
X               ret = rmvfile(fnodospath(path, filepos));
X               if (ret == APL_ERROR) warning(-1, cp);
X       }
X       else
X #endif
X       {
-               prepareremove();
+               if (prepareremove(1, 1) < 0) return(FNC_CANCEL);
X               ret = applydir(cp, rmvfile, NULL, rmvdir, ORD_NOPREDIR, NULL);
X       }
X       if (ret == APL_OK) filepos++;
diff -urNP ../FD-2.08f/custom.c ./custom.c
--- ../FD-2.08f/custom.c        Tue Aug  8 00:00:00 2006
+++ ./custom.c  Tue Aug 22 00:00:00 2006
@@ -25,15 +25,19 @@
X #if   !defined (_USEDOSCOPY) && !defined (_NOEXTRACOPY)
X extern int inheritcopy;
X #endif
+#ifndef        _NOEXTRACOPY
+extern int progressbar;
+extern int precopymenu;
+#endif
X #if   !MSDOS
X extern int adjtty;
X #endif
X extern int hideclock;
X extern int defcolumns;
X extern int minfilename;
-extern char *histfile;
+extern char *histfile[];
X extern short histsize[];
-extern int savehist;
+extern short savehist[];
X #ifndef       _NOTREE
X extern int dircountlimit;
X #endif
@@ -45,6 +49,13 @@
X extern int tradlayout;
X #endif
X extern int sizeinfo;
+#if    FD >= 2
+extern int helplayout;
+#endif
+#ifndef        _NOIME
+extern int imekey;
+extern int imebuffer;
+#endif
X #ifndef       _NOCOLOR
X extern int ansicolor;
X # if  FD >= 2
@@ -84,6 +95,7 @@
X extern char *cappath;
X extern char *utf8path;
X extern char *utf8macpath;
+extern char *utf8iconvpath;
X extern char *noconvpath;
X #endif        /* !_NOKANJIFCONV */
X #if   FD >= 2
@@ -118,6 +130,9 @@
X #ifdef        _USEUNICODE
X extern char *unitblpath;
X #endif
+#ifndef        _NOIME
+extern char *dicttblpath;
+#endif
X #ifndef       _NOCUSTOMIZE
X extern int curcolumns;
X extern int subwindow;
@@ -160,9 +175,16 @@
X #define       MAXCUSTVAL      (n_column - MAXCUSTNAM - 3)
X #define       noselect(n, m, x, s, v) \
X                       (selectstr(n, m, x, s, v) != K_CR)
+#define        getmax(m, n)    do { \
+                               cs_max = ((!(n) & basiccustom) \
+                                       ? nbasic : (m)[n]); \
+                       } while (0)
+#define        setmax(m, n)    do { \
+                               if (!(n)) (m)[n] = cs_max; \
+                       } while (0)
X #define       MAXSAVEMENU     5
-#define        DEFPALETTE      "8962435188"
-#define        MAXPALETTE      10
+#define        DEFPALETTE      "89624351888"
+#define        MAXPALETTE      11
X #define       MAXCOLOR        10
X #ifndef       O_TEXT
X #define       O_TEXT          0
@@ -191,6 +213,7 @@
X #define       env_str(n)      (&(envlist[n].env[FDESIZ]))
X #define       fdenv_str(n)    (envlist[n].env)
X #define       env_type(n)     (envlist[n].type & T_TYPE)
+#define        _B_(t)          (T_BASIC | (t))
X #ifdef        FORCEDSTDC
X #define       def_str(n)      (envlist[n].def.str)
X #define       def_num(n)      (envlist[n].def.num)
@@ -203,6 +226,7 @@
X 
X #define       T_TYPE          0037
X #define       T_PRIMAL        0040
+#define        T_BASIC         0100
X #define       T_BOOL          0
X #define       T_SHORT         1
X #define       T_INT           2
@@ -226,10 +250,12 @@
X #define       T_KOUT          16
X #define       T_KNAM          17
X #define       T_KTERM         18
-#define        T_KPATHS        19
-#define        T_OCTAL         20
-#define        T_KEYCODE       21
-#define        T_NOVAR         22
+#define        T_MESLANG       19
+#define        T_KPATHS        20
+#define        T_OCTAL         21
+#define        T_KEYCODE       22
+#define        T_HELP          23
+#define        T_NOVAR         24
X 
X #ifndef       _NOKANJIFCONV
X typedef struct _pathtable {
@@ -349,11 +375,17 @@
X 
X #ifndef       _NOCUSTOMIZE
X int custno = -1;
+int basiccustom = 0;
X #endif
X 
X static envtable envlist[] = {
-       {"FD_SORTTYPE", &sorttype, DEFVAL(SORTTYPE), STTP_E, T_SORT},
-       {"FD_DISPLAYMODE", &displaymode, DEFVAL(DISPLAYMODE), DPMD_E, T_DISP},
+#ifndef        _NOCUSTOMIZE
+       {"FD_BASICCUSTOM", &basiccustom,
+               DEFVAL(BASICCUSTOM), BSCS_E, _B_(T_BOOL)},
+#endif
+       {"FD_SORTTYPE", &sorttype, DEFVAL(SORTTYPE), STTP_E, _B_(T_SORT)},
+       {"FD_DISPLAYMODE", &displaymode,
+               DEFVAL(DISPLAYMODE), DPMD_E, _B_(T_DISP)},
X #ifndef       _NOTREE
X       {"FD_SORTTREE", &sorttree, DEFVAL(SORTTREE), STTR_E, T_BOOL},
X #endif
@@ -366,6 +398,10 @@
X #if   !defined (_USEDOSCOPY) && !defined (_NOEXTRACOPY)
X       {"FD_INHERITCOPY", &inheritcopy, DEFVAL(INHERITCOPY), IHTM_E, T_BOOL},
X #endif
+#ifndef        _NOEXTRACOPY
+       {"FD_PROGRESSBAR", &progressbar, DEFVAL(PROGRESSBAR), PRGB_E, T_BOOL},
+       {"FD_PRECOPYMENU", &precopymenu, DEFVAL(PRECOPYMENU), PCMN_E, T_BOOL},
+#endif
X #if   !MSDOS
X       {"FD_ADJTTY", &adjtty, DEFVAL(ADJTTY), AJTY_E, T_BOOL},
X # if  FD >= 2
@@ -373,13 +409,24 @@
X               DEFVAL(USEGETCURSOR), UGCS_E, T_BOOL},
X # endif
X #endif        /* !MSDOS */
-       {"FD_DEFCOLUMNS", &defcolumns, DEFVAL(DEFCOLUMNS), CLMN_E, T_COLUMN},
+       {"FD_DEFCOLUMNS", &defcolumns,
+               DEFVAL(DEFCOLUMNS), CLMN_E, _B_(T_COLUMN)},
X       {"FD_MINFILENAME", &minfilename,
X               DEFVAL(MINFILENAME), MINF_E, T_NATURAL},
-       {"FD_HISTFILE", &histfile, DEFVAL(HISTFILE), HSFL_E, T_PATH},
-       {"FD_HISTSIZE", &(histsize[0]), DEFVAL(HISTSIZE), HSSZ_E, T_SHORT},
-       {"FD_DIRHIST", &(histsize[1]), DEFVAL(DIRHIST), DRHS_E, T_SHORT},
-       {"FD_SAVEHIST", &savehist, DEFVAL(SAVEHIST), SVHS_E, T_INT},
+       {"FD_HISTFILE", &(histfile[0]), DEFVAL(HISTFILE), HSFL_E, T_PATH},
+#if    FD >= 2
+       {"FD_DIRHISTFILE", &(histfile[1]),
+               DEFVAL(DIRHISTFILE), DHFL_E, T_PATH},
+#endif
+       {"FD_HISTSIZE", &(histsize[0]),
+               DEFVAL(HISTSIZE), HSSZ_E, _B_(T_SHORT)},
+       {"FD_DIRHIST", &(histsize[1]), DEFVAL(DIRHIST), DRHS_E, _B_(T_SHORT)},
+       {"FD_SAVEHIST", &(savehist[0]),
+               DEFVAL(SAVEHIST), SVHS_E, _B_(T_SHORT)},
+#if    FD >= 2
+       {"FD_SAVEDIRHIST", &(savehist[1]),
+               DEFVAL(SAVEDIRHIST), SVDH_E, T_SHORT},
+#endif
X #ifndef       _NOTREE
X       {"FD_DIRCOUNTLIMIT", &dircountlimit,
X               DEFVAL(DIRCOUNTLIMIT), DCLM_E, T_INT},
@@ -387,13 +434,20 @@
X #ifndef       _NODOSDRIVE
X       {"FD_DOSDRIVE", &dosdrive, DEFVAL(DOSDRIVE), DOSD_E, T_DDRV},
X #endif
-       {"FD_SECOND", &showsecond, DEFVAL(SECOND), SCND_E, T_BOOL},
+       {"FD_SECOND", &showsecond, DEFVAL(SECOND), SCND_E, _B_(T_BOOL)},
X #ifndef       _NOTRADLAYOUT
X       {"FD_TRADLAYOUT", &tradlayout, DEFVAL(TRADLAYOUT), TRLO_E, T_BOOL},
X #endif
-       {"FD_SIZEINFO", &sizeinfo, DEFVAL(SIZEINFO), SZIF_E, T_BOOL},
+       {"FD_SIZEINFO", &sizeinfo, DEFVAL(SIZEINFO), SZIF_E, _B_(T_BOOL)},
+#if    FD >= 2
+       {"FD_FUNCLAYOUT", &helplayout, DEFVAL(FUNCLAYOUT), FNLO_E, T_HELP},
+#endif
+#ifndef        _NOIME
+       {"FD_IMEKEY", &imekey, DEFVAL(IMEKEY), IMKY_E, T_KEYCODE},
+       {"FD_IMEBUFFER", &imebuffer, DEFVAL(IMEBUFFER), IMBF_E, T_BOOL},
+#endif
X #ifndef       _NOCOLOR
-       {"FD_ANSICOLOR", &ansicolor, DEFVAL(ANSICOLOR), ACOL_E, T_COLOR},
+       {"FD_ANSICOLOR", &ansicolor, DEFVAL(ANSICOLOR), ACOL_E, _B_(T_COLOR)},
X # if  FD >= 2
X       {"FD_ANSIPALETTE", &ansipalette,
X               DEFVAL(ANSIPALETTE), APAL_E, T_COLORPAL},
@@ -450,13 +504,13 @@
X #endif
X #if   !defined (_NOKANJICONV) \
X || (!defined (_NOENGMES) && !defined (_NOJPNMES))
-       {"FD_LANGUAGE", &outputkcode, DEFVAL(NOCNV), LANG_E, T_KOUT},
+       {"FD_LANGUAGE", &outputkcode, DEFVAL(NOCNV), LANG_E, _B_(T_KOUT)},
X #endif
X #ifndef       _NOKANJIFCONV
X       {"FD_DEFKCODE", &defaultkcode, DEFVAL(NOCNV), DFKC_E, T_KNAM},
X #endif
X #ifndef       _NOKANJICONV
-       {"FD_INPUTKCODE", &inputkcode, DEFVAL(NOCNV), IPKC_E, T_KIN},
+       {"FD_INPUTKCODE", &inputkcode, DEFVAL(NOCNV), IPKC_E, _B_(T_KIN)},
X #endif
X #if   !defined (_NOKANJICONV) && !defined (_NOPTY)
X       {"FD_PTYINKCODE", &ptyinkcode, DEFVAL(NOCNV), PIKC_E, T_KTERM},
@@ -464,6 +518,11 @@
X #endif
X #ifndef       _NOKANJIFCONV
X       {"FD_FNAMEKCODE", &fnamekcode, DEFVAL(NOCNV), FNKC_E, T_KNAM},
+#endif
+#if    !defined (_NOENGMES) && !defined (_NOJPNMES)
+       {"FD_MESSAGELANG", &messagelang, DEFVAL(NOCNV), MESL_E, T_MESLANG},
+#endif
+#ifndef        _NOKANJIFCONV
X       {"FD_SJISPATH", &sjispath, DEFVAL(SJISPATH), SJSP_E, T_KPATHS},
X       {"FD_EUCPATH", &eucpath, DEFVAL(EUCPATH), EUCP_E, T_KPATHS},
X       {"FD_JISPATH", &jis7path, DEFVAL(JISPATH), JISP_E, T_KPATHS},
@@ -477,6 +536,8 @@
X       {"FD_UTF8PATH", &utf8path, DEFVAL(UTF8PATH), UTF8P_E, T_KPATHS},
X       {"FD_UTF8MACPATH", &utf8macpath,
X               DEFVAL(UTF8MACPATH), UTF8MACP_E, T_KPATHS},
+       {"FD_UTF8ICONVPATH", &utf8iconvpath,
+               DEFVAL(UTF8ICONVPATH), UTF8ICONVP_E, T_KPATHS},
X       {"FD_NOCONVPATH", &noconvpath, DEFVAL(NOCONVPATH), NCVP_E, T_KPATHS},
X #endif        /* !_NOKANJIFCONV */
X #ifndef       _NOCUSTOMIZE
@@ -501,6 +562,9 @@
X # ifdef       _USEUNICODE
X       {&unitblpath, NULL, NOCNV, P_STABLE},
X # endif
+# ifndef       _NOIME
+       {&dicttblpath, NULL, NOCNV, P_STABLE},
+# endif
X };
X #define       PATHLISTSIZ     arraysize(pathlist)
X # ifndef      _NOSPLITWIN
@@ -525,6 +589,8 @@
X };
X #define       MEDIADESCRSIZ   arraysize(mediadescr)
X # endif       /* _USEDOSEMU */
+static char basicenv[ENVLISTSIZ];
+static int nbasic = 0;
X static int cs_item = 0;
X static int cs_max = 0;
X static int cs_row = 0;
@@ -728,6 +794,7 @@
X               case T_KOUT:
X               case T_KNAM:
X               case T_KTERM:
+               case T_MESLANG:
X                       n = (1 << (env_type(no) - T_KIN));
X                       *((int *)(envlist[no].var)) = getlang(cp, n);
X                       break;
@@ -738,12 +805,20 @@
X                       *((int *)(envlist[no].var)) = n;
X                       break;
X #endif
-#ifndef        _NOPTY
+#if    !defined (_NOPTY) || !defined (_NOIME)
X               case T_KEYCODE:
X                       if ((n = getkeycode(cp, 0)) < 0) n = def_num(no);
X                       *((int *)(envlist[no].var)) = n;
X                       break;
X #endif
+#if    FD >= 2
+               case T_HELP:
+                       if ((n = atoi2(cp)) < 0 || (n / 100) > MAXHELPINDEX
+                       || (n % 100) > (n / 100))
+                               n = def_num(no);
+                       *((int *)(envlist[no].var)) = n;
+                       break;
+#endif
X #ifndef       _NOCUSTOMIZE
X               case T_NOVAR:
X                       break;
@@ -884,7 +959,7 @@
X 
X #ifndef       _NOKANJIFCONV
X       type = env_type(n);
-       if (type < T_KIN || type > T_KPATHS) type = -1;
+       if (type != T_KPATHS && (type < T_KIN || type > T_KTERM)) type = -1;
X       if (type >= 0) savepathlang();
X #endif
X       _evalenv(n);
@@ -1344,6 +1419,7 @@
X       int n, p;
X 
X       new = NULL;
+       if (basiccustom) no = basicenv[no];
X       switch (env_type(no)) {
X               case T_BOOL:
X                       str[0] = VBOL0_K;
@@ -1382,7 +1458,12 @@
X                       }
X                       if (p) {
X                               new = strcatalloc(new, ", ");
-                               new = strcatalloc(new, VSORT_K);
+#if    FD >= 2
+                               if (p > 1) cp = VSARC_K;
+                               else
+#endif
+                               cp = VSORT_K;
+                               new = strcatalloc(new, cp);
X                       }
X                       cp = new;
X                       break;
@@ -1473,6 +1554,7 @@
X               case T_KOUT:
X               case T_KNAM:
X               case T_KTERM:
+               case T_MESLANG:
X                       str[NOCNV] = VNCNV_K;
X                       str[ENG] = VENG_K;
X #  ifndef     _NOKANJICONV
@@ -1488,6 +1570,7 @@
X                       str[CAP] = "CAP";
X                       str[UTF8] = "UTF-8";
X                       str[M_UTF8] = "UTF-8 for Mac OS X";
+                       str[I_UTF8] = "UTF-8 for iconv";
X #  endif      /* !_NOKANJICONV */
X                       cp = str[*((int *)(envlist[no].var))];
X                       break;
@@ -1497,11 +1580,24 @@
X                       cp = ascoctal(*((int *)(envlist[no].var)), buf);
X                       break;
X # endif
-# ifndef       _NOPTY
+# if   !defined (_NOPTY) || !defined (_NOIME)
X               case T_KEYCODE:
X                       cp = getenv2(fdenv_str(no));
X                       break;
X # endif
+# if   FD >= 2
+               case T_HELP:
+                       n = *((int *)(envlist[no].var));
+                       p = n / 100;
+                       n %= 100;
+                       new = strdup2(VFNMX_K);
+                       new = strcatalloc(new, int2str(buf, p));
+                       new = strcatalloc(new, ", ");
+                       new = strcatalloc(new, VFNBR_K);
+                       new = strcatalloc(new, int2str(buf, n));
+                       cp = new;
+                       break;
+# endif        /* FD >= 2 */
X               default:
X                       if (!(cp = getenv2(fdenv_str(no)))) cp = def_str(no);
X                       break;
@@ -1527,6 +1623,7 @@
X       for (n = 0; n < MAXSELECTSTRS; n++) val[n] = n;
X 
X       new = NULL;
+       if (basiccustom) no = basicenv[no];
X       env = env_str(no);
X       switch (env_type(no)) {
X               case T_BOOL:
@@ -1614,8 +1711,10 @@
X                       envcaption(VSORT_K);
X                       str[0] = VSRT0_K;
X                       str[1] = VSRT1_K;
+                       str[2] = VSRT2_K;
X                       val[0] = 0;
X                       val[1] = 1;
+                       val[2] = 2;
X                       if (noselect(&p, MAXSORTINHERIT + 1, 0, str, val))
X                               return(0);
X                       n += p * 100;
@@ -1728,6 +1827,7 @@
X                       str[7] = VCFIF_K;
X                       str[8] = VCBLD_K;
X                       str[9] = VCCHD_K;
+                       str[10] = VCEXE_K;
X                       str[MAXPALETTE] = VUSET_K;
X                       val[MAXPALETTE] = -1;
X                       envcaption(env);
@@ -1789,6 +1889,7 @@
X               case T_KNAM:
X               case T_KOUT:
X               case T_KTERM:
+               case T_MESLANG:
X                       tmp = 0;
X                       str[tmp] = VNCNV_K;
X                       val[tmp++] = NOCNV;
@@ -1839,6 +1940,7 @@
X                                       n--;
X                                       break;
X                               case M_UTF8:
+                               case I_UTF8:
X                                       p = n - UTF8;
X                                       n = UTF8;
X                                       break;
@@ -1870,7 +1972,8 @@
X                               case UTF8:
X                                       str[0] = VUTF8_K;
X                                       str[1] = VUTFM_K;
-                                       tmp = 2;
+                                       str[2] = VUTFI_K;
+                                       tmp = 3;
X                                       break;
X                               default:
X                                       tmp = -1;
@@ -1879,6 +1982,7 @@
X                       if (tmp >= 0) {
X                               val[0] = 0;
X                               val[1] = 1;
+                               val[2] = 2;
X                               if (noselect(&p, tmp, 64, str, val)) return(0);
X                               n += p;
X                       }
@@ -1900,6 +2004,7 @@
X                       str[CAP] = "cap";
X                       str[UTF8] = "utf8";
X                       str[M_UTF8] = "utf8-mac";
+                       str[I_UTF8] = "utf8-iconv";
X #  endif      /* !_NOKANJICONV */
X                       cp = str[n];
X                       break;
@@ -1919,7 +2024,7 @@
X                       cp = ascoctal(n, buf);
X                       break;
X # endif       /* FD >= 2 */
-# ifndef       _NOPTY
+# if   !defined (_NOPTY) || !defined (_NOIME)
X               case T_KEYCODE:
X                       cp = asprintf3(VKYCD_K, env);
X                       n = inputkeycode(cp);
@@ -1932,7 +2037,40 @@
X                       cp = getkeysym(n, 0);
X                       if (!yesno(VKYOK_K, cp, env_str(no))) return(0);
X                       break;
-# endif        /* !_NOPTY */
+# endif        /* !_NOPTY || !_NOIME */
+# if   FD >= 2
+               case T_HELP:
+                       n = *((int *)(envlist[no].var));
+                       p = n / 100;
+                       n %= 100;
+                       envcaption(env);
+                       int2str(buf, p);
+                       lcmdline = -1;
+                       cp = inputcustenvstr(VFNMX_K, 1, buf, -1);
+                       if (cp == (char *)-1) return(0);
+                       if (!cp) break;
+                       p = atoi2(cp);
+                       free(cp);
+                       if (p < 0 || p > MAXHELPINDEX) {
+                               warning(0, VALNG_K);
+                               return(0);
+                       }
+
+                       envcaption(env);
+                       int2str(buf, n);
+                       lcmdline = -1;
+                       cp = inputcustenvstr(VFNBR_K, 1, buf, -1);
+                       if (cp == (char *)-1) return(0);
+                       if (!cp) break;
+                       n = atoi2(cp);
+                       free(cp);
+                       if (n < 0 || n > p) {
+                               warning(0, VALNG_K);
+                               return(0);
+                       }
+                       cp = int2str(buf, p * 100 + n);
+                       break;
+# endif        /* FD >= 2 */
X               default:
X                       if (!(cp = getenv2(fdenv_str(no)))) cp = def_str(no);
X                       new = inputcustenvstr(env, 0, cp, -1);
@@ -3889,18 +4027,18 @@
X       }
X       else {
X               warning(-1, path);
-#  if  MSDOS || defined (CYGWIN)
-               lockclose(lck);
+#  if  !MSDOS && !defined (CYGWIN)
X               if (fd >= 0) {
-                       if (fpin) VOID_C Xclose(fd);
X                       Xunlink(path);
+                       if (fpin) VOID_C Xclose(fd);
X               }
+               lockclose(lck);
X #  else
+               lockclose(lck);
X               if (fd >= 0) {
-                       Xunlink(path);
X                       if (fpin) VOID_C Xclose(fd);
+                       Xunlink(path);
X               }
-               lockclose(lck);
X #  endif
X               return(-1);
X       }
@@ -4073,10 +4211,7 @@
X               if (origflaglist[i]) free(origflaglist[i]);
X       }
X 
-       if (!fpin) {
-               lockclose(lck);
-               n = 0;
-       }
+       if (!fpin) lockclose(lck);
X       else {
X #  if !MSDOS && !defined (CYGWIN)
X               n = Xrename(path, file);
@@ -4094,12 +4229,11 @@
X               }
X #   endif
X #  endif      /* MSDOS || CYGWIN */
-       }
-
-       if (n < 0) {
-               warning(-1, file);
-               Xunlink(path);
-               return(-1);
+               if (n < 0) {
+                       warning(-1, file);
+                       Xunlink(path);
+                       return(-1);
+               }
X       }
X 
X       return(0);
@@ -4278,6 +4412,7 @@
X       cp = NEWET_K;
X       switch (custno) {
X               case 0:
+                       if (basiccustom) no = basicenv[no];
X                       cp = env_str(no);
X                       break;
X               case 1:
@@ -4449,6 +4584,7 @@
X       switch (custno) {
X               case 0:
X                       n = editenv(cs_item);
+                       cs_max = (basiccustom) ? nbasic : ENVLISTSIZ;
X                       break;
X               case 1:
X                       if ((n = editbind(cs_item))) {
@@ -4506,6 +4642,11 @@
X       }
X       for (i = 0; i < MAXCUSTOM; i++) item[i] = 0;
X 
+       nbasic = 0;
+       for (i = 0; i < ENVLISTSIZ; i++)
+               if (envlist[i].type & T_BASIC) basicenv[nbasic++] = i;
+       while (i < ENVLISTSIZ) basicenv[i++] = -1;
+
X       tmpenvlist = copyenv(NULL);
X       tmpmacrolist = copystrarray(NULL, macrolist, &tmpmaxmacro, maxmacro);
X       tmphelpindex = copystrarray(NULL, helpindex, NULL, MAXHELPINDEX);
@@ -4544,7 +4685,7 @@
X       changed = 0;
X       custno = 0;
X       cs_item = item[custno];
-       cs_max = max[custno];
+       getmax(max, custno);
X       cs_row = (FILEPERROW - 2) / 2;
X       cs_len = (int *)malloc2(cs_row * sizeof(int));
X       custtitle();
@@ -4573,22 +4714,22 @@
X                       case K_RIGHT:
X                               if (custno < MAXCUSTOM - 1) {
X                                       item[custno] = cs_item;
-                                       max[custno] = cs_max;
+                                       setmax(max, custno);
X                                       custno++;
X                                       custtitle();
X                                       cs_item = item[custno];
-                                       cs_max = max[custno];
+                                       getmax(max, custno);
X                                       old = -1;
X                               }
X                               break;
X                       case K_LEFT:
X                               if (custno > 0) {
X                                       item[custno] = cs_item;
-                                       max[custno] = cs_max;
+                                       setmax(max, custno);
X                                       custno--;
X                                       custtitle();
X                                       cs_item = item[custno];
-                                       cs_max = max[custno];
+                                       getmax(max, custno);
X                                       old = -1;
X                               }
X                               break;
@@ -4632,7 +4773,7 @@
X                                       break;
X                               }
X                               if (custno < MAXCUSTOM - 1) {
-                                       max[custno] = cs_max;
+                                       setmax(max, custno);
X                                       changed = 1;
X                               }
X                               else {
diff -urNP ../FD-2.08f/dict.c ./dict.c
--- ../FD-2.08f/dict.c  Thu Jan  1 09:00:00 1970
+++ ./dict.c    Tue Aug 22 00:00:00 2006
@@ -0,0 +1,1070 @@
+/*
+ *     dict.c
+ *
+ *     dictionary accessing module
+ */
+
+#include <fcntl.h>
+#include "fd.h"
+#include "termio.h"
+#include "func.h"
+#include "roman.h"
+#include "hinsi.h"
+
+#ifndef        _NOIME
+
+#define        DICTTBL         "fd-dict.tbl"
+#define        MAXHINSI        16
+#define        FREQMAGIC       0x4446
+#define        FREQVERSION     0x0100
+#define        USERFREQBIAS    16
+#define        freqbias(n)     (((long)(n) + USERFREQBIAS) * USERFREQBIAS)
+#define        getword(s, n)   (((u_short)((s)[(n) + 1]) << 8) | (s)[n])
+#define        getdword(s, n)  (((u_long)getword(s, (n) + 2) << 16) | getword(s, n))
+#define        skread(f,o,s,n) (Xlseek(f, o, L_SET) >= (off_t)0 \
+                       && sureread(f, s, n) == n)
+
+#ifndef        O_BINARY
+#define        O_BINARY        0
+#endif
+#ifndef        L_SET
+# ifdef        SEEK_SET
+# define       L_SET   SEEK_SET
+# else
+# define       L_SET   0
+# endif
+#endif /* !L_SET */
+#ifndef        L_INCR
+# ifdef        SEEK_CUR
+# define       L_INCR  SEEK_CUR
+# else
+# define       L_INCR  1
+# endif
+#endif /* !L_INCR */
+
+typedef struct _kanjitable {
+       u_short *kbuf;
+       u_char klen;
+       u_char len;
+       u_char match;
+       u_char kmatch;
+       u_short freq;
+       u_short hinsi[MAXHINSI];
+       long ofs;
+} kanjitable;
+
+static int NEAR fgetbyte __P_((u_char *, int));
+static int NEAR fgetword __P_((u_short *, int));
+static int NEAR fgetdword __P_((long *, int));
+static int NEAR fgetstring __P_((kanjitable *, int));
+static off_t NEAR fgetoffset __P_((long, int));
+static int NEAR fgetjisbuf __P_((kanjitable *, long, int));
+static int NEAR fgethinsi __P_((u_short [], int));
+static int NEAR fgetfreqbuf __P_((kanjitable *, long, int));
+static int NEAR _fchkhinsi __P_((int, u_short [], int));
+static int NEAR fchkhinsi __P_((u_short [], u_short [],
+               u_short [], u_short [], int));
+static int NEAR opendicttbl __P_((char *));
+static u_char *NEAR newhinsitbl __P_((ALLOC_T));
+static VOID NEAR readdicttable __P_((int));
+static int NEAR fputbyte __P_((int, int));
+static int NEAR fputword __P_((u_int, int));
+static int NEAR fputdword __P_((long, int));
+static int NEAR fputstring __P_((kanjitable *, int));
+static lockbuf_t *NEAR openfreqtbl __P_((char *, int));
+static int NEAR getfreq __P_((kanjitable *, kanjitable *));
+static int NEAR copyuserfreq __P_((kanjitable *, kanjitable *, int, int));
+static int cmpdict __P_((CONST VOID_P, CONST VOID_P));
+static int cmpfreq __P_((CONST VOID_P, CONST VOID_P));
+static long NEAR addkanji __P_((long, kanjitable **, kanjitable *));
+static VOID freekanji __P_((kanjitable *));
+static long NEAR addkanjilist __P_((long, kanjitable **,
+               long, kanjitable *, kanjitable *, int));
+static off_t NEAR nextofs __P_((off_t, int));
+static long NEAR _searchdict __P_((long, kanjitable **, kanjitable *, int));
+static long NEAR uniqkanji __P_((long, kanjitable *));
+
+char *dicttblpath = NULL;
+int imebuffer = 0;
+
+static kanjitable *kanjilist = NULL;
+static u_char *hinsiindexbuf = NULL;
+static u_char *hinsitblbuf = NULL;
+static long dicttblent = 0L;
+static long freqtblent = 0L;
+static int hinsitblent = 0;
+static off_t hinsitblofs = (off_t)0;
+
+
+static int NEAR fgetbyte(cp, fd)
+u_char *cp;
+int fd;
+{
+       if (sureread(fd, cp, 1) != 1) return(-1);
+
+       return(0);
+}
+
+static int NEAR fgetword(wp, fd)
+u_short *wp;
+int fd;
+{
+       u_char buf[2];
+
+       if (sureread(fd, buf, 2) != 2) return(-1);
+       *wp = getword(buf, 0);
+
+       return(0);
+}
+
+static int NEAR fgetdword(lp, fd)
+long *lp;
+int fd;
+{
+       u_char buf[4];
+
+       if (sureread(fd, buf, 4) != 4) return(-1);
+       *lp = getdword(buf, 0);
+
+       return(0);
+}
+
+static int NEAR fgetstring(kp, fd)
+kanjitable *kp;
+int fd;
+{
+       u_short *kbuf;
+       u_char c;
+       int i;
+
+       kp -> kbuf = NULL;
+       if (fgetbyte(&c, fd) < 0) return(-1);
+       kp -> klen = c;
+       kbuf = (u_short *)malloc2((kp -> klen + 1) * sizeof(u_short));
+       for (i = 0; i < kp -> klen; i++) if (fgetword(&(kbuf[i]), fd) < 0) {
+               free(kbuf);
+               return(-1);
+       }
+       kbuf[i] = (short)0;
+       kp -> kbuf = kbuf;
+
+       return(0);
+}
+
+static off_t NEAR fgetoffset(n, fd)
+long n;
+int fd;
+{
+       u_char buf[4];
+       off_t ofs;
+
+       ofs = (off_t)n * 4 + 4;
+       if (!skread(fd, ofs, buf, 4)) return((off_t)-1);
+       ofs = (off_t)(dicttblent + 1) * 4 + 4 + getdword(buf, 0);
+
+       return(ofs);
+}
+
+static int NEAR fgetjisbuf(kp, n, fd)
+kanjitable *kp;
+long n;
+int fd;
+{
+       off_t ofs;
+
+       if ((ofs = fgetoffset(n, fd)) < (off_t)0) return(-1);
+       if (Xlseek(fd, ofs, L_SET) < (off_t)0) return(-1);
+
+       return(fgetstring(kp, fd));
+}
+
+static int NEAR fgethinsi(hinsi, fd)
+u_short hinsi[MAXHINSI];
+int fd;
+{
+       u_char c;
+       int i, n;
+
+       if (hinsitblent <= 0) n = 0;
+       else {
+               if (fgetbyte(&c, fd) < 0) return(-1);
+               if ((n = c) > MAXHINSI) n = MAXHINSI;
+               for (i = 0; i < n; i++)
+                       if (fgetword(&(hinsi[i]), fd) < 0) return(-1);
+       }
+       if (n < MAXHINSI) hinsi[n] = MAXUTYPE(u_short);
+
+       return(n);
+}
+
+static int NEAR fgetfreqbuf(kp, n, fd)
+kanjitable *kp;
+long n;
+int fd;
+{
+       u_char buf[4];
+       off_t ofs;
+
+       ofs = (off_t)n * 4 + 4 + 4;
+       if (!skread(fd, ofs, buf, 4)) return(-1);
+       ofs = (off_t)(freqtblent + 1) * 4 + 4 + 4 + getdword(buf, 0);
+       if (Xlseek(fd, ofs, L_SET) < (off_t)0) return(-1);
+
+       return(fgetstring(kp, fd));
+}
+
+static int NEAR _fchkhinsi(id, hinsi, fd)
+int id;
+u_short hinsi[MAXHINSI];
+int fd;
+{
+       u_char *cp, *hbuf, buf[2];
+       off_t ofs;
+       u_short w;
+       int i, j, len;
+
+       if (hinsitblent <= 0) return(0);
+       if (id >= hinsitblent) return(MAXUTYPE(u_short));
+
+       ofs = (off_t)id * 2;
+       if (hinsiindexbuf) ofs = getword(hinsiindexbuf, ofs);
+       else {
+               ofs += hinsitblofs + 2;
+               if (!skread(fd, ofs, buf, 2)) return(-1);
+               ofs = getword(buf, 0);
+       }
+
+       if (hinsitblbuf) {
+               cp = &(hinsitblbuf[ofs]);
+               len = getword(cp, 0);
+               cp += 2;
+               hbuf = NULL;
+       }
+       else {
+               ofs += hinsitblofs + (off_t)(hinsitblent + 1) * 2 + 2;
+               if (!skread(fd, ofs, buf, 2)) return(-1);
+               if ((len = getword(buf, 0)) <= 0) return(MAXUTYPE(u_short));
+               cp = hbuf = (u_char *)malloc2(len * 2);
+               if (sureread(fd, hbuf, len * 2) != len * 2) {
+                       free(hbuf);
+                       return(-1);
+               }
+       }
+
+       for (i = 0; i < len; i++, cp += 2) {
+               w = getword(cp, 0);
+               for (j = 0; j < MAXHINSI; j++) {
+                       if (hinsi[j] == MAXUTYPE(u_short)) break;
+                       if (hinsi[j] == w) {
+                               if (hbuf) free(hbuf);
+                               return(j);
+                       }
+               }
+       }
+       if (hbuf) free(hbuf);
+
+       return(MAXUTYPE(u_short));
+}
+
+static int NEAR fchkhinsi(fdest, fsrc, bdest, bsrc, fd)
+u_short fdest[MAXHINSI], fsrc[MAXHINSI], bdest[MAXHINSI], bsrc[MAXHINSI];
+int fd;
+{
+       u_short fhit[MAXHINSI], bhit[MAXHINSI];
+       int i, j, n;
+
+       if (hinsitblent <= 0 || fsrc[0] == MAXUTYPE(u_short)) {
+               if (fdest) memcpy((char *)fdest, (char *)fsrc, sizeof(fhit));
+               if (bdest) memcpy((char *)bdest, (char *)bsrc, sizeof(bhit));
+               return(0);
+       }
+
+       for (i = 0; i < MAXHINSI; i++) fhit[i] = bhit[i] = MAXUTYPE(u_short);
+       for (i = j = 0; i < MAXHINSI; i++) {
+               if (bsrc[i] == MAXUTYPE(u_short)) break;
+               n = _fchkhinsi(bsrc[i], fsrc, fd);
+               if (n < 0) return(-1);
+               if (n < MAXUTYPE(u_short)) {
+                       fhit[n] = fsrc[n];
+                       bhit[i] = bsrc[i];
+                       j++;
+               }
+       }
+       if (!j) return(-1);
+
+       if (fdest) {
+               for (i = j = 0; i < MAXHINSI; i++)
+                       if (fhit[i] < MAXUTYPE(u_short)) fdest[j++] = fhit[i];
+               if (j < MAXHINSI) fdest[j] = MAXUTYPE(u_short);
+       }
+       if (bdest) {
+               for (i = j = 0; i < MAXHINSI; i++)
+                       if (bhit[i] < MAXUTYPE(u_short)) bdest[j++] = bhit[i];
+               if (j < MAXHINSI) bdest[j] = MAXUTYPE(u_short);
+       }
+
+       return(0);
+}
+
+static int NEAR opendicttbl(file)
+char *file;
+{
+       static int fd = -2;
+       u_char buf[2];
+       char path[MAXPATHLEN];
+
+       if (!file) {
+               if (fd >= 0) Xclose(fd);
+               fd = -2;
+               return(0);
+       }
+
+       if (fd >= -1) return(fd);
+
+       if (!dicttblpath || !*dicttblpath) strcpy(path, file);
+       else strcatdelim2(path, dicttblpath, file);
+
+       if ((fd = Xopen(path, O_BINARY | O_RDONLY, 0666)) < 0) fd = -1;
+       else if (!dicttblent && fgetdword(&dicttblent, fd) < 0) {
+               Xclose(fd);
+               fd = -1;
+       }
+       else if (!hinsitblent) {
+               if ((hinsitblofs = fgetoffset(dicttblent, fd)) < (off_t)0
+               || !skread(fd, hinsitblofs, buf, 2))
+                       hinsitblent = -1;
+               else hinsitblent = getword(buf, 0);
+       }
+
+       return(fd);
+}
+
+static u_char *NEAR newhinsitbl(size)
+ALLOC_T size;
+{
+       u_char *tbl;
+
+       if ((tbl = (u_char *)malloc(size))) return(tbl);
+       if (imebuffer) imebuffer = 0;
+
+       return(NULL);
+}
+
+static VOID NEAR readdicttable(fd)
+int fd;
+{
+       u_char *tbl, buf[2];
+       ALLOC_T size;
+       off_t ofs;
+
+       if (hinsitblent <= 0) return;
+
+       if (!hinsiindexbuf) {
+               size = (ALLOC_T)hinsitblent * 2;
+               if (!(tbl = newhinsitbl(size))) return;
+               if (!skread(fd, hinsitblofs + 2, tbl, size)) {
+                       free(tbl);
+                       return;
+               }
+               hinsiindexbuf = tbl;
+       }
+
+       if (!imebuffer) return;
+
+       if (!hinsitblbuf) {
+               ofs = (off_t)hinsitblent * 2 + 2;
+               if (!skread(fd, hinsitblofs + ofs, buf, 2)) return;
+               size = getword(buf, 0);
+               if (!(tbl = newhinsitbl(size))) return;
+               if (sureread(fd, tbl, size) != size) {
+                       free(tbl);
+                       return;
+               }
+               hinsitblbuf = tbl;
+       }
+}
+
+VOID discarddicttable(VOID_A)
+{
+       if (hinsiindexbuf) {
+               free(hinsiindexbuf);
+               hinsiindexbuf = NULL;
+       }
+       if (hinsitblbuf) {
+               free(hinsitblbuf);
+               hinsitblbuf = NULL;
+       }
+}
+
+static int NEAR fputbyte(c, fd)
+int c, fd;
+{
+       u_char uc;
+
+       uc = c;
+       if (surewrite(fd, &uc, sizeof(uc)) < 0) return(-1);
+
+       return(0);
+}
+
+static int NEAR fputword(w, fd)
+u_int w;
+int fd;
+{
+       u_char buf[2];
+
+       buf[0] = (w & 0xff);
+       buf[1] = ((w >> 8) & 0xff);
+       if (surewrite(fd, buf, sizeof(buf)) < 0) return(-1);
+
+       return(0);
+}
+
+static int NEAR fputdword(dw, fd)
+long dw;
+int fd;
+{
+       u_char buf[4];
+
+       buf[0] = (dw & 0xff);
+       buf[1] = ((dw >> 8) & 0xff);
+       buf[2] = ((dw >> 16) & 0xff);
+       buf[3] = ((dw >> 24) & 0xff);
+       if (surewrite(fd, buf, sizeof(buf)) < 0) return(-1);
+
+       return(0);
+}
+
+static int NEAR fputstring(kp, fd)
+kanjitable *kp;
+int fd;
+{
+       int i;
+
+       if (fputbyte(kp -> klen, fd) < 0) return(-1);
+       for (i = 0; i < kp -> klen; i++)
+               if (fputword(kp -> kbuf[i], fd) < 0) return(-1);
+
+       return(0);
+}
+
+static lockbuf_t *NEAR openfreqtbl(file, flags)
+char *file;
+int flags;
+{
+       static lockbuf_t *lck = NULL;
+       u_short w;
+
+       if (!file) {
+               lockclose(lck);
+               lck = NULL;
+               return(NULL);
+       }
+
+       if (lck) return(lck);
+       file = evalpath(strdup2(file), 0);
+
+       freqtblent = 0L;
+       lck = lockopen(file, flags, 0666);
+       if (!lck || lck -> fd < 0) /*EMPTY*/;
+       else if (fgetword(&w, lck -> fd) < 0 || w != FREQMAGIC
+       || fgetword(&w, lck -> fd) < 0 || w != FREQVERSION
+       || fgetdword(&freqtblent, lck -> fd) < 0) {
+               lockclose(lck);
+               lck = NULL;
+       }
+
+       if (!lck) {
+               lck = (lockbuf_t *)malloc2(sizeof(lockbuf_t));
+               lck -> fd = -1;
+               lck -> fp = NULL;
+               lck -> name = NULL;
+               lck -> flags = LCK_INVALID;
+       }
+
+       return(lck);
+}
+
+static int NEAR getfreq(kp1, kp2)
+kanjitable *kp1, *kp2;
+{
+       kanjitable tmp;
+       lockbuf_t *lck;
+       long ofs, min, max;
+       int n;
+
+       kp1 -> ofs = -1L;
+       lck = openfreqtbl(FREQFILE, O_BINARY | O_RDONLY);
+       if (lck -> fd < 0) return(0);
+
+       min = -1L;
+       max = freqtblent;
+       for (;;) {
+               ofs = (min + max) / 2;
+               if (ofs <= min) {
+                       kp1 -> ofs = min + 1;
+                       return(0);
+               }
+               else if (ofs >= max) {
+                       kp1 -> ofs = max;
+                       return(0);
+               }
+               else if (fgetfreqbuf(&tmp, ofs, lck -> fd) < 0) return(-1);
+
+               n = cmpdict(kp1, &tmp);
+               free(tmp.kbuf);
+               if (n > 0) min = ofs;
+               else if (n < 0) max = ofs;
+               else if (fgetstring(&tmp, lck -> fd) < 0) return(-1);
+               else {
+                       n = cmpdict(kp2, &tmp);
+                       free(tmp.kbuf);
+                       if (n > 0) min = ofs;
+                       else if (n < 0) max = ofs;
+                       else break;
+               }
+       }
+
+       kp1 -> ofs = ofs;
+       if (fgetword(&(kp1 -> freq), lck -> fd) < 0) return(-1);
+
+       return(1);
+}
+
+static int NEAR copyuserfreq(kp1, kp2, fdin, fdout)
+kanjitable *kp1, *kp2;
+int fdin, fdout;
+{
+       kanjitable tmp;
+       ALLOC_T size;
+       long ofs, index, ent;
+       int n, skip;
+
+       size = 1 + (kp1 -> klen * 2) + 1 + (kp2 -> klen * 2) + 2;
+       skip = 0;
+       if (fdin < 0) {
+               ent = kp1 -> ofs = 0L;
+               kp1 -> freq = (u_short)1;
+       }
+       else {
+               ent = freqtblent;
+               n = getfreq(kp1, kp2);
+               if (n < 0) return(-1);
+               else if (!n) kp1 -> freq = (u_short)1;
+               else {
+                       skip++;
+                       if (kp1 -> freq < MAXUTYPE(u_short)) kp1 -> freq++;
+               }
+               if (Xlseek(fdin, (off_t)1 * 4 + 4 + 4, L_SET) < (off_t)0)
+                       return(-1);
+       }
+
+       if (fputword(FREQMAGIC, fdout) < 0) return(-1);
+       if (fputword(FREQVERSION, fdout) < 0) return(-1);
+       if (fputdword(ent + 1 - skip, fdout) < 0) return(-1);
+       index = 0L;
+       if (fputdword(index, fdout) < 0) return(-1);
+       for (ofs = 1; ofs <= kp1 -> ofs; ofs++) {
+               if (fgetdword(&index, fdin) < 0) return(-1);
+               if (fputdword(index, fdout) < 0) return(-1);
+       }
+       if (fputdword(index + size, fdout) < 0) return(-1);
+       if (skip) {
+               if (fgetdword(&index, fdin) < 0) return(-1);
+               size = (ALLOC_T)0;
+               ofs++;
+       }
+       for (; ofs <= ent; ofs++) {
+               if (fgetdword(&index, fdin) < 0) return(-1);
+               index += size;
+               if (fputdword(index, fdout) < 0) return(-1);
+       }
+
+       for (ofs = 0; ofs < kp1 -> ofs; ofs++) {
+               if (fgetstring(&tmp, fdin) < 0) return(-1);
+               if (fputstring(&tmp, fdout) < 0) return(-1);
+               free(tmp.kbuf);
+               if (fgetstring(&tmp, fdin) < 0) return(-1);
+               if (fputstring(&tmp, fdout) < 0) return(-1);
+               free(tmp.kbuf);
+               if (fgetword(&(tmp.freq), fdin) < 0) return(-1);
+               if (fputword(tmp.freq, fdout) < 0) return(-1);
+       }
+       if (skip) {
+               if (fgetstring(&tmp, fdin) < 0) return(-1);
+               free(tmp.kbuf);
+               if (fgetstring(&tmp, fdin) < 0) return(-1);
+               free(tmp.kbuf);
+               if (fgetword(&(tmp.freq), fdin) < 0) return(-1);
+               ofs++;
+       }
+       if (fputstring(kp1, fdout) < 0) return(-1);
+       if (fputstring(kp2, fdout) < 0) return(-1);
+       if (fputword(kp1 -> freq, fdout) < 0) return(-1);
+       for (; ofs < ent; ofs++) {
+               if (fgetstring(&tmp, fdin) < 0) return(-1);
+               if (fputstring(&tmp, fdout) < 0) return(-1);
+               free(tmp.kbuf);
+               if (fgetstring(&tmp, fdin) < 0) return(-1);
+               if (fputstring(&tmp, fdout) < 0) return(-1);
+               free(tmp.kbuf);
+               if (fgetword(&(tmp.freq), fdin) < 0) return(-1);
+               if (fputword(tmp.freq, fdout) < 0) return(-1);
+       }
+
+       return(0);
+}
+
+VOID saveuserfreq(kana, kbuf)
+u_short *kana, *kbuf;
+{
+       kanjitable tmp1, tmp2;
+       lockbuf_t *lck;
+       char *cp, path[MAXPATHLEN];
+       long argc;
+       int n, fdin, fdout;
+
+       if (!kanjilist) return;
+
+       for (argc = 0L; kanjilist[argc].kbuf; argc++)
+               if (kbuf == kanjilist[argc].kbuf) break;
+       if (!kanjilist[argc].kbuf) return;
+
+       VOID_C openfreqtbl(NULL, 0);
+       if (!(lck = openfreqtbl(FREQFILE, O_BINARY | O_RDWR))) return;
+       cp = evalpath(strdup2(FREQFILE), 0);
+       strcpy(path, cp);
+       if ((fdin = lck -> fd) >= 0) fdout = opentmpfile(path, 0666);
+       else {
+               VOID_C openfreqtbl(NULL, 0);
+               lck = lockopen(path,
+                       O_BINARY | O_WRONLY | O_CREAT | O_EXCL, 0666);
+               fdout = (lck) ? lck -> fd : -1;
+       }
+
+       if (fdout < 0) {
+               VOID_C openfreqtbl(NULL, 0);
+               if (fdin < 0) lockclose(lck);
+               free(cp);
+               return;
+       }
+
+       tmp1.kbuf = kana;
+       tmp1.klen = kanjilist[argc].match;
+       tmp2.kbuf = kbuf;
+       tmp2.klen = kanjilist[argc].kmatch;
+
+       n = copyuserfreq(&tmp1, &tmp2, fdin, fdout);
+       if (fdin < 0) {
+#if    !MSDOS && !defined (CYGWIN)
+               if (n < 0) Xunlink(path);
+               lockclose(lck);
+#else
+               lockclose(lck);
+               if (n < 0) Xunlink(path);
+#endif
+       }
+       else {
+#if    !MSDOS && !defined (CYGWIN)
+               if (n >= 0) n = Xrename(path, cp);
+               VOID_C openfreqtbl(NULL, 0);
+               Xclose(fdout);
+#else  /* MSDOS || CYGWIN */
+               VOID_C openfreqtbl(NULL, 0);
+               Xclose(fdout);
+               if (n >= 0) {
+# if   MSDOS
+                       n = Xrename(path, cp);
+# else
+                       while ((n = Xrename(path, cp)) < 0) {
+                               if (errno != EACCES) break;
+                               usleep(100000L);
+                       }
+# endif
+               }
+#endif /* MSDOS || CYGWIN */
+               if (n < 0) Xunlink(path);
+       }
+
+       free(cp);
+}
+
+static int cmpdict(vp1, vp2)
+CONST VOID_P vp1;
+CONST VOID_P vp2;
+{
+       kanjitable *kp1, *kp2;
+       u_short *kbuf1, *kbuf2;
+       int i, klen1, klen2;
+
+       kp1 = (kanjitable *)vp1;
+       kp2 = (kanjitable *)vp2;
+       kbuf1 = kp1 -> kbuf;
+       kbuf2 = kp2 -> kbuf;
+       klen1 = kp1 -> klen;
+       klen2 = kp2 -> klen;
+
+       for (i = 0; i < klen1; i++) {
+               if (i >= klen2) return(1);
+               if (kbuf1[i] > kbuf2[i]) return(1);
+               else if (kbuf1[i] < kbuf2[i]) return(-1);
+       }
+
+       return(klen1 - klen2);
+}
+
+static int cmpfreq(vp1, vp2)
+CONST VOID_P vp1;
+CONST VOID_P vp2;
+{
+       kanjitable *kp1, *kp2;
+
+       kp1 = (kanjitable *)vp1;
+       kp2 = (kanjitable *)vp2;
+
+       if (kp1 -> len < kp2 -> len) return(1);
+       else if (kp1 -> len > kp2 -> len) return(-1);
+       if (kp1 -> freq < kp2 -> freq) return(1);
+       else if (kp1 -> freq > kp2 -> freq) return(-1);
+       if (kp1 -> ofs > kp2 -> ofs) return(1);
+       else if (kp1 -> ofs < kp2 -> ofs) return(-1);
+
+       return(0);
+}
+
+static long NEAR addkanji(argc, argvp, tmp)
+long argc;
+kanjitable **argvp, *tmp;
+{
+       *argvp = (kanjitable *)realloc2(*argvp,
+               (argc + 2) * sizeof(kanjitable));
+       memcpy((char *)&((*argvp)[argc++]), tmp, sizeof(kanjitable));
+       (*argvp)[argc].kbuf = NULL;
+
+       return(argc);
+}
+
+static VOID freekanji(argv)
+kanjitable *argv;
+{
+       long n;
+
+       if (argv) {
+               for (n = 0L; argv[n].kbuf; n++) free(argv[n].kbuf);
+               free(argv);
+       }
+}
+
+static long NEAR addkanjilist(argc, argvp, argc2, argv2, kp, fd)
+long argc;
+kanjitable **argvp;
+long argc2;
+kanjitable *argv2, *kp;
+int fd;
+{
+       kanjitable *next, tmp1, tmp2;
+       u_short hinsi[MAXHINSI], shuutan[MAXHINSI];
+       long n;
+       int i;
+
+       tmp1.kbuf = kp -> kbuf;
+       tmp1.klen = kp -> len;
+       if (fgetstring(&tmp2, fd) < 0 || fgetword(&(tmp2.freq), fd) < 0
+       || fgethinsi(hinsi, fd) < 0) {
+               if (tmp2.kbuf) free(tmp2.kbuf);
+               return(argc);
+       }
+
+       if (getfreq(&tmp1, &tmp2) <= 0) /*EMPTY*/;
+       else if (tmp2.freq < MAXUTYPE(u_short) - freqbias(tmp1.freq))
+               tmp2.freq += freqbias(tmp1.freq);
+       else tmp2.freq = MAXUTYPE(u_short);
+       tmp1.kbuf = tmp2.kbuf;
+       tmp1.klen = tmp2.klen;
+       tmp1.freq = tmp2.freq;
+
+       tmp2.match = kp -> len;
+       tmp2.kmatch = tmp1.klen;
+       tmp2.len = kp -> len;
+       tmp2.ofs = kp -> ofs;
+       if (hinsitblent <= 0) {
+               if (kp -> len < kp -> klen) {
+                       tmp2.klen += kp -> klen - kp -> len;
+                       tmp2.kbuf = (u_short *)realloc2(tmp2.kbuf,
+                               (tmp2.klen + 1) * sizeof(u_short));
+                       memcpy((char *)&(tmp2.kbuf[tmp1.klen]),
+                               (char *)&(kp -> kbuf[kp -> len]),
+                               (kp -> klen - kp -> len) * sizeof(short));
+                       tmp2.kbuf[tmp2.klen] = (short)0;
+               }
+               return(addkanji(argc, argvp, &tmp2));
+       }
+
+       i = fchkhinsi(NULL, kp -> hinsi, hinsi, hinsi, fd);
+       if (i >= 0 && kp -> len >= kp -> klen) {
+               shuutan[0] = SH_svkantan;
+               shuutan[1] = MAXUTYPE(u_short);
+               i = fchkhinsi(tmp2.hinsi, hinsi, NULL, shuutan, fd);
+               if (i >= 0) return(addkanji(argc, argvp, &tmp2));
+       }
+       if (i < 0) {
+               if (kp -> hinsi[0] == (u_short)HN_SENTOU
+               && kp -> len >= kp -> klen) {
+                       for (i = 0; i < MAXHINSI; i++) {
+                               if (hinsi[i] == MAXUTYPE(u_short)) break;
+                               if (hinsi[i] == (u_short)HN_TANKAN)
+                                       return(addkanji(argc, argvp, &tmp2));
+                       }
+               }
+               free(tmp1.kbuf);
+               return(argc);
+       }
+
+       if (!(next = argv2)) {
+               tmp2.kbuf = &(kp -> kbuf[kp -> len]);
+               tmp2.klen = kp -> klen - kp -> len;
+               memcpy((char *)(tmp2.hinsi), (char *)hinsi, sizeof(hinsi));
+               for (tmp2.len = kp -> klen; tmp2.len > (u_char)0; tmp2.len--)
+                       argc2 = _searchdict(argc2, &argv2, &tmp2, fd);
+               if (!argv2) {
+                       free(tmp1.kbuf);
+                       return(argc);
+               }
+       }
+
+       for (n = 0L; n < argc2; n++) {
+               if (next
+               && fchkhinsi(tmp2.hinsi, hinsi, NULL, argv2[n].hinsi, fd) < 0)
+                       continue;
+
+               tmp2.klen = tmp1.klen + argv2[n].klen;
+               tmp2.kbuf =
+                       (u_short *)malloc2((tmp2.klen + 1) * sizeof(u_short));
+               memcpy((char *)(tmp2.kbuf), (char *)(tmp1.kbuf),
+                       tmp1.klen * sizeof(u_short));
+               memcpy((char *)&(tmp2.kbuf[tmp1.klen]),
+                       (char *)(argv2[n].kbuf),
+                       argv2[n].klen * sizeof(u_short));
+               tmp2.kbuf[tmp2.klen] = (u_short)0;
+
+               if (argv2[n].hinsi[0] >= (u_short)HN_MAX) {
+                       tmp2.len = kp -> len + argv2[n].len;
+                       tmp2.freq = tmp1.freq + argv2[n].freq;
+               }
+               else if (tmp2.hinsi[0] >= (u_short)HN_MAX) {
+                       tmp2.len = argv2[n].len;
+                       tmp2.freq = argv2[n].freq;
+               }
+               else if (kp -> len > argv2[n].len) {
+                       tmp2.len = kp -> len;
+                       tmp2.freq = tmp1.freq;
+               }
+               else if (tmp2.len < argv2[n].len) {
+                       tmp2.len = argv2[n].len;
+                       tmp2.freq = argv2[n].freq;
+               }
+               else {
+                       tmp2.len = kp -> len;
+                       tmp2.freq = (tmp1.freq > argv2[n].freq)
+                               ? tmp1.freq : argv2[n].freq;
+               }
+
+               argc = addkanji(argc, argvp, &tmp2);
+       }
+
+       if (!next) freekanji(argv2);
+       free(tmp1.kbuf);
+
+       return(argc);
+}
+
+static off_t NEAR nextofs(ofs, fd)
+off_t ofs;
+int fd;
+{
+       u_char c;
+
+       if (Xlseek(fd, ofs, L_SET) < (off_t)0) return((off_t)-1);
+       if (fgetbyte(&c, fd) < 0) return((off_t)-1);
+       ofs = (off_t)c * 2 + 2;
+       if ((ofs = Xlseek(fd, ofs, L_INCR)) < (off_t)0) return((off_t)-1);
+       if (hinsitblent <= 0) return(ofs);
+       if (fgetbyte(&c, fd) < 0) return((off_t)-1);
+       ofs = (off_t)c * 2;
+
+       return(Xlseek(fd, ofs, L_INCR));
+}
+
+static long NEAR _searchdict(argc, argvp, kp, fd)
+long argc;
+kanjitable **argvp, *kp;
+int fd;
+{
+       kanjitable *argv2, tmp1, tmp2;
+       off_t curofs;
+       long ofs, min, max, argc2;
+       u_char c;
+       int n;
+
+       min = -1L;
+       max = dicttblent;
+       tmp1.kbuf = kp -> kbuf;
+       tmp1.klen = kp -> len;
+       for (;;) {
+               ofs = (min + max) / 2;
+               if (ofs <= min || ofs >= max
+               || (fgetjisbuf(&tmp2, ofs, fd)) < 0)
+                       return(argc);
+               n = cmpdict(&tmp1, &tmp2);
+               free(tmp2.kbuf);
+               if (n > 0) min = ofs;
+               else if (n < 0) max = ofs;
+               else break;
+       }
+
+       kp -> ofs = ofs;
+       if (fgetbyte(&c, fd) < 0) return(argc);
+       if (c <= 1) return(addkanjilist(argc, argvp, 0, NULL, kp, fd));
+
+       if ((curofs = Xlseek(fd, (off_t)0, L_INCR)) < (off_t)0) return(argc);
+       argv2 = NULL;
+       argc2 = 0L;
+       if (hinsitblent > 0 && kp -> len < kp -> klen) {
+               tmp1.kbuf = &(kp -> kbuf[kp -> len]);
+               tmp1.klen = kp -> klen - kp -> len;
+               tmp1.hinsi[0] = MAXUTYPE(u_short);
+               for (tmp1.len = kp -> klen; tmp1.len > (u_char)0; tmp1.len--)
+                       argc2 = _searchdict(argc2, &argv2, &tmp1, fd);
+               if (!argv2) return(argc);
+       }
+
+       if (Xlseek(fd, curofs, L_SET) >= (off_t)0) {
+               for (n = 0; n < c; n++, curofs = nextofs(curofs, fd)) {
+                       if (curofs < (off_t)0) break;
+                       argc = addkanjilist(argc, argvp, argc2, argv2, kp, fd);
+               }
+       }
+
+       freekanji(argv2);
+
+       return(argc);
+}
+
+static long NEAR uniqkanji(argc, argv)
+long argc;
+kanjitable *argv;
+{
+       long i, j;
+       int c;
+
+       for (i = 0L; i < argc - 1; i++) {
+               for (j = 1L; i + j < argc; j++) {
+                       if (argv[i].klen != argv[i + j].klen) break;
+                       c = memcmp((char *)(argv[i].kbuf),
+                               (char *)(argv[i + j].kbuf),
+                               argv[i].klen * sizeof(u_short));
+                       if (c) break;
+                       free(argv[i + j].kbuf);
+                       if (argv[i + j].len > argv[i].len) {
+                               argv[i].len = argv[j].len;
+                               argv[i].freq = argv[j].freq;
+                       }
+                       else if (argv[i + j].len == argv[i].len) {
+                               if (argv[i + j].freq > argv[i].freq)
+                                       argv[i].freq = argv[j].freq;
+                       }
+               }
+               if (j <= 1L) continue;
+               memmove((char *)&(argv[i + 1]), (char *)&(argv[i + j]),
+                       (argc + 1 - (i + j)) * sizeof(kanjitable));
+               argc -= --j;
+       }
+
+       return(argc);
+}
+
+VOID freekanjilist(argv)
+u_short **argv;
+{
+       long n, argc;
+
+       if (argv) {
+               for (argc = 0L; argv[argc]; argc++) {
+                       if (kanjilist) {
+                               for (n = 0L; kanjilist[n].kbuf; n++)
+                                       if (argv[argc] == kanjilist[n].kbuf)
+                                               break;
+                               if (kanjilist[n].kbuf) continue;
+                       }
+                       free(argv[argc]);
+               }
+               free(argv);
+       }
+       freekanji(kanjilist);
SHAR_EOF
  : || $echo 'restore of' 'FD-2.09.patch' 'failed'
fi
$echo 'End of' 'FD-2.09.patch' 'part' '2'
$echo 'File' 'FD-2.09.patch' 'is continued in part' '3'
echo 3 > _sh00904/seq
exit 0
-- 
                                               しらい たかし